1- use std:: env;
21use std:: ffi:: OsString ;
3- use std:: fmt:: { Display , from_fn} ;
4- use std:: num:: ParseIntError ;
52use std:: path:: PathBuf ;
63use std:: process:: Command ;
74
85use itertools:: Itertools ;
96use rustc_middle:: middle:: exported_symbols:: SymbolExportKind ;
107use rustc_session:: Session ;
118use rustc_target:: spec:: Target ;
9+ pub ( super ) use rustc_target:: spec:: apple:: OSVersion ;
1210use tracing:: debug;
1311
14- use crate :: errors:: { AppleDeploymentTarget , XcrunError , XcrunSdkPathWarning } ;
12+ use crate :: errors:: { XcrunError , XcrunSdkPathWarning } ;
1513use crate :: fluent_generated as fluent;
1614
1715#[ cfg( test) ]
@@ -134,124 +132,6 @@ pub(super) fn add_data_and_relocation(
134132 Ok ( ( ) )
135133}
136134
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-
255135pub ( super ) fn add_version_to_llvm_target (
256136 llvm_target : & str ,
257137 deployment_target : OSVersion ,
@@ -263,18 +143,17 @@ pub(super) fn add_version_to_llvm_target(
263143 let environment = components. next ( ) ;
264144 assert_eq ! ( components. next( ) , None , "too many LLVM triple components" ) ;
265145
266- let ( major, minor, patch) = deployment_target;
267-
268146 assert ! (
269147 !os. contains( |c: char | c. is_ascii_digit( ) ) ,
270148 "LLVM target must not already be versioned"
271149 ) ;
272150
151+ let version = deployment_target. fmt_full ( ) ;
273152 if let Some ( env) = environment {
274153 // Insert version into OS, before environment
275- format ! ( "{arch}-{vendor}-{os}{major}.{minor}.{patch }-{env}" )
154+ format ! ( "{arch}-{vendor}-{os}{version }-{env}" )
276155 } else {
277- format ! ( "{arch}-{vendor}-{os}{major}.{minor}.{patch }" )
156+ format ! ( "{arch}-{vendor}-{os}{version }" )
278157 }
279158}
280159
0 commit comments