Skip to content

Commit 1d13162

Browse files
committed
Always attempt to invoke xcrun to get the Apple SDK
The exact reasoning why we do not always pass the SDK root when linking on macOS eludes me, but I suspect it's because we want to support compiler drivers which do not support the `-isysroot` option. Since we now pass the SDK root via the environment variable SDKROOT, compiler drivers that don't support it can just ignore it. Similarly, since we only warn when xcrun fails, users that expect their compiler driver to provide the SDK location can do so now.
1 parent f4a9110 commit 1d13162

File tree

3 files changed

+41
-4
lines changed

3 files changed

+41
-4
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3200,11 +3200,15 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) ->
32003200
let LinkerFlavor::Darwin(cc, _) = flavor else {
32013201
return None;
32023202
};
3203-
if os == "macos" && cc != Cc::No {
3204-
// FIXME(madsmtm): Remove this branch.
3205-
return None;
3206-
}
32073203

3204+
// The default compiler driver on macOS is at `/usr/bin/cc`. This is a trampoline binary that
3205+
// effectively invokes `xcrun cc` internally to look up both the compiler binary and the SDK
3206+
// root from the current Xcode installation. When cross-compiling, when `rustc` is invoked
3207+
// inside Xcode, or when invoking the linker directly, this default logic is unsuitable, so
3208+
// instead we invoke `xcrun` manually.
3209+
//
3210+
// (Note that this doesn't mean we get a duplicate lookup here - passing `SDKROOT` below will
3211+
// cause the trampoline binary to skip looking up the SDK itself).
32083212
let sdkroot = sess.time("get_apple_sdk_root", || get_apple_sdk_root(sess))?;
32093213

32103214
if cc == Cc::Yes {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn main() {}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//! Test that linking works under an environment similar to what Xcode sets up.
2+
//!
3+
//! Regression test for https://github.com/rust-lang/rust/issues/80817.
4+
5+
//@ only-apple
6+
7+
use run_make_support::{cmd, rustc, target};
8+
9+
fn main() {
10+
// Fetch toolchain `/usr/bin` directory. Usually:
11+
// /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
12+
let clang_bin = cmd("xcrun").arg("--find").arg("clang").run().stdout_utf8();
13+
let toolchain_bin = clang_bin.trim().strip_suffix("/clang").unwrap();
14+
15+
// Put toolchain directory at the front of PATH.
16+
let path = format!("{}:{}", toolchain_bin, std::env::var("PATH").unwrap());
17+
18+
// Check that compiling and linking still works.
19+
//
20+
// Removing `SDKROOT` is necessary for the test to excercise what we want, since bootstrap runs
21+
// under `/usr/bin/python3`, which will set SDKROOT for us.
22+
rustc().target(target()).env_remove("SDKROOT").env("PATH", &path).input("foo.rs").run();
23+
24+
// Also check linking directly with the system linker.
25+
rustc()
26+
.target(target())
27+
.env_remove("SDKROOT")
28+
.env("PATH", &path)
29+
.input("foo.rs")
30+
.arg("-Clinker-flavor=ld")
31+
.run();
32+
}

0 commit comments

Comments
 (0)