@@ -1524,6 +1524,9 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
15241524 // NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
15251525 add_pre_link_args ( cmd, sess, flavor) ;
15261526
1527+ // NO-OPT-OUT, OBJECT-FILES-NO
1528+ add_apple_sdk ( cmd, sess, flavor) ;
1529+
15271530 // NO-OPT-OUT
15281531 add_link_script ( cmd, sess, tmpdir, crate_type) ;
15291532
@@ -2083,3 +2086,86 @@ fn are_upstream_rust_objects_already_included(sess: &Session) -> bool {
20832086 config:: Lto :: No | config:: Lto :: ThinLocal => false ,
20842087 }
20852088}
2089+
2090+ fn add_apple_sdk ( cmd : & mut dyn Linker , sess : & Session , flavor : LinkerFlavor ) {
2091+ let arch = & sess. target . target . arch ;
2092+ let os = & sess. target . target . target_os ;
2093+ let llvm_target = & sess. target . target . llvm_target ;
2094+ if sess. target . target . target_vendor != "apple"
2095+ || !matches ! ( os. as_str( ) , "ios" | "tvos" )
2096+ || flavor != LinkerFlavor :: Gcc
2097+ {
2098+ return ;
2099+ }
2100+ let sdk_name = match ( arch. as_str ( ) , os. as_str ( ) ) {
2101+ ( "aarch64" , "tvos" ) => "appletvos" ,
2102+ ( "x86_64" , "tvos" ) => "appletvsimulator" ,
2103+ ( "arm" , "ios" ) => "iphoneos" ,
2104+ ( "aarch64" , "ios" ) => "iphoneos" ,
2105+ ( "x86" , "ios" ) => "iphonesimulator" ,
2106+ ( "x86_64" , "ios" ) if llvm_target. contains ( "macabi" ) => "macosx10.15" ,
2107+ ( "x86_64" , "ios" ) => "iphonesimulator" ,
2108+ _ => {
2109+ sess. err ( & format ! ( "unsupported arch `{}` for os `{}`" , arch, os) ) ;
2110+ return ;
2111+ }
2112+ } ;
2113+ let sdk_root = match get_apple_sdk_root ( sdk_name) {
2114+ Ok ( s) => s,
2115+ Err ( e) => {
2116+ sess. err ( & e) ;
2117+ return ;
2118+ }
2119+ } ;
2120+ let arch_name = llvm_target. split ( '-' ) . next ( ) . expect ( "LLVM target must have a hyphen" ) ;
2121+ cmd. args ( & [ "-arch" , arch_name, "-isysroot" , & sdk_root, "-Wl,-syslibroot" , & sdk_root] ) ;
2122+ }
2123+
2124+ fn get_apple_sdk_root ( sdk_name : & str ) -> Result < String , String > {
2125+ // Following what clang does
2126+ // (https://github.com/llvm/llvm-project/blob/
2127+ // 296a80102a9b72c3eda80558fb78a3ed8849b341/clang/lib/Driver/ToolChains/Darwin.cpp#L1661-L1678)
2128+ // to allow the SDK path to be set. (For clang, xcrun sets
2129+ // SDKROOT; for rustc, the user or build system can set it, or we
2130+ // can fall back to checking for xcrun on PATH.)
2131+ if let Ok ( sdkroot) = env:: var ( "SDKROOT" ) {
2132+ let p = Path :: new ( & sdkroot) ;
2133+ match sdk_name {
2134+ // Ignore `SDKROOT` if it's clearly set for the wrong platform.
2135+ "appletvos"
2136+ if sdkroot. contains ( "TVSimulator.platform" )
2137+ || sdkroot. contains ( "MacOSX.platform" ) => { }
2138+ "appletvsimulator"
2139+ if sdkroot. contains ( "TVOS.platform" ) || sdkroot. contains ( "MacOSX.platform" ) => { }
2140+ "iphoneos"
2141+ if sdkroot. contains ( "iPhoneSimulator.platform" )
2142+ || sdkroot. contains ( "MacOSX.platform" ) => { }
2143+ "iphonesimulator"
2144+ if sdkroot. contains ( "iPhoneOS.platform" ) || sdkroot. contains ( "MacOSX.platform" ) => {
2145+ }
2146+ "macosx10.15"
2147+ if sdkroot. contains ( "iPhoneOS.platform" )
2148+ || sdkroot. contains ( "iPhoneSimulator.platform" ) => { }
2149+ // Ignore `SDKROOT` if it's not a valid path.
2150+ _ if !p. is_absolute ( ) || p == Path :: new ( "/" ) || !p. exists ( ) => { }
2151+ _ => return Ok ( sdkroot) ,
2152+ }
2153+ }
2154+ let res =
2155+ Command :: new ( "xcrun" ) . arg ( "--show-sdk-path" ) . arg ( "-sdk" ) . arg ( sdk_name) . output ( ) . and_then (
2156+ |output| {
2157+ if output. status . success ( ) {
2158+ Ok ( String :: from_utf8 ( output. stdout ) . unwrap ( ) )
2159+ } else {
2160+ let error = String :: from_utf8 ( output. stderr ) ;
2161+ let error = format ! ( "process exit with error: {}" , error. unwrap( ) ) ;
2162+ Err ( io:: Error :: new ( io:: ErrorKind :: Other , & error[ ..] ) )
2163+ }
2164+ } ,
2165+ ) ;
2166+
2167+ match res {
2168+ Ok ( output) => Ok ( output. trim ( ) . to_string ( ) ) ,
2169+ Err ( e) => Err ( format ! ( "failed to get {} SDK path: {}" , sdk_name, e) ) ,
2170+ }
2171+ }
0 commit comments