]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_target/src/spec/apple_base.rs
Auto merge of #96324 - berendjan:set_tcp_quickack, r=dtolnay
[rust.git] / compiler / rustc_target / src / spec / apple_base.rs
1 use std::{borrow::Cow, env};
2
3 use crate::spec::{cvs, DebuginfoKind, FramePointer, SplitDebuginfo, TargetOptions};
4 use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor};
5
6 fn pre_link_args(os: &'static str, arch: &'static str, abi: &'static str) -> LinkArgs {
7     let mut args = LinkArgs::new();
8
9     let platform_name = match abi {
10         "sim" => format!("{}-simulator", os),
11         "macabi" => "mac-catalyst".to_string(),
12         _ => os.to_string(),
13     };
14
15     let platform_version = match os.as_ref() {
16         "ios" => ios_lld_platform_version(),
17         "tvos" => tvos_lld_platform_version(),
18         "watchos" => watchos_lld_platform_version(),
19         "macos" => macos_lld_platform_version(arch),
20         _ => unreachable!(),
21     };
22
23     if abi != "macabi" {
24         args.insert(LinkerFlavor::Gcc, vec!["-arch".into(), arch.into()]);
25     }
26
27     args.insert(
28         LinkerFlavor::Lld(LldFlavor::Ld64),
29         vec![
30             "-arch".into(),
31             arch.into(),
32             "-platform_version".into(),
33             platform_name.into(),
34             platform_version.clone().into(),
35             platform_version.into(),
36         ],
37     );
38
39     args
40 }
41
42 pub fn opts(os: &'static str, arch: &'static str, abi: &'static str) -> TargetOptions {
43     // ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6
44     // either the linker will complain if it is used or the binary will end up
45     // segfaulting at runtime when run on 10.6. Rust by default supports macOS
46     // 10.7+, but there is a standard environment variable,
47     // MACOSX_DEPLOYMENT_TARGET, which is used to signal targeting older
48     // versions of macOS. For example compiling on 10.10 with
49     // MACOSX_DEPLOYMENT_TARGET set to 10.6 will cause the linker to generate
50     // warnings about the usage of ELF TLS.
51     //
52     // Here we detect what version is being requested, defaulting to 10.7. ELF
53     // TLS is flagged as enabled if it looks to be supported. The architecture
54     // only matters for default deployment target which is 11.0 for ARM64 and
55     // 10.7 for everything else.
56     let has_thread_local = macos_deployment_target("x86_64") >= (10, 7);
57
58     TargetOptions {
59         os: os.into(),
60         vendor: "apple".into(),
61         // macOS has -dead_strip, which doesn't rely on function_sections
62         function_sections: false,
63         dynamic_linking: true,
64         pre_link_args: pre_link_args(os, arch, abi),
65         linker_is_gnu: false,
66         families: cvs!["unix"],
67         is_like_osx: true,
68         default_dwarf_version: 2,
69         frame_pointer: FramePointer::Always,
70         has_rpath: true,
71         dll_suffix: ".dylib".into(),
72         archive_format: "darwin".into(),
73         has_thread_local,
74         abi_return_struct_as_int: true,
75         emit_debug_gdb_scripts: false,
76         eh_frame_header: false,
77         lld_flavor: LldFlavor::Ld64,
78
79         debuginfo_kind: DebuginfoKind::DwarfDsym,
80         // The historical default for macOS targets is to run `dsymutil` which
81         // generates a packed version of debuginfo split from the main file.
82         split_debuginfo: SplitDebuginfo::Packed,
83         supported_split_debuginfo: Cow::Borrowed(&[
84             SplitDebuginfo::Packed,
85             SplitDebuginfo::Unpacked,
86             SplitDebuginfo::Off,
87         ]),
88
89         // This environment variable is pretty magical but is intended for
90         // producing deterministic builds. This was first discovered to be used
91         // by the `ar` tool as a way to control whether or not mtime entries in
92         // the archive headers were set to zero or not. It appears that
93         // eventually the linker got updated to do the same thing and now reads
94         // this environment variable too in recent versions.
95         //
96         // For some more info see the commentary on #47086
97         link_env: Cow::Borrowed(&[(Cow::Borrowed("ZERO_AR_DATE"), Cow::Borrowed("1"))]),
98
99         ..Default::default()
100     }
101 }
102
103 fn deployment_target(var_name: &str) -> Option<(u32, u32)> {
104     let deployment_target = env::var(var_name).ok();
105     deployment_target
106         .as_ref()
107         .and_then(|s| s.split_once('.'))
108         .and_then(|(a, b)| a.parse::<u32>().and_then(|a| b.parse::<u32>().map(|b| (a, b))).ok())
109 }
110
111 fn macos_default_deployment_target(arch: &str) -> (u32, u32) {
112     if arch == "arm64" { (11, 0) } else { (10, 7) }
113 }
114
115 fn macos_deployment_target(arch: &str) -> (u32, u32) {
116     deployment_target("MACOSX_DEPLOYMENT_TARGET")
117         .unwrap_or_else(|| macos_default_deployment_target(arch))
118 }
119
120 fn macos_lld_platform_version(arch: &str) -> String {
121     let (major, minor) = macos_deployment_target(arch);
122     format!("{}.{}", major, minor)
123 }
124
125 pub fn macos_llvm_target(arch: &str) -> String {
126     let (major, minor) = macos_deployment_target(arch);
127     format!("{}-apple-macosx{}.{}.0", arch, major, minor)
128 }
129
130 pub fn macos_link_env_remove() -> Vec<Cow<'static, str>> {
131     let mut env_remove = Vec::with_capacity(2);
132     // Remove the `SDKROOT` environment variable if it's clearly set for the wrong platform, which
133     // may occur when we're linking a custom build script while targeting iOS for example.
134     if let Ok(sdkroot) = env::var("SDKROOT") {
135         if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("iPhoneSimulator.platform") {
136             env_remove.push("SDKROOT".into())
137         }
138     }
139     // Additionally, `IPHONEOS_DEPLOYMENT_TARGET` must not be set when using the Xcode linker at
140     // "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld",
141     // although this is apparently ignored when using the linker at "/usr/bin/ld".
142     env_remove.push("IPHONEOS_DEPLOYMENT_TARGET".into());
143     env_remove
144 }
145
146 fn ios_deployment_target() -> (u32, u32) {
147     deployment_target("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or((7, 0))
148 }
149
150 pub fn ios_llvm_target(arch: &str) -> String {
151     // Modern iOS tooling extracts information about deployment target
152     // from LC_BUILD_VERSION. This load command will only be emitted when
153     // we build with a version specific `llvm_target`, with the version
154     // set high enough. Luckily one LC_BUILD_VERSION is enough, for Xcode
155     // to pick it up (since std and core are still built with the fallback
156     // of version 7.0 and hence emit the old LC_IPHONE_MIN_VERSION).
157     let (major, minor) = ios_deployment_target();
158     format!("{}-apple-ios{}.{}.0", arch, major, minor)
159 }
160
161 fn ios_lld_platform_version() -> String {
162     let (major, minor) = ios_deployment_target();
163     format!("{}.{}", major, minor)
164 }
165
166 pub fn ios_sim_llvm_target(arch: &str) -> String {
167     let (major, minor) = ios_deployment_target();
168     format!("{}-apple-ios{}.{}.0-simulator", arch, major, minor)
169 }
170
171 fn tvos_deployment_target() -> (u32, u32) {
172     deployment_target("TVOS_DEPLOYMENT_TARGET").unwrap_or((7, 0))
173 }
174
175 fn tvos_lld_platform_version() -> String {
176     let (major, minor) = tvos_deployment_target();
177     format!("{}.{}", major, minor)
178 }
179
180 fn watchos_deployment_target() -> (u32, u32) {
181     deployment_target("WATCHOS_DEPLOYMENT_TARGET").unwrap_or((5, 0))
182 }
183
184 fn watchos_lld_platform_version() -> String {
185     let (major, minor) = watchos_deployment_target();
186     format!("{}.{}", major, minor)
187 }
188
189 pub fn watchos_sim_llvm_target(arch: &str) -> String {
190     let (major, minor) = watchos_deployment_target();
191     format!("{}-apple-watchos{}.{}.0-simulator", arch, major, minor)
192 }