From cbedc33d7bac08850aa9c8e4aef754fdbb081f23 Mon Sep 17 00:00:00 2001 From: BlackHoleFox Date: Thu, 3 Aug 2023 23:46:04 -0500 Subject: [PATCH] Use rustc's minimum Apple deployment targets when available --- src/lib.rs | 122 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 80 insertions(+), 42 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2f82c3974..bb674edfe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2253,31 +2253,16 @@ impl Build { Catalyst(&'static str), } - enum Os { - MacOs, - Ios, - WatchOs, - } - impl Display for Os { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match self { - Os::MacOs => f.write_str("macOS"), - Os::Ios => f.write_str("iOS"), - Os::WatchOs => f.write_str("WatchOS"), - } - } - } - let target = self.get_target()?; let os = if target.contains("-darwin") { - Os::MacOs + AppleOs::MacOs } else if target.contains("-watchos") { - Os::WatchOs + AppleOs::WatchOs } else { - Os::Ios + AppleOs::Ios }; let is_mac = match os { - Os::MacOs => true, + AppleOs::MacOs => true, _ => false, }; @@ -2351,29 +2336,11 @@ impl Build { } }; - let (sdk_prefix, sim_prefix, min_version) = match os { - Os::MacOs => ( - "macosx", - "", - std::env::var("MACOSX_DEPLOYMENT_TARGET").unwrap_or_else(|_| { - (if arch_str == "aarch64" { - "11.0" - } else { - "10.7" - }) - .into() - }), - ), - Os::Ios => ( - "iphone", - "ios-", - std::env::var("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "7.0".into()), - ), - Os::WatchOs => ( - "watch", - "watch", - std::env::var("WATCHOS_DEPLOYMENT_TARGET").unwrap_or_else(|_| "2.0".into()), - ), + let min_version = self.apple_deployment_version(os, &target, arch_str); + let (sdk_prefix, sim_prefix) = match os { + AppleOs::MacOs => ("macosx", ""), + AppleOs::Ios => ("iphone", "ios-"), + AppleOs::WatchOs => ("watch", "watch"), }; let sdk = match arch { @@ -3323,6 +3290,61 @@ impl Build { Ok(ret) } + fn apple_deployment_version(&self, os: AppleOs, target: &str, arch_str: &str) -> String { + fn rustc_provided_target(rustc: Option<&str>, target: &str) -> Option { + let rustc = rustc?; + let output = Command::new(rustc) + .stderr(Stdio::piped()) + .stdout(Stdio::piped()) + .args(&["--target", target]) + .args(&["--print", "deployment-target"]) + .output() + .ok()?; + + if output.status.success() { + std::str::from_utf8(&output.stdout) + .unwrap() + .split('=') + .last() + .map(|v| v.trim()) + .map(ToString::to_string) + } else { + // rustc is < 1.71 + None + } + } + + let rustc = self.getenv("RUSTC"); + let rustc = rustc.as_deref(); + // note the hardcoded minimums here are subject to change in a future compiler release, + // so the ones rustc knows about are preferred. For any compiler version that has bumped them + // though, `--print deployment-target` will be present and the fallbacks won't be used. + // + // the ordering of env -> rustc -> old defaults is intentional for performance when using + // an explicit target + match os { + AppleOs::MacOs => env::var("MACOSX_DEPLOYMENT_TARGET") + .ok() + .or_else(|| rustc_provided_target(rustc, target)) + .unwrap_or_else(|| { + if arch_str == "aarch64" { + "11.0" + } else { + "10.7" + } + .into() + }), + AppleOs::Ios => env::var("IPHONEOS_DEPLOYMENT_TARGET") + .ok() + .or_else(|| rustc_provided_target(rustc, target)) + .unwrap_or_else(|| "7.0".into()), + AppleOs::WatchOs => env::var("WATCHOS_DEPLOYMENT_TARGET") + .ok() + .or_else(|| rustc_provided_target(rustc, target)) + .unwrap_or_else(|| "2.0".into()), + } + } + fn cuda_file_count(&self) -> usize { self.files .iter() @@ -3676,6 +3698,22 @@ fn command_add_output_file( } } +#[derive(Clone, Copy)] +enum AppleOs { + MacOs, + Ios, + WatchOs, +} +impl Display for AppleOs { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + AppleOs::MacOs => f.write_str("macOS"), + AppleOs::Ios => f.write_str("iOS"), + AppleOs::WatchOs => f.write_str("WatchOS"), + } + } +} + // Use by default minimum available API level // See note about naming here // https://android.googlesource.com/platform/ndk/+/refs/heads/ndk-release-r21/docs/BuildSystemMaintainers.md#Clang