Skip to content

Commit 89fb94c

Browse files
authored
Fix building for Mac Catalyst (#1577)
Without this change, we end up passing `aarch64-apple-ios26.0-macabimacabi` to the compiler, which is definitely wrong. The core change here is to handle this in `from_cargo_environment_variables` as well, the rest is just a cleanup now that `target.env` contains the canonical value (and `target.abi`). See also the previous #1517 and #1534.
1 parent 7abc77c commit 89fb94c

File tree

5 files changed

+72
-60
lines changed

5 files changed

+72
-60
lines changed

src/lib.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2248,12 +2248,11 @@ impl Build {
22482248
// So instead, we pass the deployment target with `-m*-version-min=`, and only
22492249
// pass it here on visionOS and Mac Catalyst where that option does not exist:
22502250
// https://github.com/rust-lang/cc-rs/issues/1383
2251-
let version =
2252-
if target.os == "visionos" || target.get_apple_env() == Some(MacCatalyst) {
2253-
Some(self.apple_deployment_target(target))
2254-
} else {
2255-
None
2256-
};
2251+
let version = if target.os == "visionos" || target.env == "macabi" {
2252+
Some(self.apple_deployment_target(target))
2253+
} else {
2254+
None
2255+
};
22572256

22582257
let clang_target =
22592258
target.llvm_target(&self.get_raw_target()?, version.as_deref());
@@ -2746,9 +2745,7 @@ impl Build {
27462745
// https://github.com/llvm/llvm-project/issues/88271
27472746
// And the workaround to use `-mtargetos=` cannot be used with the `--target` flag that we
27482747
// otherwise specify. So we avoid emitting that, and put the version in `--target` instead.
2749-
if cmd.is_like_gnu()
2750-
|| !(target.os == "visionos" || target.get_apple_env() == Some(MacCatalyst))
2751-
{
2748+
if cmd.is_like_gnu() || !(target.os == "visionos" || target.env == "macabi") {
27522749
let min_version = self.apple_deployment_target(&target);
27532750
cmd.args
27542751
.push(target.apple_version_flag(&min_version).into());
@@ -2768,7 +2765,7 @@ impl Build {
27682765
cmd.env
27692766
.push(("SDKROOT".into(), OsStr::new(&sdk_path).to_owned()));
27702767

2771-
if target.get_apple_env() == Some(MacCatalyst) {
2768+
if target.env == "macabi" {
27722769
// Mac Catalyst uses the macOS SDK, but to compile against and
27732770
// link to iOS-specific frameworks, we should have the support
27742771
// library stubs in the include and library search path.

src/target.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ mod generated;
66
mod llvm;
77
mod parser;
88

9-
pub(crate) use apple::*;
109
pub(crate) use parser::TargetInfoParser;
1110

1211
/// Information specific to a `rustc` target.

src/target/apple.rs

Lines changed: 22 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,18 @@
11
use super::TargetInfo;
22

3-
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
4-
pub(crate) enum AppleEnv {
5-
Simulator,
6-
MacCatalyst,
7-
}
8-
pub(crate) use AppleEnv::*;
9-
103
impl TargetInfo<'_> {
11-
pub(crate) fn get_apple_env(&self) -> Option<AppleEnv> {
12-
match (self.env, self.abi) {
13-
("sim", _) | (_, "sim") => Some(Simulator),
14-
("macabi", _) | (_, "macabi") => Some(MacCatalyst),
15-
_ => None,
16-
}
17-
}
18-
194
pub(crate) fn apple_sdk_name(&self) -> &'static str {
20-
match (self.os, self.get_apple_env()) {
21-
("macos", None) => "macosx",
22-
("ios", None) => "iphoneos",
23-
("ios", Some(Simulator)) => "iphonesimulator",
24-
("ios", Some(MacCatalyst)) => "macosx",
25-
("tvos", None) => "appletvos",
26-
("tvos", Some(Simulator)) => "appletvsimulator",
27-
("watchos", None) => "watchos",
28-
("watchos", Some(Simulator)) => "watchsimulator",
29-
("visionos", None) => "xros",
30-
("visionos", Some(Simulator)) => "xrsimulator",
5+
match (self.os, self.env) {
6+
("macos", "") => "macosx",
7+
("ios", "") => "iphoneos",
8+
("ios", "sim") => "iphonesimulator",
9+
("ios", "macabi") => "macosx",
10+
("tvos", "") => "appletvos",
11+
("tvos", "sim") => "appletvsimulator",
12+
("watchos", "") => "watchos",
13+
("watchos", "sim") => "watchsimulator",
14+
("visionos", "") => "xros",
15+
("visionos", "sim") => "xrsimulator",
3116
(os, _) => panic!("invalid Apple target OS {}", os),
3217
}
3318
}
@@ -45,19 +30,19 @@ impl TargetInfo<'_> {
4530
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mmacos-version-min
4631
// https://clang.llvm.org/docs/AttributeReference.html#availability
4732
// https://gcc.gnu.org/onlinedocs/gcc/Darwin-Options.html#index-mmacosx-version-min
48-
match (self.os, self.get_apple_env()) {
49-
("macos", None) => format!("-mmacosx-version-min={min_version}"),
50-
("ios", None) => format!("-miphoneos-version-min={min_version}"),
51-
("ios", Some(Simulator)) => format!("-mios-simulator-version-min={min_version}"),
52-
("ios", Some(MacCatalyst)) => format!("-mtargetos=ios{min_version}-macabi"),
53-
("tvos", None) => format!("-mappletvos-version-min={min_version}"),
54-
("tvos", Some(Simulator)) => format!("-mappletvsimulator-version-min={min_version}"),
55-
("watchos", None) => format!("-mwatchos-version-min={min_version}"),
56-
("watchos", Some(Simulator)) => format!("-mwatchsimulator-version-min={min_version}"),
33+
match (self.os, self.env) {
34+
("macos", "") => format!("-mmacosx-version-min={min_version}"),
35+
("ios", "") => format!("-miphoneos-version-min={min_version}"),
36+
("ios", "sim") => format!("-mios-simulator-version-min={min_version}"),
37+
("ios", "macabi") => format!("-mtargetos=ios{min_version}-macabi"),
38+
("tvos", "") => format!("-mappletvos-version-min={min_version}"),
39+
("tvos", "sim") => format!("-mappletvsimulator-version-min={min_version}"),
40+
("watchos", "") => format!("-mwatchos-version-min={min_version}"),
41+
("watchos", "sim") => format!("-mwatchsimulator-version-min={min_version}"),
5742
// `-mxros-version-min` does not exist
5843
// https://github.com/llvm/llvm-project/issues/88271
59-
("visionos", None) => format!("-mtargetos=xros{min_version}"),
60-
("visionos", Some(Simulator)) => format!("-mtargetos=xros{min_version}-simulator"),
44+
("visionos", "") => format!("-mtargetos=xros{min_version}"),
45+
("visionos", "sim") => format!("-mtargetos=xros{min_version}-simulator"),
6146
(os, _) => panic!("invalid Apple target OS {}", os),
6247
}
6348
}

src/target/llvm.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,6 @@ impl TargetInfo<'_> {
9595
env => env,
9696
};
9797
let abi = match self.abi {
98-
"sim" => {
99-
if env != "simulator" {
100-
"simulator"
101-
} else {
102-
""
103-
}
104-
}
10598
"llvm" | "softfloat" | "uwp" | "vec-extabi" => "",
10699
"ilp32" => "_ilp32",
107100
"abi64" => "",
@@ -198,8 +191,8 @@ mod tests {
198191
arch: "aarch64",
199192
vendor: "apple",
200193
os: "ios",
201-
env: "",
202-
abi: "sim",
194+
env: "sim",
195+
abi: "",
203196
}
204197
.llvm_target("aarch64-apple-ios-sim", Some("14.0")),
205198
"arm64-apple-ios14.0-simulator"

src/target/parser.rs

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::env;
1+
use std::{env, mem};
22

33
use crate::{target::TargetInfo, utilities::OnceLock, Error, ErrorKind};
44

@@ -67,13 +67,25 @@ impl TargetInfoParserInner {
6767
let arch = cargo_env("CARGO_CFG_TARGET_ARCH", ft.map(|t| t.arch))?;
6868
let vendor = cargo_env("CARGO_CFG_TARGET_VENDOR", ft.map(|t| t.vendor))?;
6969
let os = cargo_env("CARGO_CFG_TARGET_OS", ft.map(|t| t.os))?;
70-
let env = cargo_env("CARGO_CFG_TARGET_ENV", ft.map(|t| t.env))?;
70+
let mut env = cargo_env("CARGO_CFG_TARGET_ENV", ft.map(|t| t.env))?;
7171
// `target_abi` was stabilized in Rust 1.78, which is higher than our
7272
// MSRV, so it may not always be available; In that case, fall back to
7373
// `""`, which is _probably_ correct for unknown target names.
74-
let abi = cargo_env("CARGO_CFG_TARGET_ABI", ft.map(|t| t.abi))
74+
let mut abi = cargo_env("CARGO_CFG_TARGET_ABI", ft.map(|t| t.abi))
7575
.unwrap_or_else(|_| String::default().into_boxed_str());
7676

77+
// Remove `macabi` and `sim` from `target_abi` (if present), it's been moved to `target_env`.
78+
// TODO: Remove once MSRV is bumped to 1.91 and `rustc` removes these from `target_abi`.
79+
if matches!(&*abi, "macabi" | "sim") {
80+
debug_assert!(
81+
matches!(&*env, "" | "macbi" | "sim"),
82+
"env/abi mismatch: {:?}, {:?}",
83+
env,
84+
abi,
85+
);
86+
env = mem::replace(&mut abi, String::default().into_boxed_str());
87+
}
88+
7789
Ok(Self {
7890
full_arch: full_arch.to_string().into_boxed_str(),
7991
arch,
@@ -597,4 +609,30 @@ mod tests {
597609
panic!("failed comparing targets");
598610
}
599611
}
612+
613+
#[test]
614+
fn parses_apple_envs_correctly() {
615+
assert_eq!(
616+
TargetInfo::from_rustc_target("aarch64-apple-ios-macabi").unwrap(),
617+
TargetInfo {
618+
full_arch: "aarch64",
619+
arch: "aarch64",
620+
vendor: "apple",
621+
os: "ios",
622+
env: "macabi",
623+
abi: "",
624+
}
625+
);
626+
assert_eq!(
627+
TargetInfo::from_rustc_target("aarch64-apple-ios-sim").unwrap(),
628+
TargetInfo {
629+
full_arch: "aarch64",
630+
arch: "aarch64",
631+
vendor: "apple",
632+
os: "ios",
633+
env: "sim",
634+
abi: "",
635+
}
636+
);
637+
}
600638
}

0 commit comments

Comments
 (0)