about summary refs log tree commit diff
diff options
context:
space:
mode:
authormary <mary@mary.zone>2022-07-01 15:12:46 +0000
committermary <mary@mary.zone>2022-08-03 15:41:05 +0000
commit78bbe57c88469abbbcd1c46c8e8f3cf014b5a154 (patch)
treef525c4e4e8b0253378db8f6c41e9a13db403244d
parent9538d2d0f1c708affa36ef8917729efec2e5e0ed (diff)
downloadrust-78bbe57c88469abbbcd1c46c8e8f3cf014b5a154.tar.gz
rust-78bbe57c88469abbbcd1c46c8e8f3cf014b5a154.zip
Add support for link-flavor rust-lld for iOS, tvOS and watchOS
This adds support for rust-lld for Apple *OS targets.

This was tested against targets "aarch64-apple-ios" and "aarch64-apple-ios-sim".

For targets "armv7-apple-ios" and "armv7s-apple-ios", it doesn't link because of
"symbols.o" not being generated with the correct CPU subtype (changes in
the "object" crate needs to be done to support it).
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs17
-rw-r--r--compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs11
-rw-r--r--compiler/rustc_target/src/spec/apple_base.rs19
-rw-r--r--compiler/rustc_target/src/spec/apple_sdk_base.rs54
-rw-r--r--compiler/rustc_target/src/spec/tests/tests_impl.rs5
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs10
6 files changed, 101 insertions, 15 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 13a7b6be947..8197872bf30 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -2675,7 +2675,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
     let llvm_target = &sess.target.llvm_target;
     if sess.target.vendor != "apple"
         || !matches!(os.as_ref(), "ios" | "tvos" | "watchos")
-        || flavor != LinkerFlavor::Gcc
+        || (flavor != LinkerFlavor::Gcc && flavor != LinkerFlavor::Lld(LldFlavor::Ld64))
     {
         return;
     }
@@ -2706,13 +2706,16 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
             return;
         }
     };
