@@ -3,6 +3,75 @@ use std::{borrow::Cow, env};
33use crate :: spec:: { cvs, Cc , DebuginfoKind , FramePointer , LinkArgs } ;
44use crate :: spec:: { LinkerFlavor , Lld , SplitDebuginfo , StaticCow , TargetOptions } ;
55
6+ #[ cfg( test) ]
7+ #[ path = "apple/tests.rs" ]
8+ mod tests;
9+
10+ use Arch :: * ;
11+ #[ allow( non_camel_case_types) ]
12+ #[ derive( Copy , Clone ) ]
13+ pub enum Arch {
14+ Armv7 ,
15+ Armv7k ,
16+ Armv7s ,
17+ Arm64 ,
18+ Arm64_32 ,
19+ I386 ,
20+ X86_64 ,
21+ X86_64_sim ,
22+ X86_64_macabi ,
23+ Arm64_macabi ,
24+ Arm64_sim ,
25+ }
26+
27+ impl Arch {
28+ pub fn target_name ( self ) -> & ' static str {
29+ match self {
30+ Armv7 => "armv7" ,
31+ Armv7k => "armv7k" ,
32+ Armv7s => "armv7s" ,
33+ Arm64 | Arm64_macabi | Arm64_sim => "arm64" ,
34+ Arm64_32 => "arm64_32" ,
35+ I386 => "i386" ,
36+ X86_64 | X86_64_sim | X86_64_macabi => "x86_64" ,
37+ }
38+ }
39+
40+ fn target_abi ( self ) -> & ' static str {
41+ match self {
42+ Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 => "" ,
43+ X86_64_macabi | Arm64_macabi => "macabi" ,
44+ // x86_64-apple-ios is a simulator target, even though it isn't
45+ // declared that way in the target like the other ones...
46+ Arm64_sim | X86_64_sim => "sim" ,
47+ }
48+ }
49+
50+ fn target_cpu ( self ) -> & ' static str {
51+ match self {
52+ Armv7 => "cortex-a8" , // iOS7 is supported on iPhone 4 and higher
53+ Armv7k => "cortex-a8" ,
54+ Armv7s => "cortex-a9" ,
55+ Arm64 => "apple-a7" ,
56+ Arm64_32 => "apple-s4" ,
57+ I386 => "yonah" ,
58+ X86_64 | X86_64_sim => "core2" ,
59+ X86_64_macabi => "core2" ,
60+ Arm64_macabi => "apple-a12" ,
61+ Arm64_sim => "apple-a12" ,
62+ }
63+ }
64+
65+ fn link_env_remove ( self ) -> StaticCow < [ StaticCow < str > ] > {
66+ match self {
67+ Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 | X86_64_sim | Arm64_sim => {
68+ cvs ! [ "MACOSX_DEPLOYMENT_TARGET" ]
69+ }
70+ X86_64_macabi | Arm64_macabi => cvs ! [ "IPHONEOS_DEPLOYMENT_TARGET" ] ,
71+ }
72+ }
73+ }
74+
675fn pre_link_args ( os : & ' static str , arch : & ' static str , abi : & ' static str ) -> LinkArgs {
776 let platform_name: StaticCow < str > = match abi {
877 "sim" => format ! ( "{}-simulator" , os) . into ( ) ,
@@ -35,30 +104,35 @@ fn pre_link_args(os: &'static str, arch: &'static str, abi: &'static str) -> Lin
35104 args
36105}
37106
38- pub fn opts ( os : & ' static str , arch : & ' static str , abi : & ' static str ) -> TargetOptions {
39- // ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6
107+ pub fn opts ( os : & ' static str , arch : Arch ) -> TargetOptions {
108+ // Static TLS is only available in macOS 10.7+. If you try to compile for 10.6
40109 // either the linker will complain if it is used or the binary will end up
41110 // segfaulting at runtime when run on 10.6. Rust by default supports macOS
42111 // 10.7+, but there is a standard environment variable,
43112 // MACOSX_DEPLOYMENT_TARGET, which is used to signal targeting older
44113 // versions of macOS. For example compiling on 10.10 with
45114 // MACOSX_DEPLOYMENT_TARGET set to 10.6 will cause the linker to generate
46- // warnings about the usage of ELF TLS.
115+ // warnings about the usage of static TLS.
47116 //
48- // Here we detect what version is being requested, defaulting to 10.7. ELF
117+ // Here we detect what version is being requested, defaulting to 10.7. Static
49118 // TLS is flagged as enabled if it looks to be supported. The architecture
50119 // only matters for default deployment target which is 11.0 for ARM64 and
51120 // 10.7 for everything else.
52- let has_thread_local = macos_deployment_target ( "x86_64" ) >= ( 10 , 7 ) ;
121+ let has_thread_local = os == "macos" && macos_deployment_target ( "x86_64" ) >= ( 10 , 7 ) ;
122+
123+ let abi = arch. target_abi ( ) ;
53124
54125 TargetOptions {
126+ abi : abi. into ( ) ,
55127 os : os. into ( ) ,
128+ cpu : arch. target_cpu ( ) . into ( ) ,
129+ link_env_remove : arch. link_env_remove ( ) ,
56130 vendor : "apple" . into ( ) ,
57131 linker_flavor : LinkerFlavor :: Darwin ( Cc :: Yes , Lld :: No ) ,
58132 // macOS has -dead_strip, which doesn't rely on function_sections
59133 function_sections : false ,
60134 dynamic_linking : true ,
61- pre_link_args : pre_link_args ( os, arch, abi) ,
135+ pre_link_args : pre_link_args ( os, arch. target_name ( ) , abi) ,
62136 families : cvs ! [ "unix" ] ,
63137 is_like_osx : true ,
64138 default_dwarf_version : 2 ,
@@ -142,25 +216,25 @@ fn ios_deployment_target() -> (u32, u32) {
142216 deployment_target ( "IPHONEOS_DEPLOYMENT_TARGET" ) . unwrap_or ( ( 7 , 0 ) )
143217}
144218
145- pub fn ios_llvm_target ( arch : & str ) -> String {
219+ pub fn ios_llvm_target ( arch : Arch ) -> String {
146220 // Modern iOS tooling extracts information about deployment target
147221 // from LC_BUILD_VERSION. This load command will only be emitted when
148222 // we build with a version specific `llvm_target`, with the version
149223 // set high enough. Luckily one LC_BUILD_VERSION is enough, for Xcode
150224 // to pick it up (since std and core are still built with the fallback
151225 // of version 7.0 and hence emit the old LC_IPHONE_MIN_VERSION).
152226 let ( major, minor) = ios_deployment_target ( ) ;
153- format ! ( "{}-apple-ios{}.{}.0" , arch, major, minor)
227+ format ! ( "{}-apple-ios{}.{}.0" , arch. target_name ( ) , major, minor)
154228}
155229
156230fn ios_lld_platform_version ( ) -> String {
157231 let ( major, minor) = ios_deployment_target ( ) ;
158232 format ! ( "{}.{}" , major, minor)
159233}
160234
161- pub fn ios_sim_llvm_target ( arch : & str ) -> String {
235+ pub fn ios_sim_llvm_target ( arch : Arch ) -> String {
162236 let ( major, minor) = ios_deployment_target ( ) ;
163- format ! ( "{}-apple-ios{}.{}.0-simulator" , arch, major, minor)
237+ format ! ( "{}-apple-ios{}.{}.0-simulator" , arch. target_name ( ) , major, minor)
164238}
165239
166240fn tvos_deployment_target ( ) -> ( u32 , u32 ) {
@@ -181,7 +255,7 @@ fn watchos_lld_platform_version() -> String {
181255 format ! ( "{}.{}" , major, minor)
182256}
183257
184- pub fn watchos_sim_llvm_target ( arch : & str ) -> String {
258+ pub fn watchos_sim_llvm_target ( arch : Arch ) -> String {
185259 let ( major, minor) = watchos_deployment_target ( ) ;
186- format ! ( "{}-apple-watchos{}.{}.0-simulator" , arch, major, minor)
260+ format ! ( "{}-apple-watchos{}.{}.0-simulator" , arch. target_name ( ) , major, minor)
187261}
0 commit comments