@@ -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,62 @@ 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 :: < 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+
34303488 let rustc = self . getenv ( "RUSTC" ) ;
34313489 let rustc = rustc. as_deref ( ) ;
34323490 // note the hardcoded minimums here are subject to change in a future compiler release,
@@ -3436,31 +3494,27 @@ impl Build {
34363494 // the ordering of env -> rustc -> old defaults is intentional for performance when using
34373495 // an explicit target
34383496 match os {
3439- AppleOs :: MacOs => env:: var ( "MACOSX_DEPLOYMENT_TARGET" )
3440- . ok ( )
3497+ AppleOs :: MacOs => deployment_from_env ( "MACOSX_DEPLOYMENT_TARGET" )
34413498 . or_else ( || rustc_provided_target ( rustc, target) )
3499+ . map ( maybe_cpp_version_baseline)
34423500 . unwrap_or_else ( || {
34433501 if arch_str == Some ( "aarch64" ) {
3444- "11.0"
3502+ "11.0" . into ( )
34453503 } else {
3446- if self . cpp {
3447- "10.9"
3448- } else {
3449- "10.7"
3450- }
3504+ maybe_cpp_version_baseline ( "10.7" . into ( ) )
34513505 }
3452- . into ( )
34533506 } ) ,
3454- AppleOs :: Ios => env :: var ( "IPHONEOS_DEPLOYMENT_TARGET" )
3455- . ok ( )
3507+
3508+ AppleOs :: Ios => deployment_from_env ( "IPHONEOS_DEPLOYMENT_TARGET" )
34563509 . 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" )
34603514 . or_else ( || rustc_provided_target ( rustc, target) )
34613515 . 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" )
34643518 . or_else ( || rustc_provided_target ( rustc, target) )
34653519 . unwrap_or_else ( || "9.0" . into ( ) ) ,
34663520 }
0 commit comments