-    if llvm_target.contains("macabi") {
-        cmd.args(&["-target", llvm_target])
-    } else {
-        let arch_name = llvm_target.split('-').next().expect("LLVM target must have a hyphen");
-        cmd.args(&["-arch", arch_name])
+
+    match flavor {
+        LinkerFlavor::Gcc => {
+            cmd.args(&["-isysroot", &sdk_root, "-Wl,-syslibroot", &sdk_root]);
+        }
+        LinkerFlavor::Lld(LldFlavor::Ld64) => {
+            cmd.args(&["-syslibroot", &sdk_root]);
+        }
+        _ => unreachable!(),
     }
-    cmd.args(&["-isysroot", &sdk_root, "-Wl,-syslibroot", &sdk_root]);
 }
 
 fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> {
diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs
index 57634cbbfb1..1dad07a9a42 100644
--- a/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs
+++ b/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs
@@ -1,9 +1,14 @@
 use super::apple_sdk_base::{opts, Arch};
-use crate::spec::{FramePointer, Target, TargetOptions};
+use crate::spec::{FramePointer, LinkerFlavor, Target, TargetOptions};
 
 pub fn target() -> Target {
+    let llvm_target = "arm64-apple-ios14.0-macabi";
+
+    let mut base = opts("ios", Arch::Arm64_macabi);
+    base.add_pre_link_args(LinkerFlavor::Gcc, &["-target", llvm_target]);
+
     Target {
-        llvm_target: "arm64-apple-ios14.0-macabi".into(),
+        llvm_target: llvm_target.into(),
         pointer_width: 64,
         data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(),
         arch: "aarch64".into(),
@@ -21,7 +26,7 @@ pub fn target() -> Target {
                 -disable-llvm-passes\0\
                 -Os\0"
                 .into(),
-            ..opts("ios", Arch::Arm64_macabi)
+            ..base
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs
index 9bfae46ef32..15e4fb9be63 100644
--- a/compiler/rustc_target/src/spec/apple_base.rs
+++ b/compiler/rustc_target/src/spec/apple_base.rs
@@ -109,15 +109,34 @@ pub fn ios_llvm_target(arch: &str) -> String {
     format!("{}-apple-ios{}.{}.0", arch, major, minor)
 }
 
+pub fn ios_lld_platform_version() -> String {
+    let (major, minor) = ios_deployment_target();
+    format!("{}.{}", major, minor)
+}
+
 pub fn ios_sim_llvm_target(arch: &str) -> String {
     let (major, minor) = ios_deployment_target();
     format!("{}-apple-ios{}.{}.0-simulator", arch, major, minor)
 }
 
+fn tvos_deployment_target() -> (u32, u32) {
+    deployment_target("TVOS_DEPLOYMENT_TARGET").unwrap_or((7, 0))
+}
+
+pub fn tvos_lld_platform_version() -> String {
+    let (major, minor) = tvos_deployment_target();
+    format!("{}.{}", major, minor)
+}
+
 fn watchos_deployment_target() -> (u32, u32) {
     deployment_target("WATCHOS_DEPLOYMENT_TARGET").unwrap_or((5, 0))
 }
 
+pub fn watchos_lld_platform_version() -> String {
+    let (major, minor) = watchos_deployment_target();
+    format!("{}.{}", major, minor)
+}
+
 pub fn watchos_sim_llvm_target(arch: &str) -> String {
     let (major, minor) = watchos_deployment_target();
     format!("{}-apple-watchos{}.{}.0-simulator", arch, major, minor)
diff --git a/compiler/rustc_target/src/spec/apple_sdk_base.rs b/compiler/rustc_target/src/spec/apple_sdk_base.rs
index 0328ea98c48..d77558f0f84 100644
--- a/compiler/rustc_target/src/spec/apple_sdk_base.rs
+++ b/compiler/rustc_target/src/spec/apple_sdk_base.rs
@@ -1,4 +1,4 @@
-use crate::{spec::cvs, spec::TargetOptions};
+use crate::spec::{cvs, LinkArgs, LinkerFlavor, LldFlavor, TargetOptions};
 use std::borrow::Cow;
 
 use Arch::*;
@@ -17,6 +17,18 @@ pub enum Arch {
     Arm64_sim,
 }
 
+fn target_arch_name(arch: Arch) -> &'static str {
+    match arch {
+        Armv7 => "armv7",
+        Armv7k => "armv7k",
+        Armv7s => "armv7s",
+        Arm64 | Arm64_macabi | Arm64_sim => "arm64",
+        Arm64_32 => "arm64_32",
+        I386 => "i386",
+        X86_64 | X86_64_macabi => "x86_64",
+    }
+}
+
 fn target_abi(arch: Arch) -> &'static str {
     match arch {
         Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 => "",
@@ -49,11 +61,51 @@ fn link_env_remove(arch: Arch) -> Cow<'static, [Cow<'static, str>]> {
     }
 }
 
+fn pre_link_args(os: &'static str, arch: Arch) -> LinkArgs {
+    let mut args = LinkArgs::new();
+
+    let target_abi = target_abi(arch);
+
+    let platform_name = match target_abi {
+        "sim" => format!("{}-simulator", os),
+        "macabi" => "mac-catalyst".to_string(),
+        _ => os.to_string(),
+    };
+
+    let platform_version = match os.as_ref() {
+        "ios" => super::apple_base::ios_lld_platform_version(),
+        "tvos" => super::apple_base::tvos_lld_platform_version(),
+        "watchos" => super::apple_base::watchos_lld_platform_version(),
+        _ => unreachable!(),
+    };
+
+    let arch_str = target_arch_name(arch);
+
+    if target_abi != "macabi" {
+        args.insert(LinkerFlavor::Gcc, vec!["-arch".into(), arch_str.into()]);
+    }
+
+    args.insert(
+        LinkerFlavor::Lld(LldFlavor::Ld64),
+        vec![
+            "-arch".into(),
+            arch_str.into(),
+            "-platform_version".into(),
+            platform_name.into(),
+            platform_version.clone().into(),
+            platform_version.into(),
+        ],
+    );
+
+    args
+}
+
 pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
     TargetOptions {
         abi: target_abi(arch).into(),
         cpu: target_cpu(arch).into(),
         dynamic_linking: false,
+        pre_link_args: pre_link_args(os, arch),
         link_env_remove: link_env_remove(arch),
         has_thread_local: false,
         ..super::apple_base::opts(os)
diff --git a/compiler/rustc_target/src/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs
index c7c5a231901..1db6db78b17 100644
--- a/compiler/rustc_target/src/spec/tests/tests_impl.rs
+++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs
@@ -46,7 +46,10 @@ impl Target {
                         )
                     }
                     (LinkerFlavor::Gcc, LldFlavor::Ld64) => {
-                        assert_matches!(flavor, LinkerFlavor::Gcc)
+                        assert_matches!(
+                            flavor,
+                            LinkerFlavor::Lld(LldFlavor::Ld64) | LinkerFlavor::Gcc
+                        )
                     }
                     (LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link), LldFlavor::Link) => {
                         assert_matches!(
diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs
index c75632571ad..2122bcd37fc 100644
--- a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs
@@ -1,10 +1,14 @@
 use super::apple_sdk_base::{opts, Arch};
-use crate::spec::{StackProbeType, Target, TargetOptions};
+use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
 
 pub fn target() -> Target {
-    let base = opts("ios", Arch::X86_64_macabi);
+    let llvm_target = "x86_64-apple-ios13.0-macabi";
+
+    let mut base = opts("ios", Arch::X86_64_macabi);
+    base.add_pre_link_args(LinkerFlavor::Gcc, &["-target", llvm_target]);
+
     Target {
-        llvm_target: "x86_64-apple-ios13.0-macabi".into(),
+        llvm_target: llvm_target.into(),
         pointer_width: 64,
         data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
             .into(),