@@ -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,62 @@ 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 :: < u32 > ( ) . expect ( "integer version" ) ) ;
3454
+
3455
+ match os {
3456
+ AppleOs :: MacOs => {
3457
+ let major = deployment_target. next ( ) . unwrap_or ( 0 ) ;
3458
+ let minor = deployment_target. next ( ) . unwrap_or ( 0 ) ;
3459
+
3460
+ // If below 10.9, we round up.
3461
+ if major == 10 && minor < 9 {
3462
+ println ! (
3463
+ "cargo-warning: macOS deployment target ({}) too low, it will be increased" ,
3464
+ deployment_target_ver
3465
+ ) ;
3466
+ return String :: from ( "10.9" ) ;
3467
+ }
3468
+ }
3469
+ AppleOs :: Ios => {
3470
+ let major = deployment_target. next ( ) . unwrap_or ( 0 ) ;
3471
+
3472
+ if major < 7 {
3473
+ println ! (
3474
+ "cargo-warning: iOS deployment target ({}) too low, it will be increased" ,
3475
+ deployment_target_ver
3476
+ ) ;
3477
+ return String :: from ( OLD_IOS_MINIMUM_VERSION ) ;
3478
+ }
3479
+ }
3480
+ // watchOS, tvOS, and others are all new enough that libc++ is their baseline.
3481
+ _ => { }
3482
+ }
3483
+
3484
+ // If the deployment target met or exceeded the C++ baseline
3485
+ deployment_target_ver
3486
+ } ;
3487
+
3430
3488
let rustc = self . getenv ( "RUSTC" ) ;
3431
3489
let rustc = rustc. as_deref ( ) ;
3432
3490
// note the hardcoded minimums here are subject to change in a future compiler release,
@@ -3436,31 +3494,27 @@ impl Build {
3436
3494
// the ordering of env -> rustc -> old defaults is intentional for performance when using
3437
3495
// an explicit target
3438
3496
match os {
3439
- AppleOs :: MacOs => env:: var ( "MACOSX_DEPLOYMENT_TARGET" )
3440
- . ok ( )
3497
+ AppleOs :: MacOs => deployment_from_env ( "MACOSX_DEPLOYMENT_TARGET" )
3441
3498
. or_else ( || rustc_provided_target ( rustc, target) )
3499
+ . map ( maybe_cpp_version_baseline)
3442
3500
. unwrap_or_else ( || {
3443
3501
if arch_str == Some ( "aarch64" ) {
3444
- "11.0"
3502
+ "11.0" . into ( )
3445
3503
} else {
3446
- if self . cpp {
3447
- "10.9"
3448
- } else {
3449
- "10.7"
3450
- }
3504
+ maybe_cpp_version_baseline ( "10.7" . into ( ) )
3451
3505
}
3452
- . into ( )
3453
3506
} ) ,
3454
- AppleOs :: Ios => env :: var ( "IPHONEOS_DEPLOYMENT_TARGET" )
3455
- . ok ( )
3507
+
3508
+ AppleOs :: Ios => deployment_from_env ( "IPHONEOS_DEPLOYMENT_TARGET" )
3456
3509
. or_else ( || rustc_provided_target ( rustc, target) )
3457
- . unwrap_or_else ( || "7.0" . into ( ) ) ,
3458
- AppleOs :: WatchOs => env:: var ( "WATCHOS_DEPLOYMENT_TARGET" )
3459
- . ok ( )
3510
+ . map ( maybe_cpp_version_baseline)
3511
+ . unwrap_or_else ( || OLD_IOS_MINIMUM_VERSION . into ( ) ) ,
3512
+
3513
+ AppleOs :: WatchOs => deployment_from_env ( "WATCHOS_DEPLOYMENT_TARGET" )
3460
3514
. or_else ( || rustc_provided_target ( rustc, target) )
3461
3515
. unwrap_or_else ( || "5.0" . into ( ) ) ,
3462
- AppleOs :: TvOs => env :: var ( "TVOS_DEPLOYMENT_TARGET" )
3463
- . ok ( )
3516
+
3517
+ AppleOs :: TvOs => deployment_from_env ( "TVOS_DEPLOYMENT_TARGET" )
3464
3518
. or_else ( || rustc_provided_target ( rustc, target) )
3465
3519
. unwrap_or_else ( || "9.0" . into ( ) ) ,
3466
3520
}
0 commit comments