@@ -3,6 +3,75 @@ use std::{borrow::Cow, env};
3
3
use crate :: spec:: { cvs, Cc , DebuginfoKind , FramePointer , LinkArgs } ;
4
4
use crate :: spec:: { LinkerFlavor , Lld , SplitDebuginfo , StaticCow , TargetOptions } ;
5
5
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
+
6
75
fn pre_link_args ( os : & ' static str , arch : & ' static str , abi : & ' static str ) -> LinkArgs {
7
76
let platform_name: StaticCow < str > = match abi {
8
77
"sim" => format ! ( "{}-simulator" , os) . into ( ) ,
@@ -35,30 +104,35 @@ fn pre_link_args(os: &'static str, arch: &'static str, abi: &'static str) -> Lin
35
104
args
36
105
}
37
106
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
40
109
// either the linker will complain if it is used or the binary will end up
41
110
// segfaulting at runtime when run on 10.6. Rust by default supports macOS
42
111
// 10.7+, but there is a standard environment variable,
43
112
// MACOSX_DEPLOYMENT_TARGET, which is used to signal targeting older
44
113
// versions of macOS. For example compiling on 10.10 with
45
114
// 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.
47
116
//
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
49
118
// TLS is flagged as enabled if it looks to be supported. The architecture
50
119
// only matters for default deployment target which is 11.0 for ARM64 and
51
120
// 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 ( ) ;
53
124
54
125
TargetOptions {
126
+ abi : abi. into ( ) ,
55
127
os : os. into ( ) ,
128
+ cpu : arch. target_cpu ( ) . into ( ) ,
129
+ link_env_remove : arch. link_env_remove ( ) ,
56
130
vendor : "apple" . into ( ) ,
57
131
linker_flavor : LinkerFlavor :: Darwin ( Cc :: Yes , Lld :: No ) ,
58
132
// macOS has -dead_strip, which doesn't rely on function_sections
59
133
function_sections : false ,
60
134
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) ,
62
136
families : cvs ! [ "unix" ] ,
63
137
is_like_osx : true ,
64
138
default_dwarf_version : 2 ,
@@ -142,25 +216,25 @@ fn ios_deployment_target() -> (u32, u32) {
142
216
deployment_target ( "IPHONEOS_DEPLOYMENT_TARGET" ) . unwrap_or ( ( 7 , 0 ) )
143
217
}
144
218
145
- pub fn ios_llvm_target ( arch : & str ) -> String {
219
+ pub fn ios_llvm_target ( arch : Arch ) -> String {
146
220
// Modern iOS tooling extracts information about deployment target
147
221
// from LC_BUILD_VERSION. This load command will only be emitted when
148
222
// we build with a version specific `llvm_target`, with the version
149
223
// set high enough. Luckily one LC_BUILD_VERSION is enough, for Xcode
150
224
// to pick it up (since std and core are still built with the fallback
151
225
// of version 7.0 and hence emit the old LC_IPHONE_MIN_VERSION).
152
226
let ( major, minor) = ios_deployment_target ( ) ;
153
- format ! ( "{}-apple-ios{}.{}.0" , arch, major, minor)
227
+ format ! ( "{}-apple-ios{}.{}.0" , arch. target_name ( ) , major, minor)
154
228
}
155
229
156
230
fn ios_lld_platform_version ( ) -> String {
157
231
let ( major, minor) = ios_deployment_target ( ) ;
158
232
format ! ( "{}.{}" , major, minor)
159
233
}
160
234
161
- pub fn ios_sim_llvm_target ( arch : & str ) -> String {
235
+ pub fn ios_sim_llvm_target ( arch : Arch ) -> String {
162
236
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)
164
238
}
165
239
166
240
fn tvos_deployment_target ( ) -> ( u32 , u32 ) {
@@ -181,7 +255,7 @@ fn watchos_lld_platform_version() -> String {
181
255
format ! ( "{}.{}" , major, minor)
182
256
}
183
257
184
- pub fn watchos_sim_llvm_target ( arch : & str ) -> String {
258
+ pub fn watchos_sim_llvm_target ( arch : Arch ) -> String {
185
259
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)
187
261
}
0 commit comments