@@ -3208,15 +3208,37 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) ->
32083208 let sdkroot = sess. time ( "get_apple_sdk_root" , || get_apple_sdk_root ( sess) ) ?;
32093209
32103210 if cc == Cc :: Yes {
3211- // Use `-isysroot` instead of `--sysroot`, as only the former
3212- // makes Clang treat it as a platform SDK.
3211+ // There are a few options to pass the SDK root when linking with a C/C++ compiler:
3212+ // - The `--sysroot` flag.
3213+ // - The `-isysroot` flag.
3214+ // - The `SDKROOT` environment variable.
32133215 //
3214- // This is admittedly a bit strange, as on most targets
3215- // `-isysroot` only applies to include header files, but on Apple
3216- // targets this also applies to libraries and frameworks.
3217- cmd. cc_arg ( "-isysroot" ) ;
3218- cmd. cc_arg ( & sdk_root) ;
3216+ // `--sysroot` isn't actually enough to get Clang to treat it as a platform SDK, you need
3217+ // to specify `-isysroot`. This is admittedly a bit strange, as on most targets `-isysroot`
3218+ // only applies to include header files, but on Apple targets it also applies to libraries
3219+ // and frameworks.
3220+ //
3221+ // This leaves the choice between `-isysroot` and `SDKROOT`. Both are supported by Clang and
3222+ // GCC, though they may not be supported by all compiler drivers. We choose `SDKROOT`,
3223+ // primarily because that is the same interface that is used when invoking the tool under
3224+ // `xcrun -sdk macosx $tool`.
3225+ //
3226+ // In that sense, if a given compiler driver does not support `SDKROOT`, the blame is fairly
3227+ // clearly in the tool in question, since they also don't support being run under `xcrun`.
3228+ //
3229+ // Additionally, `SDKROOT` is an environment variable and thus optional. It also has lower
3230+ // precedence than `-isysroot`, so a custom compiler driver that does not support it and
3231+ // instead figures out the SDK on their own can easily do so by using `-isysroot`.
3232+ //
3233+ // (This in particular affects Clang built with the `DEFAULT_SYSROOT` CMake flag, such as
3234+ // the one provided by some versions of Homebrew's `llvm` package. Those will end up
3235+ // ignoring the value we set here, and instead use their built-in sysroot).
3236+ cmd. cmd ( ) . env ( "SDKROOT" , & sdkroot) ;
32193237 } else {
3238+ // When invoking the linker directly, we use the `-syslibroot` parameter. `SDKROOT` is not
3239+ // read by the linker, so it's really the only option.
3240+ //
3241+ // This is also what Clang does.
32203242 cmd. link_arg ( "-syslibroot" ) ;
32213243 cmd. link_arg ( & sdkroot) ;
32223244 }
@@ -3250,7 +3272,13 @@ fn get_apple_sdk_root(sess: &Session) -> Option<PathBuf> {
32503272 }
32513273 "macosx"
32523274 if sdkroot. contains ( "iPhoneOS.platform" )
3253- || sdkroot. contains ( "iPhoneSimulator.platform" ) => { }
3275+ || sdkroot. contains ( "iPhoneSimulator.platform" )
3276+ || sdkroot. contains ( "AppleTVOS.platform" )
3277+ || sdkroot. contains ( "AppleTVSimulator.platform" )
3278+ || sdkroot. contains ( "WatchOS.platform" )
3279+ || sdkroot. contains ( "WatchSimulator.platform" )
3280+ || sdkroot. contains ( "XROS.platform" )
3281+ || sdkroot. contains ( "XRSimulator.platform" ) => { }
32543282 "watchos"
32553283 if sdkroot. contains ( "WatchSimulator.platform" )
32563284 || sdkroot. contains ( "MacOSX.platform" ) => { }
0 commit comments