11use std:: env;
2- use std:: fmt:: { Display , from_fn} ;
3- use std:: num:: ParseIntError ;
2+ use std:: str:: FromStr ;
43
54use rustc_session:: Session ;
65use rustc_target:: spec:: Target ;
6+ pub ( super ) use rustc_target:: spec:: apple:: OSVersion ;
77
88use crate :: errors:: AppleDeploymentTarget ;
99
@@ -26,76 +26,6 @@ pub(super) fn macho_platform(target: &Target) -> u32 {
2626 }
2727}
2828
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-
9929/// Name of the environment variable used to fetch the deployment target on the given OS.
10030pub fn deployment_target_env_var ( os : & str ) -> & ' static str {
10131 match os {
@@ -111,22 +41,22 @@ pub fn deployment_target_env_var(os: &str) -> &'static str {
11141/// Get the deployment target based on the standard environment variables, or fall back to the
11242/// minimum version supported by `rustc`.
11343pub fn deployment_target ( sess : & Session ) -> OSVersion {
114- let min = minimum_deployment_target ( & sess. target ) ;
44+ let min = OSVersion :: minimum_deployment_target ( & sess. target ) ;
11545 let env_var = deployment_target_env_var ( & sess. target . os ) ;
11646
11747 if let Ok ( deployment_target) = env:: var ( env_var) {
118- match parse_version ( & deployment_target) {
48+ match OSVersion :: from_str ( & deployment_target) {
11949 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 ) ;
12151 // It is common that the deployment target is set a bit too low, for example on
12252 // macOS Aarch64 to also target older x86_64. So we only want to warn when variable
12353 // is lower than the minimum OS supported by rustc, not when the variable is lower
12454 // than the minimum for a specific target.
12555 if version < os_min {
12656 sess. dcx ( ) . emit_warn ( AppleDeploymentTarget :: TooLow {
12757 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 ( ) ,
13060 } ) ;
13161 }
13262
@@ -155,17 +85,16 @@ pub(super) fn add_version_to_llvm_target(
15585 let environment = components. next ( ) ;
15686 assert_eq ! ( components. next( ) , None , "too many LLVM triple components" ) ;
15787
158- let ( major, minor, patch) = deployment_target;
159-
16088 assert ! (
16189 !os. contains( |c: char | c. is_ascii_digit( ) ) ,
16290 "LLVM target must not already be versioned"
16391 ) ;
16492
93+ let version = deployment_target. fmt_full ( ) ;
16594 if let Some ( env) = environment {
16695 // Insert version into OS, before environment
167- format ! ( "{arch}-{vendor}-{os}{major}.{minor}.{patch }-{env}" )
96+ format ! ( "{arch}-{vendor}-{os}{version }-{env}" )
16897 } else {
169- format ! ( "{arch}-{vendor}-{os}{major}.{minor}.{patch }" )
98+ format ! ( "{arch}-{vendor}-{os}{version }" )
17099 }
171100}
0 commit comments