@@ -1524,6 +1524,9 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
1524
1524
// NO-OPT-OUT, OBJECT-FILES-MAYBE, CUSTOMIZATION-POINT
1525
1525
add_pre_link_args ( cmd, sess, flavor) ;
1526
1526
1527
+ // NO-OPT-OUT, OBJECT-FILES-NO
1528
+ add_apple_sdk ( cmd, sess, flavor) ;
1529
+
1527
1530
// NO-OPT-OUT
1528
1531
add_link_script ( cmd, sess, tmpdir, crate_type) ;
1529
1532
@@ -2083,3 +2086,86 @@ fn are_upstream_rust_objects_already_included(sess: &Session) -> bool {
2083
2086
config:: Lto :: No | config:: Lto :: ThinLocal => false ,
2084
2087
}
2085
2088
}
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