1
- use std:: env;
2
1
use std:: ffi:: OsString ;
3
- use std:: fmt:: { Display , from_fn} ;
4
- use std:: num:: ParseIntError ;
5
2
use std:: path:: PathBuf ;
6
3
use std:: process:: Command ;
7
4
8
5
use itertools:: Itertools ;
9
6
use rustc_middle:: middle:: exported_symbols:: SymbolExportKind ;
10
7
use rustc_session:: Session ;
11
8
use rustc_target:: spec:: Target ;
9
+ pub ( super ) use rustc_target:: spec:: apple:: OSVersion ;
12
10
use tracing:: debug;
13
11
14
- use crate :: errors:: { AppleDeploymentTarget , XcrunError , XcrunSdkPathWarning } ;
12
+ use crate :: errors:: { XcrunError , XcrunSdkPathWarning } ;
15
13
use crate :: fluent_generated as fluent;
16
14
17
15
#[ cfg( test) ]
@@ -134,124 +132,6 @@ pub(super) fn add_data_and_relocation(
134
132
Ok ( ( ) )
135
133
}
136
134
137
- /// Deployment target or SDK version.
138
- ///
139
- /// The size of the numbers in here are limited by Mach-O's `LC_BUILD_VERSION`.
140
- type OSVersion = ( u16 , u8 , u8 ) ;
141
-
142
- /// Parse an OS version triple (SDK version or deployment target).
143
- fn parse_version ( version : & str ) -> Result < OSVersion , ParseIntError > {
144
- if let Some ( ( major, minor) ) = version. split_once ( '.' ) {
145
- let major = major. parse ( ) ?;
146
- if let Some ( ( minor, patch) ) = minor. split_once ( '.' ) {
147
- Ok ( ( major, minor. parse ( ) ?, patch. parse ( ) ?) )
148
- } else {
149
- Ok ( ( major, minor. parse ( ) ?, 0 ) )
150
- }
151
- } else {
152
- Ok ( ( version. parse ( ) ?, 0 , 0 ) )
153
- }
154
- }
155
-
156
- pub fn pretty_version ( version : OSVersion ) -> impl Display {
157
- let ( major, minor, patch) = version;
158
- from_fn ( move |f| {
159
- write ! ( f, "{major}.{minor}" ) ?;
160
- if patch != 0 {
161
- write ! ( f, ".{patch}" ) ?;
162
- }
163
- Ok ( ( ) )
164
- } )
165
- }
166
-
167
- /// Minimum operating system versions currently supported by `rustc`.
168
- fn os_minimum_deployment_target ( os : & str ) -> OSVersion {
169
- // When bumping a version in here, remember to update the platform-support docs too.
170
- //
171
- // NOTE: The defaults may change in future `rustc` versions, so if you are looking for the
172
- // default deployment target, prefer:
173
- // ```
174
- // $ rustc --print deployment-target
175
- // ```
176
- match os {
177
- "macos" => ( 10 , 12 , 0 ) ,
178
- "ios" => ( 10 , 0 , 0 ) ,
179
- "tvos" => ( 10 , 0 , 0 ) ,
180
- "watchos" => ( 5 , 0 , 0 ) ,
181
- "visionos" => ( 1 , 0 , 0 ) ,
182
- _ => unreachable ! ( "tried to get deployment target for non-Apple platform" ) ,
183
- }
184
- }
185
-
186
- /// The deployment target for the given target.
187
- ///
188
- /// This is similar to `os_minimum_deployment_target`, except that on certain targets it makes sense
189
- /// to raise the minimum OS version.
190
- ///
191
- /// This matches what LLVM does, see in part:
192
- /// <https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/llvm/lib/TargetParser/Triple.cpp#L1900-L1932>
193
- fn minimum_deployment_target ( target : & Target ) -> OSVersion {
194
- match ( & * target. os , & * target. arch , & * target. abi ) {
195
- ( "macos" , "aarch64" , _) => ( 11 , 0 , 0 ) ,
196
- ( "ios" , "aarch64" , "macabi" ) => ( 14 , 0 , 0 ) ,
197
- ( "ios" , "aarch64" , "sim" ) => ( 14 , 0 , 0 ) ,
198
- ( "ios" , _, _) if target. llvm_target . starts_with ( "arm64e" ) => ( 14 , 0 , 0 ) ,
199
- // Mac Catalyst defaults to 13.1 in Clang.
200
- ( "ios" , _, "macabi" ) => ( 13 , 1 , 0 ) ,
201
- ( "tvos" , "aarch64" , "sim" ) => ( 14 , 0 , 0 ) ,
202
- ( "watchos" , "aarch64" , "sim" ) => ( 7 , 0 , 0 ) ,
203
- ( os, _, _) => os_minimum_deployment_target ( os) ,
204
- }
205
- }
206
-
207
- /// Name of the environment variable used to fetch the deployment target on the given OS.
208
- pub fn deployment_target_env_var ( os : & str ) -> & ' static str {
209
- match os {
210
- "macos" => "MACOSX_DEPLOYMENT_TARGET" ,
211
- "ios" => "IPHONEOS_DEPLOYMENT_TARGET" ,
212
- "watchos" => "WATCHOS_DEPLOYMENT_TARGET" ,
213
- "tvos" => "TVOS_DEPLOYMENT_TARGET" ,
214
- "visionos" => "XROS_DEPLOYMENT_TARGET" ,
215
- _ => unreachable ! ( "tried to get deployment target env var for non-Apple platform" ) ,
216
- }
217
- }
218
-
219
- /// Get the deployment target based on the standard environment variables, or fall back to the
220
- /// minimum version supported by `rustc`.
221
- pub fn deployment_target ( sess : & Session ) -> OSVersion {
222
- let min = minimum_deployment_target ( & sess. target ) ;
223
- let env_var = deployment_target_env_var ( & sess. target . os ) ;
224
-
225
- if let Ok ( deployment_target) = env:: var ( env_var) {
226
- match parse_version ( & deployment_target) {
227
- Ok ( version) => {
228
- let os_min = os_minimum_deployment_target ( & sess. target . os ) ;
229
- // It is common that the deployment target is set a bit too low, for example on
230
- // macOS Aarch64 to also target older x86_64. So we only want to warn when variable
231
- // is lower than the minimum OS supported by rustc, not when the variable is lower
232
- // than the minimum for a specific target.
233
- if version < os_min {
234
- sess. dcx ( ) . emit_warn ( AppleDeploymentTarget :: TooLow {
235
- env_var,
236
- version : pretty_version ( version) . to_string ( ) ,
237
- os_min : pretty_version ( os_min) . to_string ( ) ,
238
- } ) ;
239
- }
240
-
241
- // Raise the deployment target to the minimum supported.
242
- version. max ( min)
243
- }
244
- Err ( error) => {
245
- sess. dcx ( ) . emit_err ( AppleDeploymentTarget :: Invalid { env_var, error } ) ;
246
- min
247
- }
248
- }
249
- } else {
250
- // If no deployment target variable is set, default to the minimum found above.
251
- min
252
- }
253
- }
254
-
255
135
pub ( super ) fn add_version_to_llvm_target (
256
136
llvm_target : & str ,
257
137
deployment_target : OSVersion ,
@@ -263,18 +143,17 @@ pub(super) fn add_version_to_llvm_target(
263
143
let environment = components. next ( ) ;
264
144
assert_eq ! ( components. next( ) , None , "too many LLVM triple components" ) ;
265
145
266
- let ( major, minor, patch) = deployment_target;
267
-
268
146
assert ! (
269
147
!os. contains( |c: char | c. is_ascii_digit( ) ) ,
270
148
"LLVM target must not already be versioned"
271
149
) ;
272
150
151
+ let version = deployment_target. fmt_full ( ) ;
273
152
if let Some ( env) = environment {
274
153
// Insert version into OS, before environment
275
- format ! ( "{arch}-{vendor}-{os}{major}.{minor}.{patch }-{env}" )
154
+ format ! ( "{arch}-{vendor}-{os}{version }-{env}" )
276
155
} else {
277
- format ! ( "{arch}-{vendor}-{os}{major}.{minor}.{patch }" )
156
+ format ! ( "{arch}-{vendor}-{os}{version }" )
278
157
}
279
158
}
280
159
0 commit comments