@@ -2410,10 +2410,10 @@ fn add_order_independent_options(
2410
2410
// Take care of the flavors and CLI options requesting the `lld` linker.
2411
2411
add_lld_args ( cmd, sess, flavor, self_contained_components) ;
2412
2412
2413
- add_apple_link_args ( cmd, sess, flavor) ;
2414
-
2415
2413
let apple_sdk_data = add_apple_sdk ( cmd, sess, crate_type, flavor) ;
2416
2414
2415
+ add_apple_link_args ( cmd, sess, flavor, & apple_sdk_data) ;
2416
+
2417
2417
add_link_script ( cmd, sess, tmpdir, crate_type) ;
2418
2418
2419
2419
if sess. target . os == "fuchsia"
@@ -2970,7 +2970,12 @@ pub(crate) fn are_upstream_rust_objects_already_included(sess: &Session) -> bool
2970
2970
/// - The environment / ABI.
2971
2971
/// - The deployment target.
2972
2972
/// - The SDK version.
2973
- fn add_apple_link_args ( cmd : & mut dyn Linker , sess : & Session , flavor : LinkerFlavor ) {
2973
+ fn add_apple_link_args (
2974
+ cmd : & mut dyn Linker ,
2975
+ sess : & Session ,
2976
+ flavor : LinkerFlavor ,
2977
+ settings : & Option < ( PathBuf , SDKSettings ) > ,
2978
+ ) {
2974
2979
if !sess. target . is_like_osx {
2975
2980
return ;
2976
2981
}
@@ -3030,31 +3035,41 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo
3030
3035
// `-[NSView wantsBestResolutionOpenGLSurface]` is `YES` when the SDK version is >= 10.15.
3031
3036
// <https://developer.apple.com/documentation/appkit/nsview/1414938-wantsbestresolutionopenglsurface?language=objc>
3032
3037
//
3033
- // We do not currently know the actual SDK version though, so we have a few options:
3034
- // 1. Use the minimum version supported by rustc.
3035
- // 2. Use the same as the deployment target.
3036
- // 3. Use an arbitary recent version.
3037
- // 4. Omit the version.
3038
+ // So it is important that we pass the correct version here.
3038
3039
//
3039
- // The first option is too low / too conservative, and means that users will not get the
3040
- // same behaviour from a binary compiled with rustc as with one compiled by clang.
3041
3040
//
3042
- // The second option is similarly conservative, and also wrong since if the user specified a
3043
- // higher deployment target than the SDK they're compiling/linking with, the runtime might
3044
- // make invalid assumptions about the capabilities of the binary.
3041
+ // For posterity, insufficient alternatives are listed below:
3045
3042
//
3046
- // The third option requires that `rustc` is periodically kept up to date with Apple's SDK
3047
- // version, and is also wrong for similar reasons as above.
3043
+ // 1. Use the minimum version supported by rustc.
3044
+ // Too low / too conservative, and means that users will not get the same behaviour from
3045
+ // a binary compiled with rustc as with one compiled by clang.
3048
3046
//
3049
- // The fourth option is bad because while `ld`, `otool`, `vtool` and such understand it to
3050
- // mean "absent" or `n/a`, dyld doesn't actually understand it, and will end up interpreting
3051
- // it as 0.0, which is again too low/conservative.
3047
+ // 2. Use the same as the deployment target.
3048
+ // Similarly conservative, and also wrong since if the user specified a higher deployment
3049
+ // target than the SDK they're compiling/linking with, the runtime might make invalid
3050
+ // assumptions about the capabilities of the binary.
3052
3051
//
3053
- // Currently, we lie about the SDK version, and choose the second option.
3052
+ // 3. Use an arbitary recent version.
3053
+ // Requires that `rustc` is periodically kept up to date with Apple's SDK version, and is
3054
+ // also wrong for similar reasons as above.
3054
3055
//
3055
- // FIXME(madsmtm): Parse the SDK version from the SDK root instead.
3056
- // <https://github.com/rust-lang/rust/issues/129432>
3057
- let sdk_version = & * min_version;
3056
+ // 4. Omit the version.
3057
+ // Bad because while `ld`, `otool`, `vtool` and such understand it to mean "absent" or
3058
+ // `n/a`, dyld doesn't actually understand it, and will end up interpreting it as 0.0,
3059
+ // which is again too low/conservative.
3060
+ let AppleOSVersion { major, minor, patch } = if let Some ( ( sdkroot, settings) ) = settings {
3061
+ settings. sdk_version ( & sess. target , & sdkroot) . unwrap_or_else ( |err| {
3062
+ sess. dcx ( ) . emit_err ( err) ;
3063
+ AppleOSVersion :: MAX
3064
+ } )
3065
+ } else {
3066
+ // If the SDK wasn't read properly, we may have errored already, but we may also only
3067
+ // have given a warning to support `zig cc` on non-macOS hosts. `ld64` requires the SDK
3068
+ // version though, so we must actually error here.
3069
+ sess. dcx ( ) . emit_err ( errors:: AppleSdkError :: MustHaveWhenUsingLd64 ) ;
3070
+ AppleOSVersion :: MAX
3071
+ } ;
3072
+ let sdk_version = format ! ( "{major}.{minor}.{patch}" ) ;
3058
3073
3059
3074
// From the man page for ld64 (`man ld`):
3060
3075
// > This is set to indicate the platform, oldest supported version of
@@ -3064,7 +3079,7 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo
3064
3079
// Like with `-arch`, the linker can figure out the platform versions
3065
3080
// itself from the binaries being linked, but to be safe, we specify
3066
3081
// the desired versions here explicitly.
3067
- cmd. link_args ( & [ "-platform_version" , platform_name, & * min_version, sdk_version] ) ;
3082
+ cmd. link_args ( & [ "-platform_version" , platform_name, & * min_version, & * sdk_version] ) ;
3068
3083
} else {
3069
3084
// cc == Cc::Yes
3070
3085
//
0 commit comments