diff --git a/Cargo.lock b/Cargo.lock index 6472b446f5af..040a73d76cf3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4736,6 +4736,7 @@ dependencies = [ "schemars", "serde", "serde_json", + "tracing", "uv-auth", "uv-cache", "uv-normalize", diff --git a/README.md b/README.md index 47d998b66569..d313919a890d 100644 --- a/README.md +++ b/README.md @@ -584,6 +584,9 @@ In addition, uv respects the following environment variables: - `ZSH_VERSION`: Used to detect the use of the Zsh shell. - `RAYON_NUM_THREADS`: Used to control the number of threads used when unzipping and installing packages. See the [rayon documentation](https://docs.rs/rayon/latest/rayon/) for more. +- `MACOSX_DEPLOYMENT_TARGET`: Used with `--python-platform macos` and related variants to set the + deployment target (i.e., the minimum supported macOS version). Defaults to `12.0`, the + least-recent non-EOL macOS version at time of writing. ## Versioning diff --git a/crates/uv-configuration/Cargo.toml b/crates/uv-configuration/Cargo.toml index 15277a1c3aa9..0be1229898aa 100644 --- a/crates/uv-configuration/Cargo.toml +++ b/crates/uv-configuration/Cargo.toml @@ -27,6 +27,7 @@ rustc-hash = { workspace = true } schemars = { workspace = true, optional = true } serde = { workspace = true } serde_json = { workspace = true } +tracing = { workspace = true } [features] default = [] diff --git a/crates/uv-configuration/src/target_triple.rs b/crates/uv-configuration/src/target_triple.rs index ceedf03c5d7f..0a49b24c6aee 100644 --- a/crates/uv-configuration/src/target_triple.rs +++ b/crates/uv-configuration/src/target_triple.rs @@ -1,3 +1,5 @@ +use tracing::debug; + use pep508_rs::MarkerEnvironment; use platform_tags::{Arch, Os, Platform}; @@ -29,13 +31,18 @@ pub enum TargetTriple { #[cfg_attr(feature = "schemars", schemars(rename = "x86_64-unknown-linux-gnu"))] X8664UnknownLinuxGnu, - /// An ARM-based macOS target, as seen on Apple Silicon devices, with support for the - /// least-recent, non-EOL macOS version (12.0). + /// An ARM-based macOS target, as seen on Apple Silicon devices + /// + /// By default, assumes the least-recent, non-EOL macOS version (12.0), but respects + /// the `MACOSX_DEPLOYMENT_TARGET` environment variable if set. #[cfg_attr(feature = "clap", value(name = "aarch64-apple-darwin"))] #[cfg_attr(feature = "schemars", schemars(rename = "aarch64-apple-darwin"))] Aarch64AppleDarwin, - /// An x86 macOS target, with support for the least-recent, non-EOL macOS version (12.0). + /// An x86 macOS target. + /// + /// By default, assumes the least-recent, non-EOL macOS version (12.0), but respects + /// the `MACOSX_DEPLOYMENT_TARGET` environment variable if set. #[cfg_attr(feature = "clap", value(name = "x86_64-apple-darwin"))] #[cfg_attr(feature = "schemars", schemars(rename = "x86_64-apple-darwin"))] X8664AppleDarwin, @@ -88,20 +95,20 @@ impl TargetTriple { }, Arch::X86_64, ), - Self::Macos | Self::Aarch64AppleDarwin => Platform::new( - Os::Macos { - major: 12, - minor: 0, - }, - Arch::Aarch64, - ), - Self::X8664AppleDarwin => Platform::new( - Os::Macos { - major: 12, - minor: 0, - }, - Arch::X86_64, - ), + Self::Macos | Self::Aarch64AppleDarwin => { + let (major, minor) = macos_deployment_target().map_or((12, 0), |(major, minor)| { + debug!("Found macOS deployment target: {}.{}", major, minor); + (major, minor) + }); + Platform::new(Os::Macos { major, minor }, Arch::Aarch64) + } + Self::X8664AppleDarwin => { + let (major, minor) = macos_deployment_target().map_or((12, 0), |(major, minor)| { + debug!("Found macOS deployment target: {}.{}", major, minor); + (major, minor) + }); + Platform::new(Os::Macos { major, minor }, Arch::X86_64) + } Self::Aarch64UnknownLinuxGnu => Platform::new( Os::Manylinux { major: 2, @@ -271,3 +278,17 @@ impl TargetTriple { } } } + +/// Return the macOS deployment target as parsed from the environment. +fn macos_deployment_target() -> Option<(u16, u16)> { + let version = std::env::var("MACOSX_DEPLOYMENT_TARGET").ok()?; + let mut parts = version.split('.'); + + // Parse the major version (e.g., `12` in `12.0`). + let major = parts.next()?.parse::().ok()?; + + // Parse the minor version (e.g., `0` in `12.0`), with a default of `0`. + let minor = parts.next().unwrap_or("0").parse::().ok()?; + + Some((major, minor)) +} diff --git a/uv.schema.json b/uv.schema.json index 5dd3b779464c..829f90da98d0 100644 --- a/uv.schema.json +++ b/uv.schema.json @@ -815,14 +815,14 @@ ] }, { - "description": "An ARM-based macOS target, as seen on Apple Silicon devices, with support for the least-recent, non-EOL macOS version (12.0).", + "description": "An ARM-based macOS target, as seen on Apple Silicon devices\n\nBy default, assumes the least-recent, non-EOL macOS version (12.0), but respects the `MACOSX_DEPLOYMENT_TARGET` environment variable if set.", "type": "string", "enum": [ "aarch64-apple-darwin" ] }, { - "description": "An x86 macOS target, with support for the least-recent, non-EOL macOS version (12.0).", + "description": "An x86 macOS target.\n\nBy default, assumes the least-recent, non-EOL macOS version (12.0), but respects the `MACOSX_DEPLOYMENT_TARGET` environment variable if set.", "type": "string", "enum": [ "x86_64-apple-darwin"