about summary refs log tree commit diff
path: root/compiler/rustc_target/src/spec/base
diff options
context:
space:
mode:
authorMads Marquart <mads@marquart.dk>2024-08-21 17:23:50 +0200
committerMads Marquart <mads@marquart.dk>2024-09-09 13:57:17 +0200
commitdd35398545006f5ad4da8fc2ef0190c55ffda29c (patch)
tree4aedb8fcc2d053cc00cb9646a157ad94af3a063e /compiler/rustc_target/src/spec/base
parent1f44f0a66fa0892ca680a26e271d22993d53de5c (diff)
downloadrust-dd35398545006f5ad4da8fc2ef0190c55ffda29c.tar.gz
rust-dd35398545006f5ad4da8fc2ef0190c55ffda29c.zip
Pass deployment target when linking with cc on Apple targets
When linking macOS targets with cc, pass the `-mmacosx-version-min=.`
option to specify the desired deployment target. Also, no longer pass
`-m32`/`-m64`, these are redundant since we already pass `-arch`.

When linking with cc on other Apple targets, always pass `-target`.
(We assume for these targets that cc => clang).
Diffstat (limited to 'compiler/rustc_target/src/spec/base')
-rw-r--r--compiler/rustc_target/src/spec/base/apple/mod.rs30
1 files changed, 29 insertions, 1 deletions
diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs
index b1fe49f76ca..d2886a89b53 100644
--- a/compiler/rustc_target/src/spec/base/apple/mod.rs
+++ b/compiler/rustc_target/src/spec/base/apple/mod.rs
@@ -168,7 +168,26 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: TargetAbi) -> LinkArgs {
         ["-platform_version".into(), platform_name, min_version, sdk_version].into_iter(),
     );
 
-    if abi != TargetAbi::MacCatalyst {
+    // We need to communicate four things to the C compiler to be able to link:
+    // - The architecture.
+    // - The operating system (and that it's an Apple platform).
+    // - The deployment target.
+    // - The environment / ABI.
+    //
+    // We'd like to use `-target` everywhere, since that can uniquely
+    // communicate all of these, but that doesn't work on GCC, and since we
+    // don't know whether the `cc` compiler is Clang, GCC, or something else,
+    // we fall back to other options that also work on GCC when compiling for
+    // macOS.
+    //
+    // Targets other than macOS are ill-supported by GCC (it doesn't even
+    // support e.g. `-miphoneos-version-min`), so in those cases we can fairly
+    // safely use `-target`. See also the following, where it is made explicit
+    // that the recommendation by LLVM developers is to use `-target`:
+    // <https://github.com/llvm/llvm-project/issues/88271>
+    if os == "macos" {
+        // `-arch` communicates the architecture.
+        //
         // CC forwards the `-arch` to the linker, so we use the same value
         // here intentionally.
         add_link_args(
@@ -176,6 +195,15 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: TargetAbi) -> LinkArgs {
             LinkerFlavor::Darwin(Cc::Yes, Lld::No),
             &["-arch", arch.ld_arch()],
         );
+        // The presence of `-mmacosx-version-min` makes CC default to macOS,
+        // and it sets the deployment target.
+        let (major, minor, patch) = deployment_target(os, arch, abi);
+        let opt = format!("-mmacosx-version-min={major}.{minor}.{patch}").into();
+        add_link_args_iter(&mut args, LinkerFlavor::Darwin(Cc::Yes, Lld::No), [opt].into_iter());
+        // macOS has no environment, so with these two, we've told CC all the
+        // desired parameters.
+        //
+        // We avoid `-m32`/`-m64`, as this is already encoded by `-arch`.
     } else {
         add_link_args_iter(
             &mut args,