about summary refs log tree commit diff
path: root/compiler/rustc_codegen_ssa/src
diff options
context:
space:
mode:
authorMads Marquart <mads@marquart.dk>2025-08-11 22:29:00 +0200
committerMads Marquart <mads@marquart.dk>2025-08-11 22:29:00 +0200
commit1cc44bfd22f4db5bcf3921f4a8b64df4e9cf4124 (patch)
tree33bd58076ecd2455726ce1ab942336e57fd1faa6 /compiler/rustc_codegen_ssa/src
parent1dc37df51476b568b1fa94db14a7669656989862 (diff)
downloadrust-1cc44bfd22f4db5bcf3921f4a8b64df4e9cf4124.tar.gz
rust-1cc44bfd22f4db5bcf3921f4a8b64df4e9cf4124.zip
Pass Apple SDK root to compiler driver via SDKROOT env var
This is more in-line with what Apple's tooling expects, and allows us to
better support custom compiler drivers (such as certain Homebrew and
Nixpkgs compilers) that prefer their own `-isysroot` flag.

Effectively, we now invoke the compiler driver as-if it was invoked as
`xcrun -sdk $sdk_name $tool`.
Diffstat (limited to 'compiler/rustc_codegen_ssa/src')
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs44
1 files changed, 36 insertions, 8 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index bda8eeb4c92..49454f2d845 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -3208,15 +3208,37 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) ->
     let sdkroot = sess.time("get_apple_sdk_root", || get_apple_sdk_root(sess))?;
 
     if cc == Cc::Yes {
-        // Use `-isysroot` instead of `--sysroot`, as only the former
-        // makes Clang treat it as a platform SDK.
+        // There are a few options to pass the SDK root when linking with a C/C++ compiler:
+        // - The `--sysroot` flag.
+        // - The `-isysroot` flag.
+        // - The `SDKROOT` environment variable.
         //
-        // This is admittedly a bit strange, as on most targets
-        // `-isysroot` only applies to include header files, but on Apple
-        // targets this also applies to libraries and frameworks.
-        cmd.cc_arg("-isysroot");
-        cmd.cc_arg(&sdk_root);
+        // `--sysroot` isn't actually enough to get Clang to treat it as a platform SDK, you need
+        // to specify `-isysroot`. This is admittedly a bit strange, as on most targets `-isysroot`
+        // only applies to include header files, but on Apple targets it also applies to libraries
+        // and frameworks.
+        //
+        // This leaves the choice between `-isysroot` and `SDKROOT`. Both are supported by Clang and
+        // GCC, though they may not be supported by all compiler drivers. We choose `SDKROOT`,
+        // primarily because that is the same interface that is used when invoking the tool under
+        // `xcrun -sdk macosx $tool`.
+        //
+        // In that sense, if a given compiler driver does not support `SDKROOT`, the blame is fairly
+        // clearly in the tool in question, since they also don't support being run under `xcrun`.
+        //
+        // Additionally, `SDKROOT` is an environment variable and thus optional. It also has lower
+        // precedence than `-isysroot`, so a custom compiler driver that does not support it and
+        // instead figures out the SDK on their own can easily do so by using `-isysroot`.
+        //
+        // (This in particular affects Clang built with the `DEFAULT_SYSROOT` CMake flag, such as
+        // the one provided by some versions of Homebrew's `llvm` package. Those will end up
+        // ignoring the value we set here, and instead use their built-in sysroot).
+        cmd.cmd().env("SDKROOT", &sdkroot);
     } else {
+        // When invoking the linker directly, we use the `-syslibroot` parameter. `SDKROOT` is not
+        // read by the linker, so it's really the only option.
+        //
+        // This is also what Clang does.
         cmd.link_arg("-syslibroot");
         cmd.link_arg(&sdkroot);
     }
@@ -3250,7 +3272,13 @@ fn get_apple_sdk_root(sess: &Session) -> Option<PathBuf> {
             }
             "macosx"
                 if sdkroot.contains("iPhoneOS.platform")
-                    || sdkroot.contains("iPhoneSimulator.platform") => {}
+                    || sdkroot.contains("iPhoneSimulator.platform")
+                    || sdkroot.contains("AppleTVOS.platform")
+                    || sdkroot.contains("AppleTVSimulator.platform")
+                    || sdkroot.contains("WatchOS.platform")
+                    || sdkroot.contains("WatchSimulator.platform")
+                    || sdkroot.contains("XROS.platform")
+                    || sdkroot.contains("XRSimulator.platform") => {}
             "watchos"
                 if sdkroot.contains("WatchSimulator.platform")
                     || sdkroot.contains("MacOSX.platform") => {}