@@ -3407,6 +3407,8 @@ impl Build {
34073407 target : & str ,
34083408 arch_str : Option < & str > ,
34093409 ) -> String {
3410+ const OLD_IOS_MINIMUM_VERSION : & str = "7.0" ;
3411+
34103412 fn rustc_provided_target ( rustc : Option < & str > , target : & str ) -> Option < String > {
34113413 let rustc = rustc?;
34123414 let output = Command :: new ( rustc)
@@ -3427,6 +3429,74 @@ impl Build {
34273429 }
34283430 }
34293431
3432+ let deployment_from_env = |name : & str | {
3433+ // note this isn't hit in production codepaths, its mostly just for tests which don't
3434+ // set the real env
3435+ if let Some ( ( _, v) ) = self . env . iter ( ) . find ( |( k, _) | & * * k == OsStr :: new ( name) ) {
3436+ Some ( v. to_str ( ) . unwrap ( ) . to_string ( ) )
3437+ } else {
3438+ env:: var ( name) . ok ( )
3439+ }
3440+ } ;
3441+
3442+ // Determines if the acquired deployment target is too low to support modern C++ on some Apple platform.
3443+ //
3444+ // A long time ago they used libstdc++, but since macOS 10.9 and iOS 7 libc++ has been the library the SDKs provide to link against.
3445+ // If a `cc`` config wants to use C++, we round up to these versions as the baseline.
3446+ let maybe_cpp_version_baseline = |deployment_target_ver : String | -> String {
3447+ if !self . cpp {
3448+ return deployment_target_ver;
3449+ }
3450+
3451+ let mut deployment_target = deployment_target_ver
3452+ . split ( '.' )
3453+ . map ( |v| v. parse :: < u8 > ( ) . expect ( "integer version" ) ) ;
3454+
3455+ match os {
3456+ AppleOs :: MacOs => {
3457+ // Targeting higher then 10.x (11.0+)?
3458+ let major_supported = deployment_target
3459+ . next ( )
3460+ . map ( |major| major > 10 )
3461+ . unwrap_or_default ( ) ;
3462+
3463+ // Targeting higher then 10.9?
3464+ let minor_supported = deployment_target
3465+ . next ( )
3466+ . map ( |minor| minor >= 9 )
3467+ . unwrap_or_default ( ) ;
3468+
3469+ // If below 10.9, we round up.
3470+ if !major_supported && !minor_supported {
3471+ println ! (
3472+ "cargo-warning: macOS deployment target ({}) too low, it will be increased" ,
3473+ deployment_target_ver
3474+ ) ;
3475+ return String :: from ( "10.9" ) ;
3476+ }
3477+ }
3478+ AppleOs :: Ios => {
3479+ let major_supported = deployment_target
3480+ . next ( )
3481+ . map ( |major| major >= 7 )
3482+ . unwrap_or_default ( ) ;
3483+
3484+ if !major_supported {
3485+ println ! (
3486+ "cargo-warning: iOS deployment target ({}) too low, it will be increased" ,
3487+ deployment_target_ver
3488+ ) ;
3489+ return String :: from ( OLD_IOS_MINIMUM_VERSION ) ;
3490+ }
3491+ }
3492+ // watchOS, tvOS, and others are all new enough that libc++ is their baseline.
3493+ _ => { }
3494+ }
3495+
3496+ // If the deployment target met or exceeded the C++ baseline
3497+ deployment_target_ver
3498+ } ;
3499+
34303500 let rustc = self . getenv ( "RUSTC" ) ;
34313501 let rustc = rustc. as_deref ( ) ;
34323502 // note the hardcoded minimums here are subject to change in a future compiler release,
@@ -3436,31 +3506,27 @@ impl Build {
34363506 // the ordering of env -> rustc -> old defaults is intentional for performance when using
34373507 // an explicit target
34383508 match os {
3439- AppleOs :: MacOs => env:: var ( "MACOSX_DEPLOYMENT_TARGET" )
3440- . ok ( )
3509+ AppleOs :: MacOs => deployment_from_env ( "MACOSX_DEPLOYMENT_TARGET" )
34413510 . or_else ( || rustc_provided_target ( rustc, target) )
3511+ . map ( maybe_cpp_version_baseline)
34423512 . unwrap_or_else ( || {
34433513 if arch_str == Some ( "aarch64" ) {
3444- "11.0"
3514+ "11.0" . into ( )
34453515 } else {
3446- if self . cpp {
3447- "10.9"
3448- } else {
3449- "10.7"
3450- }
3516+ maybe_cpp_version_baseline ( "10.7" . into ( ) )
34513517 }
3452- . into ( )
34533518 } ) ,
3454- AppleOs :: Ios => env :: var ( "IPHONEOS_DEPLOYMENT_TARGET" )
3455- . ok ( )
3519+
3520+ AppleOs :: Ios => deployment_from_env ( "IPHONEOS_DEPLOYMENT_TARGET" )
34563521 . or_else ( || rustc_provided_target ( rustc, target) )
3457- . unwrap_or_else ( || "7.0" . into ( ) ) ,
3458- AppleOs :: WatchOs => env:: var ( "WATCHOS_DEPLOYMENT_TARGET" )
3459- . ok ( )
3522+ . map ( maybe_cpp_version_baseline)
3523+ . unwrap_or_else ( || OLD_IOS_MINIMUM_VERSION . into ( ) ) ,
3524+
3525+ AppleOs :: WatchOs => deployment_from_env ( "WATCHOS_DEPLOYMENT_TARGET" )
34603526 . or_else ( || rustc_provided_target ( rustc, target) )
34613527 . unwrap_or_else ( || "5.0" . into ( ) ) ,
3462- AppleOs :: TvOs => env :: var ( "TVOS_DEPLOYMENT_TARGET" )
3463- . ok ( )
3528+
3529+ AppleOs :: TvOs => deployment_from_env ( "TVOS_DEPLOYMENT_TARGET" )
34643530 . or_else ( || rustc_provided_target ( rustc, target) )
34653531 . unwrap_or_else ( || "9.0" . into ( ) ) ,
34663532 }
0 commit comments