From f31ae2d7e947983d8c0fcdd79f8f48df37f702d1 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sat, 27 Sep 2025 23:56:44 +0200 Subject: [PATCH] Fix building for Mac Catalyst --- src/lib.rs | 17 ++++++------- src/target.rs | 1 - src/target/apple.rs | 59 +++++++++++++++++--------------------------- src/target/llvm.rs | 11 ++------- src/target/parser.rs | 44 ++++++++++++++++++++++++++++++--- 5 files changed, 72 insertions(+), 60 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4c0885f14..e7e2f58de 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2248,12 +2248,11 @@ impl Build { // So instead, we pass the deployment target with `-m*-version-min=`, and only // pass it here on visionOS and Mac Catalyst where that option does not exist: // https://github.com/rust-lang/cc-rs/issues/1383 - let version = - if target.os == "visionos" || target.get_apple_env() == Some(MacCatalyst) { - Some(self.apple_deployment_target(target)) - } else { - None - }; + let version = if target.os == "visionos" || target.env == "macabi" { + Some(self.apple_deployment_target(target)) + } else { + None + }; let clang_target = target.llvm_target(&self.get_raw_target()?, version.as_deref()); @@ -2746,9 +2745,7 @@ impl Build { // https://github.com/llvm/llvm-project/issues/88271 // And the workaround to use `-mtargetos=` cannot be used with the `--target` flag that we // otherwise specify. So we avoid emitting that, and put the version in `--target` instead. - if cmd.is_like_gnu() - || !(target.os == "visionos" || target.get_apple_env() == Some(MacCatalyst)) - { + if cmd.is_like_gnu() || !(target.os == "visionos" || target.env == "macabi") { let min_version = self.apple_deployment_target(&target); cmd.args .push(target.apple_version_flag(&min_version).into()); @@ -2768,7 +2765,7 @@ impl Build { cmd.env .push(("SDKROOT".into(), OsStr::new(&sdk_path).to_owned())); - if target.get_apple_env() == Some(MacCatalyst) { + if target.env == "macabi" { // Mac Catalyst uses the macOS SDK, but to compile against and // link to iOS-specific frameworks, we should have the support // library stubs in the include and library search path. diff --git a/src/target.rs b/src/target.rs index 168326785..ed432df58 100644 --- a/src/target.rs +++ b/src/target.rs @@ -6,7 +6,6 @@ mod generated; mod llvm; mod parser; -pub(crate) use apple::*; pub(crate) use parser::TargetInfoParser; /// Information specific to a `rustc` target. diff --git a/src/target/apple.rs b/src/target/apple.rs index 8db8fb595..70e816797 100644 --- a/src/target/apple.rs +++ b/src/target/apple.rs @@ -1,33 +1,18 @@ use super::TargetInfo; -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub(crate) enum AppleEnv { - Simulator, - MacCatalyst, -} -pub(crate) use AppleEnv::*; - impl TargetInfo<'_> { - pub(crate) fn get_apple_env(&self) -> Option { - match (self.env, self.abi) { - ("sim", _) | (_, "sim") => Some(Simulator), - ("macabi", _) | (_, "macabi") => Some(MacCatalyst), - _ => None, - } - } - pub(crate) fn apple_sdk_name(&self) -> &'static str { - match (self.os, self.get_apple_env()) { - ("macos", None) => "macosx", - ("ios", None) => "iphoneos", - ("ios", Some(Simulator)) => "iphonesimulator", - ("ios", Some(MacCatalyst)) => "macosx", - ("tvos", None) => "appletvos", - ("tvos", Some(Simulator)) => "appletvsimulator", - ("watchos", None) => "watchos", - ("watchos", Some(Simulator)) => "watchsimulator", - ("visionos", None) => "xros", - ("visionos", Some(Simulator)) => "xrsimulator", + match (self.os, self.env) { + ("macos", "") => "macosx", + ("ios", "") => "iphoneos", + ("ios", "sim") => "iphonesimulator", + ("ios", "macabi") => "macosx", + ("tvos", "") => "appletvos", + ("tvos", "sim") => "appletvsimulator", + ("watchos", "") => "watchos", + ("watchos", "sim") => "watchsimulator", + ("visionos", "") => "xros", + ("visionos", "sim") => "xrsimulator", (os, _) => panic!("invalid Apple target OS {}", os), } } @@ -45,19 +30,19 @@ impl TargetInfo<'_> { // https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mmacos-version-min // https://clang.llvm.org/docs/AttributeReference.html#availability // https://gcc.gnu.org/onlinedocs/gcc/Darwin-Options.html#index-mmacosx-version-min - match (self.os, self.get_apple_env()) { - ("macos", None) => format!("-mmacosx-version-min={min_version}"), - ("ios", None) => format!("-miphoneos-version-min={min_version}"), - ("ios", Some(Simulator)) => format!("-mios-simulator-version-min={min_version}"), - ("ios", Some(MacCatalyst)) => format!("-mtargetos=ios{min_version}-macabi"), - ("tvos", None) => format!("-mappletvos-version-min={min_version}"), - ("tvos", Some(Simulator)) => format!("-mappletvsimulator-version-min={min_version}"), - ("watchos", None) => format!("-mwatchos-version-min={min_version}"), - ("watchos", Some(Simulator)) => format!("-mwatchsimulator-version-min={min_version}"), + match (self.os, self.env) { + ("macos", "") => format!("-mmacosx-version-min={min_version}"), + ("ios", "") => format!("-miphoneos-version-min={min_version}"), + ("ios", "sim") => format!("-mios-simulator-version-min={min_version}"), + ("ios", "macabi") => format!("-mtargetos=ios{min_version}-macabi"), + ("tvos", "") => format!("-mappletvos-version-min={min_version}"), + ("tvos", "sim") => format!("-mappletvsimulator-version-min={min_version}"), + ("watchos", "") => format!("-mwatchos-version-min={min_version}"), + ("watchos", "sim") => format!("-mwatchsimulator-version-min={min_version}"), // `-mxros-version-min` does not exist // https://github.com/llvm/llvm-project/issues/88271 - ("visionos", None) => format!("-mtargetos=xros{min_version}"), - ("visionos", Some(Simulator)) => format!("-mtargetos=xros{min_version}-simulator"), + ("visionos", "") => format!("-mtargetos=xros{min_version}"), + ("visionos", "sim") => format!("-mtargetos=xros{min_version}-simulator"), (os, _) => panic!("invalid Apple target OS {}", os), } } diff --git a/src/target/llvm.rs b/src/target/llvm.rs index b29fdb706..4d045bcd1 100644 --- a/src/target/llvm.rs +++ b/src/target/llvm.rs @@ -95,13 +95,6 @@ impl TargetInfo<'_> { env => env, }; let abi = match self.abi { - "sim" => { - if env != "simulator" { - "simulator" - } else { - "" - } - } "llvm" | "softfloat" | "uwp" | "vec-extabi" => "", "ilp32" => "_ilp32", "abi64" => "", @@ -198,8 +191,8 @@ mod tests { arch: "aarch64", vendor: "apple", os: "ios", - env: "", - abi: "sim", + env: "sim", + abi: "", } .llvm_target("aarch64-apple-ios-sim", Some("14.0")), "arm64-apple-ios14.0-simulator" diff --git a/src/target/parser.rs b/src/target/parser.rs index 4bcf70433..ec904e241 100644 --- a/src/target/parser.rs +++ b/src/target/parser.rs @@ -1,4 +1,4 @@ -use std::env; +use std::{env, mem}; use crate::{target::TargetInfo, utilities::OnceLock, Error, ErrorKind}; @@ -67,13 +67,25 @@ impl TargetInfoParserInner { let arch = cargo_env("CARGO_CFG_TARGET_ARCH", ft.map(|t| t.arch))?; let vendor = cargo_env("CARGO_CFG_TARGET_VENDOR", ft.map(|t| t.vendor))?; let os = cargo_env("CARGO_CFG_TARGET_OS", ft.map(|t| t.os))?; - let env = cargo_env("CARGO_CFG_TARGET_ENV", ft.map(|t| t.env))?; + let mut env = cargo_env("CARGO_CFG_TARGET_ENV", ft.map(|t| t.env))?; // `target_abi` was stabilized in Rust 1.78, which is higher than our // MSRV, so it may not always be available; In that case, fall back to // `""`, which is _probably_ correct for unknown target names. - let abi = cargo_env("CARGO_CFG_TARGET_ABI", ft.map(|t| t.abi)) + let mut abi = cargo_env("CARGO_CFG_TARGET_ABI", ft.map(|t| t.abi)) .unwrap_or_else(|_| String::default().into_boxed_str()); + // Remove `macabi` and `sim` from `target_abi` (if present), it's been moved to `target_env`. + // TODO: Remove once MSRV is bumped to 1.91 and `rustc` removes these from `target_abi`. + if matches!(&*abi, "macabi" | "sim") { + debug_assert!( + matches!(&*env, "" | "macbi" | "sim"), + "env/abi mismatch: {:?}, {:?}", + env, + abi, + ); + env = mem::replace(&mut abi, String::default().into_boxed_str()); + } + Ok(Self { full_arch: full_arch.to_string().into_boxed_str(), arch, @@ -597,4 +609,30 @@ mod tests { panic!("failed comparing targets"); } } + + #[test] + fn parses_apple_envs_correctly() { + assert_eq!( + TargetInfo::from_rustc_target("aarch64-apple-ios-macabi").unwrap(), + TargetInfo { + full_arch: "aarch64", + arch: "aarch64", + vendor: "apple", + os: "ios", + env: "macabi", + abi: "", + } + ); + assert_eq!( + TargetInfo::from_rustc_target("aarch64-apple-ios-sim").unwrap(), + TargetInfo { + full_arch: "aarch64", + arch: "aarch64", + vendor: "apple", + os: "ios", + env: "sim", + abi: "", + } + ); + } }