Add UV_LIBC to allow libc selection in multi-libc environment (#14646)

Closes #14262 

## Description

Adds `UV_LIBC` environment variable and implements check within
`Libc::from_env` as recommended here:
https://github.com/astral-sh/uv/issues/14262#issuecomment-3014600313

Gave this a few passes to make sure I follow dev practices within uv as
best I am able. Feel free to call out anything that could be improved.

## Test Plan

Planned to simply run existing test suite. Open to adding more tests
once implementation is validated due to my limited Rust experience.
This commit is contained in:
Nathan Cain 2025-07-16 08:52:17 -05:00 committed by GitHub
parent 03de6c36e3
commit e547527587
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 37 additions and 14 deletions

View file

@ -5,6 +5,8 @@ use std::ops::Deref;
use std::{fmt, str::FromStr};
use thiserror::Error;
use uv_static::EnvVars;
#[derive(Error, Debug)]
pub enum Error {
#[error("Unknown operating system: {0}")]
@ -15,6 +17,8 @@ pub enum Error {
UnknownLibc(String),
#[error("Unsupported variant `{0}` for architecture `{1}`")]
UnsupportedVariant(String, String),
#[error(transparent)]
LibcDetectionError(#[from] LibcDetectionError),
}
/// Architecture variants, e.g., with support for different instruction sets
@ -95,22 +99,32 @@ pub enum Libc {
}
impl Libc {
pub(crate) fn from_env() -> Result<Self, LibcDetectionError> {
pub(crate) fn from_env() -> Result<Self, Error> {
match std::env::consts::OS {
"linux" => Ok(Self::Some(match detect_linux_libc()? {
LibcVersion::Manylinux { .. } => match std::env::consts::ARCH {
// Checks if the CPU supports hardware floating-point operations.
// Depending on the result, it selects either the `gnueabihf` (hard-float) or `gnueabi` (soft-float) environment.
// download-metadata.json only includes armv7.
"arm" | "armv5te" | "armv7" => match detect_hardware_floating_point_support() {
Ok(true) => target_lexicon::Environment::Gnueabihf,
Ok(false) => target_lexicon::Environment::Gnueabi,
Err(_) => target_lexicon::Environment::Gnu,
"linux" => {
if let Ok(libc) = std::env::var(EnvVars::UV_LIBC) {
if !libc.is_empty() {
return Self::from_str(&libc);
}
}
Ok(Self::Some(match detect_linux_libc()? {
LibcVersion::Manylinux { .. } => match std::env::consts::ARCH {
// Checks if the CPU supports hardware floating-point operations.
// Depending on the result, it selects either the `gnueabihf` (hard-float) or `gnueabi` (soft-float) environment.
// download-metadata.json only includes armv7.
"arm" | "armv5te" | "armv7" => {
match detect_hardware_floating_point_support() {
Ok(true) => target_lexicon::Environment::Gnueabihf,
Ok(false) => target_lexicon::Environment::Gnueabi,
Err(_) => target_lexicon::Environment::Gnu,
}
}
_ => target_lexicon::Environment::Gnu,
},
_ => target_lexicon::Environment::Gnu,
},
LibcVersion::Musllinux { .. } => target_lexicon::Environment::Musl,
})),
LibcVersion::Musllinux { .. } => target_lexicon::Environment::Musl,
}))
}
"windows" | "macos" => Ok(Self::None),
// Use `None` on platforms without explicit support.
_ => Ok(Self::None),

View file

@ -154,6 +154,10 @@ impl EnvVars {
/// `--no-python-downloads` option. Whether uv should allow Python downloads.
pub const UV_PYTHON_DOWNLOADS: &'static str = "UV_PYTHON_DOWNLOADS";
/// Overrides the environment-determined libc on linux systems when filling in the current platform
/// within Python version requests. Options are: `gnu`, `gnueabi`, `gnueabihf`, `musl`, and `none`.
pub const UV_LIBC: &'static str = "UV_LIBC";
/// Equivalent to the `--compile-bytecode` command-line argument. If set, uv
/// will compile Python source files to bytecode after installation.
pub const UV_COMPILE_BYTECODE: &'static str = "UV_COMPILE_BYTECODE";

View file

@ -167,6 +167,11 @@ Defaults to `~/.local/bin`.
Equivalent to the `--keyring-provider` command-line argument. If set, uv
will use this value as the keyring provider.
### `UV_LIBC`
Overrides the environment-determined libc on linux systems when filling in the current platform
within Python version requests. Options are: `gnu`, `gnueabi`, `gnueabihf`, `musl`, and `none`.
### `UV_LINK_MODE`
Equivalent to the `--link-mode` command-line argument. If set, uv will use this as