3 use crate::spec
::{FramePointer, SplitDebuginfo, TargetOptions}
;
5 pub fn opts(os
: &str) -> TargetOptions
{
6 // ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6
7 // either the linker will complain if it is used or the binary will end up
8 // segfaulting at runtime when run on 10.6. Rust by default supports macOS
9 // 10.7+, but there is a standard environment variable,
10 // MACOSX_DEPLOYMENT_TARGET, which is used to signal targeting older
11 // versions of macOS. For example compiling on 10.10 with
12 // MACOSX_DEPLOYMENT_TARGET set to 10.6 will cause the linker to generate
13 // warnings about the usage of ELF TLS.
15 // Here we detect what version is being requested, defaulting to 10.7. ELF
16 // TLS is flagged as enabled if it looks to be supported.
17 let version
= macos_deployment_target();
21 vendor
: "apple".to_string(),
22 // macOS has -dead_strip, which doesn't rely on function_sections
23 function_sections
: false,
24 dynamic_linking
: true,
27 families
: vec
!["unix".to_string()],
29 dwarf_version
: Some(2),
30 frame_pointer
: FramePointer
::Always
,
32 dll_suffix
: ".dylib".to_string(),
33 archive_format
: "darwin".to_string(),
34 has_elf_tls
: version
>= (10, 7),
35 abi_return_struct_as_int
: true,
36 emit_debug_gdb_scripts
: false,
37 eh_frame_header
: false,
39 // The historical default for macOS targets is to run `dsymutil` which
40 // generates a packed version of debuginfo split from the main file.
41 split_debuginfo
: SplitDebuginfo
::Packed
,
43 // This environment variable is pretty magical but is intended for
44 // producing deterministic builds. This was first discovered to be used
45 // by the `ar` tool as a way to control whether or not mtime entries in
46 // the archive headers were set to zero or not. It appears that
47 // eventually the linker got updated to do the same thing and now reads
48 // this environment variable too in recent versions.
50 // For some more info see the commentary on #47086
51 link_env
: vec
![("ZERO_AR_DATE".to_string(), "1".to_string())],
57 fn deployment_target(var_name
: &str) -> Option
<(u32, u32)> {
58 let deployment_target
= env
::var(var_name
).ok();
61 .and_then(|s
| s
.split_once('
.'
))
62 .and_then(|(a
, b
)| a
.parse
::<u32>().and_then(|a
| b
.parse
::<u32>().map(|b
| (a
, b
))).ok())
65 fn macos_deployment_target() -> (u32, u32) {
66 deployment_target("MACOSX_DEPLOYMENT_TARGET").unwrap_or((10, 7))
69 pub fn macos_llvm_target(arch
: &str) -> String
{
70 let (major
, minor
) = macos_deployment_target();
71 format
!("{}-apple-macosx{}.{}.0", arch
, major
, minor
)
74 pub fn macos_link_env_remove() -> Vec
<String
> {
75 let mut env_remove
= Vec
::with_capacity(2);
76 // Remove the `SDKROOT` environment variable if it's clearly set for the wrong platform, which
77 // may occur when we're linking a custom build script while targeting iOS for example.
78 if let Ok(sdkroot
) = env
::var("SDKROOT") {
79 if sdkroot
.contains("iPhoneOS.platform") || sdkroot
.contains("iPhoneSimulator.platform") {
80 env_remove
.push("SDKROOT".to_string())
83 // Additionally, `IPHONEOS_DEPLOYMENT_TARGET` must not be set when using the Xcode linker at
84 // "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld",
85 // although this is apparently ignored when using the linker at "/usr/bin/ld".
86 env_remove
.push("IPHONEOS_DEPLOYMENT_TARGET".to_string());
90 fn ios_deployment_target() -> (u32, u32) {
91 deployment_target("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or((7, 0))
94 pub fn ios_sim_llvm_target(arch
: &str) -> String
{
95 let (major
, minor
) = ios_deployment_target();
96 format
!("{}-apple-ios{}.{}.0-simulator", arch
, major
, minor
)