From 0fea8e197fbd9bfc9b72ae2dccb1bdd1b5742be4 Mon Sep 17 00:00:00 2001 From: James Farrell Date: Thu, 2 May 2024 15:33:39 -0500 Subject: [PATCH 1/5] Don't use the value of SDKROOT if it doesn't match the target. The SDKROOT environment variable can be problematic on Mac. In cases where you are compiling for multiple targets, SDKROOT cannot be right for all of them. Furthermore, the system Python interpreter sets SDKROOT to the MacOSX SDK if not already set. So, if you are using a Python script to run a build, and you need to build for multiple targets, the logic in the cc crate doesn't work. This is precisely what is happening with rustc itself, and so we can't upgrade the version of the cc crate used by the bootstrap code. (Unsetting SDKROOT doesn't work either because the custom clang build that rustc uses for CI depends on it being set) --- src/lib.rs | 38 ++++++++++++++++++++++++++++++++++++-- tests/test.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 99c2fd9c8..ff114fcb6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3653,8 +3653,42 @@ impl Build { } fn apple_sdk_root(&self, sdk: &str) -> Result { - if let Some(sdkroot) = env::var_os("SDKROOT") { - return Ok(sdkroot); + // Code copied from rustc's compiler/rustc_codegen_ssa/src/back/link.rs. + if let Ok(sdkroot) = env::var("SDKROOT") { + let p = Path::new(&sdkroot); + match sdk { + // Ignore `SDKROOT` if it's clearly set for the wrong platform. + "appletvos" + if sdkroot.contains("TVSimulator.platform") + || sdkroot.contains("MacOSX.platform") => {} + "appletvsimulator" + if sdkroot.contains("TVOS.platform") || sdkroot.contains("MacOSX.platform") => { + } + "iphoneos" + if sdkroot.contains("iPhoneSimulator.platform") + || sdkroot.contains("MacOSX.platform") => {} + "iphonesimulator" + if sdkroot.contains("iPhoneOS.platform") + || sdkroot.contains("MacOSX.platform") => {} + "macosx10.15" + if sdkroot.contains("iPhoneOS.platform") + || sdkroot.contains("iPhoneSimulator.platform") => {} + "watchos" + if sdkroot.contains("WatchSimulator.platform") + || sdkroot.contains("MacOSX.platform") => {} + "watchsimulator" + if sdkroot.contains("WatchOS.platform") + || sdkroot.contains("MacOSX.platform") => {} + "xros" + if sdkroot.contains("XRSimulator.platform") + || sdkroot.contains("MacOSX.platform") => {} + "xrsimulator" + if sdkroot.contains("XROS.platform") || sdkroot.contains("MacOSX.platform") => { + } + // Ignore `SDKROOT` if it's not a valid path. + _ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {} + _ => return Ok(sdkroot.into()), + } } let mut cache = self diff --git a/tests/test.rs b/tests/test.rs index fac6a67b0..e9bbc94a9 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -626,6 +626,32 @@ fn clang_apple_visionos() { test.cmd(0).must_not_have("-mxrsimulator-version-min=1.0"); } +#[cfg(target_os = "macos")] +#[test] +fn apple_sdkroot_wrong() { + let output = std::process::Command::new("xcrun") + .args(["--show-sdk-path", "--sdk", "iphoneos"]) + .output() + .unwrap(); + if !output.status.success() { + return; + } + + let wrong_sdkroot = "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk"; + let test = Test::clang(); + test.gcc() + .__set_env("SDKROOT", wrong_sdkroot) + .target("aarch64-apple-ios") + .file("foo.c") + .compile("foo"); + + dbg!(test.cmd(0).args); + + test.cmd(0) + .must_have(std::str::from_utf8(&output.stdout).unwrap().trim()); + test.cmd(0).must_not_have(wrong_sdkroot); +} + #[test] fn compile_intermediates() { let test = Test::gnu(); From 0f1198611139c697a5d85fc7219b30a916176f74 Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Mon, 6 May 2024 12:22:09 +1000 Subject: [PATCH 2/5] use env::var_os instead of env::var --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index ff114fcb6..adb8a2a8b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3654,7 +3654,7 @@ impl Build { fn apple_sdk_root(&self, sdk: &str) -> Result { // Code copied from rustc's compiler/rustc_codegen_ssa/src/back/link.rs. - if let Ok(sdkroot) = env::var("SDKROOT") { + if let Some(sdkroot) = env::var_os("SDKROOT") { let p = Path::new(&sdkroot); match sdk { // Ignore `SDKROOT` if it's clearly set for the wrong platform. From 1eb890bc8887529cc6b2598107f7da6973439285 Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Mon, 6 May 2024 12:24:53 +1000 Subject: [PATCH 3/5] Fix compilation --- src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib.rs b/src/lib.rs index adb8a2a8b..1faacb950 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3656,6 +3656,7 @@ impl Build { // Code copied from rustc's compiler/rustc_codegen_ssa/src/back/link.rs. if let Some(sdkroot) = env::var_os("SDKROOT") { let p = Path::new(&sdkroot); + let sdkroot = sdkroot.to_string_lossy(); match sdk { // Ignore `SDKROOT` if it's clearly set for the wrong platform. "appletvos" From a017c41eadb12a2e4ec88d749208c2c077d7a4c4 Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Mon, 6 May 2024 12:30:20 +1000 Subject: [PATCH 4/5] Fix compilation error --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1faacb950..de4af32e1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3655,7 +3655,7 @@ impl Build { fn apple_sdk_root(&self, sdk: &str) -> Result { // Code copied from rustc's compiler/rustc_codegen_ssa/src/back/link.rs. if let Some(sdkroot) = env::var_os("SDKROOT") { - let p = Path::new(&sdkroot); + let p = PathBuf::from(sdkroot); let sdkroot = sdkroot.to_string_lossy(); match sdk { // Ignore `SDKROOT` if it's clearly set for the wrong platform. @@ -3688,7 +3688,7 @@ impl Build { } // Ignore `SDKROOT` if it's not a valid path. _ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {} - _ => return Ok(sdkroot.into()), + _ => return Ok(p.into()), } } From 16aa23850d05ac91197433c8ffec479c560fd049 Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Mon, 6 May 2024 12:36:19 +1000 Subject: [PATCH 5/5] fix compilation --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index de4af32e1..7e54c891e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3656,7 +3656,7 @@ impl Build { // Code copied from rustc's compiler/rustc_codegen_ssa/src/back/link.rs. if let Some(sdkroot) = env::var_os("SDKROOT") { let p = PathBuf::from(sdkroot); - let sdkroot = sdkroot.to_string_lossy(); + let sdkroot = p.to_string_lossy(); match sdk { // Ignore `SDKROOT` if it's clearly set for the wrong platform. "appletvos"