1
1
use std:: env;
2
- use std:: fmt:: { Display , from_fn} ;
3
- use std:: num:: ParseIntError ;
2
+ use std:: str:: FromStr ;
4
3
5
4
use rustc_middle:: middle:: exported_symbols:: SymbolExportKind ;
6
5
use rustc_session:: Session ;
7
6
use rustc_target:: spec:: Target ;
7
+ pub ( super ) use rustc_target:: spec:: apple:: OSVersion ;
8
8
9
9
use crate :: errors:: AppleDeploymentTarget ;
10
10
@@ -110,76 +110,6 @@ pub(super) fn add_data_and_relocation(
110
110
Ok ( ( ) )
111
111
}
112
112
113
- /// Deployment target or SDK version.
114
- ///
115
- /// The size of the numbers in here are limited by Mach-O's `LC_BUILD_VERSION`.
116
- type OSVersion = ( u16 , u8 , u8 ) ;
117
-
118
- /// Parse an OS version triple (SDK version or deployment target).
119
- fn parse_version ( version : & str ) -> Result < OSVersion , ParseIntError > {
120
- if let Some ( ( major, minor) ) = version. split_once ( '.' ) {
121
- let major = major. parse ( ) ?;
122
- if let Some ( ( minor, patch) ) = minor. split_once ( '.' ) {
123
- Ok ( ( major, minor. parse ( ) ?, patch. parse ( ) ?) )
124
- } else {
125
- Ok ( ( major, minor. parse ( ) ?, 0 ) )
126
- }
127
- } else {
128
- Ok ( ( version. parse ( ) ?, 0 , 0 ) )
129
- }
130
- }
131
-
132
- pub fn pretty_version ( version : OSVersion ) -> impl Display {
133
- let ( major, minor, patch) = version;
134
- from_fn ( move |f| {
135
- write ! ( f, "{major}.{minor}" ) ?;
136
- if patch != 0 {
137
- write ! ( f, ".{patch}" ) ?;
138
- }
139
- Ok ( ( ) )
140
- } )
141
- }
142
-
143
- /// Minimum operating system versions currently supported by `rustc`.
144
- fn os_minimum_deployment_target ( os : & str ) -> OSVersion {
145
- // When bumping a version in here, remember to update the platform-support docs too.
146
- //
147
- // NOTE: The defaults may change in future `rustc` versions, so if you are looking for the
148
- // default deployment target, prefer:
149
- // ```
150
- // $ rustc --print deployment-target
151
- // ```
152
- match os {
153
- "macos" => ( 10 , 12 , 0 ) ,
154
- "ios" => ( 10 , 0 , 0 ) ,
155
- "tvos" => ( 10 , 0 , 0 ) ,
156
- "watchos" => ( 5 , 0 , 0 ) ,
157
- "visionos" => ( 1 , 0 , 0 ) ,
158
- _ => unreachable ! ( "tried to get deployment target for non-Apple platform" ) ,
159
- }
160
- }
161
-
162
- /// The deployment target for the given target.
163
- ///
164
- /// This is similar to `os_minimum_deployment_target`, except that on certain targets it makes sense
165
- /// to raise the minimum OS version.
166
- ///
167
- /// This matches what LLVM does, see in part:
168
- /// <https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/llvm/lib/TargetParser/Triple.cpp#L1900-L1932>
169
- fn minimum_deployment_target ( target : & Target ) -> OSVersion {
170
- match ( & * target. os , & * target. arch , & * target. abi ) {
171
- ( "macos" , "aarch64" , _) => ( 11 , 0 , 0 ) ,
172
- ( "ios" , "aarch64" , "macabi" ) => ( 14 , 0 , 0 ) ,
173
- ( "ios" , "aarch64" , "sim" ) => ( 14 , 0 , 0 ) ,
174
- ( "ios" , _, _) if target. llvm_target . starts_with ( "arm64e" ) => ( 14 , 0 , 0 ) ,
175
- // Mac Catalyst defaults to 13.1 in Clang.
176
- ( "ios" , _, "macabi" ) => ( 13 , 1 , 0 ) ,
177
- ( "tvos" , "aarch64" , "sim" ) => ( 14 , 0 , 0 ) ,
178
- ( "watchos" , "aarch64" , "sim" ) => ( 7 , 0 , 0 ) ,
179
- ( os, _, _) => os_minimum_deployment_target ( os) ,
180
- }
181
- }
182
-
183
113
/// Name of the environment variable used to fetch the deployment target on the given OS.
184
114
pub fn deployment_target_env_var ( os : & str ) -> & ' static str {
185
115
match os {
@@ -195,22 +125,22 @@ pub fn deployment_target_env_var(os: &str) -> &'static str {
195
125
/// Get the deployment target based on the standard environment variables, or fall back to the
196
126
/// minimum version supported by `rustc`.
197
127
pub fn deployment_target ( sess : & Session ) -> OSVersion {
198
- let min = minimum_deployment_target ( & sess. target ) ;
128
+ let min = OSVersion :: minimum_deployment_target ( & sess. target ) ;
199
129
let env_var = deployment_target_env_var ( & sess. target . os ) ;
200
130
201
131
if let Ok ( deployment_target) = env:: var ( env_var) {
202
- match parse_version ( & deployment_target) {
132
+ match OSVersion :: from_str ( & deployment_target) {
203
133
Ok ( version) => {
204
- let os_min = os_minimum_deployment_target ( & sess. target . os ) ;
134
+ let os_min = OSVersion :: os_minimum_deployment_target ( & sess. target . os ) ;
205
135
// It is common that the deployment target is set a bit too low, for example on
206
136
// macOS Aarch64 to also target older x86_64. So we only want to warn when variable
207
137
// is lower than the minimum OS supported by rustc, not when the variable is lower
208
138
// than the minimum for a specific target.
209
139
if version < os_min {
210
140
sess. dcx ( ) . emit_warn ( AppleDeploymentTarget :: TooLow {
211
141
env_var,
212
- version : pretty_version ( version) . to_string ( ) ,
213
- os_min : pretty_version ( os_min) . to_string ( ) ,
142
+ version : version. fmt_pretty ( ) . to_string ( ) ,
143
+ os_min : os_min. fmt_pretty ( ) . to_string ( ) ,
214
144
} ) ;
215
145
}
216
146
@@ -239,17 +169,16 @@ pub(super) fn add_version_to_llvm_target(
239
169
let environment = components. next ( ) ;
240
170
assert_eq ! ( components. next( ) , None , "too many LLVM triple components" ) ;
241
171
242
- let ( major, minor, patch) = deployment_target;
243
-
244
172
assert ! (
245
173
!os. contains( |c: char | c. is_ascii_digit( ) ) ,
246
174
"LLVM target must not already be versioned"
247
175
) ;
248
176
177
+ let version = deployment_target. fmt_full ( ) ;
249
178
if let Some ( env) = environment {
250
179
// Insert version into OS, before environment
251
- format ! ( "{arch}-{vendor}-{os}{major}.{minor}.{patch }-{env}" )
180
+ format ! ( "{arch}-{vendor}-{os}{version }-{env}" )
252
181
} else {
253
- format ! ( "{arch}-{vendor}-{os}{major}.{minor}.{patch }" )
182
+ format ! ( "{arch}-{vendor}-{os}{version }" )
254
183
}
255
184
}
0 commit comments