@@ -3407,6 +3407,8 @@ impl Build {
3407
3407
target : & str ,
3408
3408
arch_str : Option < & str > ,
3409
3409
) -> String {
3410
+ const OLD_IOS_MINIMUM_VERSION : & str = "7.0" ;
3411
+
3410
3412
fn rustc_provided_target ( rustc : Option < & str > , target : & str ) -> Option < String > {
3411
3413
let rustc = rustc?;
3412
3414
let output = Command :: new ( rustc)
@@ -3427,6 +3429,74 @@ impl Build {
3427
3429
}
3428
3430
}
3429
3431
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
+
3430
3500
let rustc = self . getenv ( "RUSTC" ) ;
3431
3501
let rustc = rustc. as_deref ( ) ;
3432
3502
// note the hardcoded minimums here are subject to change in a future compiler release,
@@ -3436,31 +3506,27 @@ impl Build {
3436
3506
// the ordering of env -> rustc -> old defaults is intentional for performance when using
3437
3507
// an explicit target
3438
3508
match os {
3439
- AppleOs :: MacOs => env:: var ( "MACOSX_DEPLOYMENT_TARGET" )
3440
- . ok ( )
3509
+ AppleOs :: MacOs => deployment_from_env ( "MACOSX_DEPLOYMENT_TARGET" )
3441
3510
. or_else ( || rustc_provided_target ( rustc, target) )
3511
+ . map ( maybe_cpp_version_baseline)
3442
3512
. unwrap_or_else ( || {
3443
3513
if arch_str == Some ( "aarch64" ) {
3444
- "11.0"
3514
+ "11.0" . into ( )
3445
3515
} else {
3446
- if self . cpp {
3447
- "10.9"
3448
- } else {
3449
- "10.7"
3450
- }
3516
+ maybe_cpp_version_baseline ( "10.7" . into ( ) )
3451
3517
}
3452
- . into ( )
3453
3518
} ) ,
3454
- AppleOs :: Ios => env :: var ( "IPHONEOS_DEPLOYMENT_TARGET" )
3455
- . ok ( )
3519
+
3520
+ AppleOs :: Ios => deployment_from_env ( "IPHONEOS_DEPLOYMENT_TARGET" )
3456
3521
. 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" )
3460
3526
. or_else ( || rustc_provided_target ( rustc, target) )
3461
3527
. 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" )
3464
3530
. or_else ( || rustc_provided_target ( rustc, target) )
3465
3531
. unwrap_or_else ( || "9.0" . into ( ) ) ,
3466
3532
}
0 commit comments