Skip to content

Commit 7b0360e

Browse files
authored
Rollup merge of #98771 - Thog:rust-lld-apple-target, r=petrochenkov
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`` with [a simple test program](https://github.com/Thog/rust-lld-apple-target_test). It currently doesn't work with targets ``armv7-apple-ios`` and ``armv7s-apple-ios`` because of ``symbols.o`` not being generated with the correct CPU subtype. This will require changes in the ``object`` crate to expose an API. As ``ld64.lld`` requires ``-platform_version`` with the minimal version supported and an sdk version, I made ``rustc_target::apple_base`` public to get access to ``*os_deployment_target`` helper functions and also added ``tvos_deployment_target`` as it was missing.
2 parents d6b96b6 + 78bbe57 commit 7b0360e

File tree

6 files changed

+101
-15
lines changed

6 files changed

+101
-15
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -2675,7 +2675,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
26752675
let llvm_target = &sess.target.llvm_target;
26762676
if sess.target.vendor != "apple"
26772677
|| !matches!(os.as_ref(), "ios" | "tvos" | "watchos")
2678-
|| flavor != LinkerFlavor::Gcc
2678+
|| (flavor != LinkerFlavor::Gcc && flavor != LinkerFlavor::Lld(LldFlavor::Ld64))
26792679
{
26802680
return;
26812681
}
@@ -2706,13 +2706,16 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
27062706
return;
27072707
}
27082708
};
2709-
if llvm_target.contains("macabi") {
2710-
cmd.args(&["-target", llvm_target])
2711-
} else {
2712-
let arch_name = llvm_target.split('-').next().expect("LLVM target must have a hyphen");
2713-
cmd.args(&["-arch", arch_name])
2709+
2710+
match flavor {
2711+
LinkerFlavor::Gcc => {
2712+
cmd.args(&["-isysroot", &sdk_root, "-Wl,-syslibroot", &sdk_root]);
2713+
}
2714+
LinkerFlavor::Lld(LldFlavor::Ld64) => {
2715+
cmd.args(&["-syslibroot", &sdk_root]);
2716+
}
2717+
_ => unreachable!(),
27142718
}
2715-
cmd.args(&["-isysroot", &sdk_root, "-Wl,-syslibroot", &sdk_root]);
27162719
}
27172720

27182721
fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> {

compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
use super::apple_sdk_base::{opts, Arch};
2-
use crate::spec::{FramePointer, Target, TargetOptions};
2+
use crate::spec::{FramePointer, LinkerFlavor, Target, TargetOptions};
33

44
pub fn target() -> Target {
5+
let llvm_target = "arm64-apple-ios14.0-macabi";
6+
7+
let mut base = opts("ios", Arch::Arm64_macabi);
8+
base.add_pre_link_args(LinkerFlavor::Gcc, &["-target", llvm_target]);
9+
510
Target {
6-
llvm_target: "arm64-apple-ios14.0-macabi".into(),
11+
llvm_target: llvm_target.into(),
712
pointer_width: 64,
813
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(),
914
arch: "aarch64".into(),
@@ -21,7 +26,7 @@ pub fn target() -> Target {
2126
-disable-llvm-passes\0\
2227
-Os\0"
2328
.into(),
24-
..opts("ios", Arch::Arm64_macabi)
29+
..base
2530
},
2631
}
2732
}

compiler/rustc_target/src/spec/apple_base.rs

+19
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,34 @@ pub fn ios_llvm_target(arch: &str) -> String {
109109
format!("{}-apple-ios{}.{}.0", arch, major, minor)
110110
}
111111

112+
pub fn ios_lld_platform_version() -> String {
113+
let (major, minor) = ios_deployment_target();
114+
format!("{}.{}", major, minor)
115+
}
116+
112117
pub fn ios_sim_llvm_target(arch: &str) -> String {
113118
let (major, minor) = ios_deployment_target();
114119
format!("{}-apple-ios{}.{}.0-simulator", arch, major, minor)
115120
}
116121

122+
fn tvos_deployment_target() -> (u32, u32) {
123+
deployment_target("TVOS_DEPLOYMENT_TARGET").unwrap_or((7, 0))
124+
}
125+
126+
pub fn tvos_lld_platform_version() -> String {
127+
let (major, minor) = tvos_deployment_target();
128+
format!("{}.{}", major, minor)
129+
}
130+
117131
fn watchos_deployment_target() -> (u32, u32) {
118132
deployment_target("WATCHOS_DEPLOYMENT_TARGET").unwrap_or((5, 0))
119133
}
120134

135+
pub fn watchos_lld_platform_version() -> String {
136+
let (major, minor) = watchos_deployment_target();
137+
format!("{}.{}", major, minor)
138+
}
139+
121140
pub fn watchos_sim_llvm_target(arch: &str) -> String {
122141
let (major, minor) = watchos_deployment_target();
123142
format!("{}-apple-watchos{}.{}.0-simulator", arch, major, minor)

compiler/rustc_target/src/spec/apple_sdk_base.rs

+53-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{spec::cvs, spec::TargetOptions};
1+
use crate::spec::{cvs, LinkArgs, LinkerFlavor, LldFlavor, TargetOptions};
22
use std::borrow::Cow;
33

44
use Arch::*;
@@ -17,6 +17,18 @@ pub enum Arch {
1717
Arm64_sim,
1818
}
1919

20+
fn target_arch_name(arch: Arch) -> &'static str {
21+
match arch {
22+
Armv7 => "armv7",
23+
Armv7k => "armv7k",
24+
Armv7s => "armv7s",
25+
Arm64 | Arm64_macabi | Arm64_sim => "arm64",
26+
Arm64_32 => "arm64_32",
27+
I386 => "i386",
28+
X86_64 | X86_64_macabi => "x86_64",
29+
}
30+
}
31+
2032
fn target_abi(arch: Arch) -> &'static str {
2133
match arch {
2234
Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 => "",
@@ -49,11 +61,51 @@ fn link_env_remove(arch: Arch) -> Cow<'static, [Cow<'static, str>]> {
4961
}
5062
}
5163

