]>
Commit | Line | Data |
---|---|---|
9cc50fc6 SL |
1 | use std::env; |
2 | ||
9fa01778 | 3 | use crate::spec::{LinkArgs, TargetOptions}; |
1a4d82fc JJ |
4 | |
5 | pub fn opts() -> TargetOptions { | |
cc61c64b | 6 | // ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6 |
9cc50fc6 | 7 | // either the linker will complain if it is used or the binary will end up |
cc61c64b | 8 | // segfaulting at runtime when run on 10.6. Rust by default supports macOS |
9cc50fc6 SL |
9 | // 10.7+, but there is a standard environment variable, |
10 | // MACOSX_DEPLOYMENT_TARGET, which is used to signal targeting older | |
cc61c64b | 11 | // versions of macOS. For example compiling on 10.10 with |
9cc50fc6 SL |
12 | // MACOSX_DEPLOYMENT_TARGET set to 10.6 will cause the linker to generate |
13 | // warnings about the usage of ELF TLS. | |
14 | // | |
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. | |
48663c56 | 17 | let version = macos_deployment_target(); |
9cc50fc6 | 18 | |
1a4d82fc | 19 | TargetOptions { |
cc61c64b | 20 | // macOS has -dead_strip, which doesn't rely on function_sections |
1a4d82fc | 21 | function_sections: false, |
1a4d82fc JJ |
22 | dynamic_linking: true, |
23 | executables: true, | |
32a655c1 | 24 | target_family: Some("unix".to_string()), |
1a4d82fc | 25 | is_like_osx: true, |
1a4d82fc JJ |
26 | has_rpath: true, |
27 | dll_prefix: "lib".to_string(), | |
28 | dll_suffix: ".dylib".to_string(), | |
74b04a01 | 29 | archive_format: "darwin".to_string(), |
cc61c64b | 30 | pre_link_args: LinkArgs::new(), |
9cc50fc6 | 31 | has_elf_tls: version >= (10, 7), |
0531ce1d | 32 | abi_return_struct_as_int: true, |
83c7162d | 33 | emit_debug_gdb_scripts: false, |
dfeec247 | 34 | ..Default::default() |
1a4d82fc JJ |
35 | } |
36 | } | |
48663c56 XL |
37 | |
38 | fn macos_deployment_target() -> (u32, u32) { | |
39 | let deployment_target = env::var("MACOSX_DEPLOYMENT_TARGET").ok(); | |
dfeec247 XL |
40 | let version = deployment_target |
41 | .as_ref() | |
42 | .and_then(|s| { | |
43 | let mut i = s.splitn(2, '.'); | |
44 | i.next().and_then(|a| i.next().map(|b| (a, b))) | |
45 | }) | |
46 | .and_then(|(a, b)| a.parse::<u32>().and_then(|a| b.parse::<u32>().map(|b| (a, b))).ok()); | |
48663c56 XL |
47 | |
48 | version.unwrap_or((10, 7)) | |
49 | } | |
50 | ||
51 | pub fn macos_llvm_target(arch: &str) -> String { | |
52 | let (major, minor) = macos_deployment_target(); | |
53 | format!("{}-apple-macosx{}.{}.0", arch, major, minor) | |
54 | } | |
e1599b0c XL |
55 | |
56 | pub fn macos_link_env_remove() -> Vec<String> { | |
57 | let mut env_remove = Vec::with_capacity(2); | |
58 | // Remove the `SDKROOT` environment variable if it's clearly set for the wrong platform, which | |
59 | // may occur when we're linking a custom build script while targeting iOS for example. | |
ba9703b0 | 60 | if let Ok(sdkroot) = env::var("SDKROOT") { |
e1599b0c XL |
61 | if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("iPhoneSimulator.platform") { |
62 | env_remove.push("SDKROOT".to_string()) | |
63 | } | |
64 | } | |
65 | // Additionally, `IPHONEOS_DEPLOYMENT_TARGET` must not be set when using the Xcode linker at | |
66 | // "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld", | |
67 | // although this is apparently ignored when using the linker at "/usr/bin/ld". | |
68 | env_remove.push("IPHONEOS_DEPLOYMENT_TARGET".to_string()); | |
69 | env_remove | |
70 | } |