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_session:: Session ;
6
5
use rustc_target:: spec:: Target ;
6
+ pub ( super ) use rustc_target:: spec:: apple:: OSVersion ;
7
7
8
8
use crate :: errors:: AppleDeploymentTarget ;
9
9
@@ -26,76 +26,6 @@ pub(super) fn macho_platform(target: &Target) -> u32 {
26
26
}
27
27
}
28
28
29
- /// Deployment target or SDK version.
30
- ///
31
- /// The size of the numbers in here are limited by Mach-O's `LC_BUILD_VERSION`.
32
- type OSVersion = ( u16 , u8 , u8 ) ;
33
-
34
- /// Parse an OS version triple (SDK version or deployment target).
35
- fn parse_version ( version : & str ) -> Result < OSVersion , ParseIntError > {
36
- if let Some ( ( major, minor) ) = version. split_once ( '.' ) {
37
- let major = major. parse ( ) ?;
38
- if let Some ( ( minor, patch) ) = minor. split_once ( '.' ) {
39
- Ok ( ( major, minor. parse ( ) ?, patch. parse ( ) ?) )
40
- } else {
41
- Ok ( ( major, minor. parse ( ) ?, 0 ) )
42
- }
43
- } else {
44
- Ok ( ( version. parse ( ) ?, 0 , 0 ) )
45
- }
46
- }
47
-
48
- pub fn pretty_version ( version : OSVersion ) -> impl Display {
49
- let ( major, minor, patch) = version;
50
- from_fn ( move |f| {
51
- write ! ( f, "{major}.{minor}" ) ?;
52
- if patch != 0 {
53
- write ! ( f, ".{patch}" ) ?;
54
- }
55
- Ok ( ( ) )
56
- } )
57
- }
58
-
59
- /// Minimum operating system versions currently supported by `rustc`.
60
- fn os_minimum_deployment_target ( os : & str ) -> OSVersion {
61
- // When bumping a version in here, remember to update the platform-support docs too.
62
- //
63
- // NOTE: The defaults may change in future `rustc` versions, so if you are looking for the
64
- // default deployment target, prefer:
65
- // ```
66
- // $ rustc --print deployment-target
67
- // ```
68
- match os {
69
- "macos" => ( 10 , 12 , 0 ) ,
70
- "ios" => ( 10 , 0 , 0 ) ,
71
- "tvos" => ( 10 , 0 , 0 ) ,
72
- "watchos" => ( 5 , 0 , 0 ) ,
73
- "visionos" => ( 1 , 0 , 0 ) ,
74
- _ => unreachable ! ( "tried to get deployment target for non-Apple platform" ) ,
75
- }
76
- }
77
-
78
- /// The deployment target for the given target.
79
- ///
80
- /// This is similar to `os_minimum_deployment_target`, except that on certain targets it makes sense
81
- /// to raise the minimum OS version.
82
- ///
83
- /// This matches what LLVM does, see in part:
84
- /// <https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/llvm/lib/TargetParser/Triple.cpp#L1900-L1932>
85
- fn minimum_deployment_target ( target : & Target ) -> OSVersion {
86
- match ( & * target. os , & * target. arch , & * target. abi ) {
87
- ( "macos" , "aarch64" , _) => ( 11 , 0 , 0 ) ,
88
- ( "ios" , "aarch64" , "macabi" ) => ( 14 , 0 , 0 ) ,
89
- ( "ios" , "aarch64" , "sim" ) => ( 14 , 0 , 0 ) ,
90
- ( "ios" , _, _) if target. llvm_target . starts_with ( "arm64e" ) => ( 14 , 0 , 0 ) ,
91
- // Mac Catalyst defaults to 13.1 in Clang.
92
- ( "ios" , _, "macabi" ) => ( 13 , 1 , 0 ) ,
93
- ( "tvos" , "aarch64" , "sim" ) => ( 14 , 0 , 0 ) ,
94
- ( "watchos" , "aarch64" , "sim" ) => ( 7 , 0 , 0 ) ,
95
- ( os, _, _) => os_minimum_deployment_target ( os) ,
96
- }
97
- }
98
-
99
29
/// Name of the environment variable used to fetch the deployment target on the given OS.
100
30
pub fn deployment_target_env_var ( os : & str ) -> & ' static str {
101
31
match os {
@@ -111,22 +41,22 @@ pub fn deployment_target_env_var(os: &str) -> &'static str {
111
41
/// Get the deployment target based on the standard environment variables, or fall back to the
112
42
/// minimum version supported by `rustc`.
113
43
pub fn deployment_target ( sess : & Session ) -> OSVersion {
114
- let min = minimum_deployment_target ( & sess. target ) ;
44
+ let min = OSVersion :: minimum_deployment_target ( & sess. target ) ;
115
45
let env_var = deployment_target_env_var ( & sess. target . os ) ;
116
46
117
47
if let Ok ( deployment_target) = env:: var ( env_var) {
118
- match parse_version ( & deployment_target) {
48
+ match OSVersion :: from_str ( & deployment_target) {
119
49
Ok ( version) => {
120
- let os_min = os_minimum_deployment_target ( & sess. target . os ) ;
50
+ let os_min = OSVersion :: os_minimum_deployment_target ( & sess. target . os ) ;
121
51
// It is common that the deployment target is set a bit too low, for example on
122
52
// macOS Aarch64 to also target older x86_64. So we only want to warn when variable
123
53
// is lower than the minimum OS supported by rustc, not when the variable is lower
124
54
// than the minimum for a specific target.
125
55
if version < os_min {
126
56
sess. dcx ( ) . emit_warn ( AppleDeploymentTarget :: TooLow {
127
57
env_var,
128
- version : pretty_version ( version) . to_string ( ) ,
129
- os_min : pretty_version ( os_min) . to_string ( ) ,
58
+ version : version. fmt_pretty ( ) . to_string ( ) ,
59
+ os_min : os_min. fmt_pretty ( ) . to_string ( ) ,
130
60
} ) ;
131
61
}
132
62
@@ -155,17 +85,16 @@ pub(super) fn add_version_to_llvm_target(
155
85
let environment = components. next ( ) ;
156
86
assert_eq ! ( components. next( ) , None , "too many LLVM triple components" ) ;
157
87
158
- let ( major, minor, patch) = deployment_target;
159
-
160
88
assert ! (
161
89
!os. contains( |c: char | c. is_ascii_digit( ) ) ,
162
90
"LLVM target must not already be versioned"
163
91
) ;
164
92
93
+ let version = deployment_target. fmt_full ( ) ;
165
94
if let Some ( env) = environment {
166
95
// Insert version into OS, before environment
167
- format ! ( "{arch}-{vendor}-{os}{major}.{minor}.{patch }-{env}" )
96
+ format ! ( "{arch}-{vendor}-{os}{version }-{env}" )
168
97
} else {
169
- format ! ( "{arch}-{vendor}-{os}{major}.{minor}.{patch }" )
98
+ format ! ( "{arch}-{vendor}-{os}{version }" )
170
99
}
171
100
}
0 commit comments