64+
fn pre_link_args(os: &'static str, arch: Arch) -> LinkArgs {
65+
let mut args = LinkArgs::new();
66+
67+
let target_abi = target_abi(arch);
68+
69+
let platform_name = match target_abi {
70+
"sim" => format!("{}-simulator", os),
71+
"macabi" => "mac-catalyst".to_string(),
72+
_ => os.to_string(),
73+
};
74+
75+
let platform_version = match os.as_ref() {
76+
"ios" => super::apple_base::ios_lld_platform_version(),
77+
"tvos" => super::apple_base::tvos_lld_platform_version(),
78+
"watchos" => super::apple_base::watchos_lld_platform_version(),
79+
_ => unreachable!(),
80+
};
81+
82+
let arch_str = target_arch_name(arch);
83+
84+
if target_abi != "macabi" {
85+
args.insert(LinkerFlavor::Gcc, vec!["-arch".into(), arch_str.into()]);
86+
}
87+
88+
args.insert(
89+
LinkerFlavor::Lld(LldFlavor::Ld64),
90+
vec![
91+
"-arch".into(),
92+
arch_str.into(),
93+
"-platform_version".into(),
94+
platform_name.into(),
95+
platform_version.clone().into(),
96+
platform_version.into(),
97+
],
98+
);
99+
100+
args
101+
}
102+
52103
pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
53104
TargetOptions {
54105
abi: target_abi(arch).into(),
55106
cpu: target_cpu(arch).into(),
56107
dynamic_linking: false,
108+
pre_link_args: pre_link_args(os, arch),
57109
link_env_remove: link_env_remove(arch),
58110
has_thread_local: false,
59111
..super::apple_base::opts(os)

compiler/rustc_target/src/spec/tests/tests_impl.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ impl Target {
4646
)
4747
}
4848
(LinkerFlavor::Gcc, LldFlavor::Ld64) => {
49-
assert_matches!(flavor, LinkerFlavor::Gcc)
49+
assert_matches!(
50+
flavor,
51+
LinkerFlavor::Lld(LldFlavor::Ld64) | LinkerFlavor::Gcc
52+
)
5053
}
5154
(LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link), LldFlavor::Link) => {
5255
assert_matches!(

compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
use super::apple_sdk_base::{opts, Arch};
2-
use crate::spec::{StackProbeType, Target, TargetOptions};
2+
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
33

44
pub fn target() -> Target {
5-
let base = opts("ios", Arch::X86_64_macabi);
5+
let llvm_target = "x86_64-apple-ios13.0-macabi";
6+
7+
let mut base = opts("ios", Arch::X86_64_macabi);
8+
base.add_pre_link_args(LinkerFlavor::Gcc, &["-target", llvm_target]);
9+
610
Target {
7-
llvm_target: "x86_64-apple-ios13.0-macabi".into(),
11+
llvm_target: llvm_target.into(),
812
pointer_width: 64,
913
data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
1014
.into(),

0 commit comments

Comments
 (0)