@@ -120,6 +120,7 @@ pub struct Build {
120120 warnings : Option < bool > ,
121121 extra_warnings : Option < bool > ,
122122 env_cache : Arc < Mutex < HashMap < String , Option < String > > > > ,
123+ apple_sdk_root_cache : Arc < Mutex < HashMap < String , OsString > > > ,
123124}
124125
125126/// Represents the types of errors that may occur while using cc-rs.
@@ -312,6 +313,7 @@ impl Build {
312313 extra_warnings : None ,
313314 warnings_into_errors : false ,
314315 env_cache : Arc :: new ( Mutex :: new ( HashMap :: new ( ) ) ) ,
316+ apple_sdk_root_cache : Arc :: new ( Mutex :: new ( HashMap :: new ( ) ) ) ,
315317 }
316318 }
317319
@@ -1172,6 +1174,9 @@ impl Build {
11721174 cmd. arg ( "-c" ) ;
11731175 }
11741176 cmd. arg ( & obj. src ) ;
1177+ if cfg ! ( target_os = "macos" ) {
1178+ self . fix_env_for_apple_os ( & mut cmd) ?;
1179+ }
11751180
11761181 run ( & mut cmd, & name) ?;
11771182 Ok ( ( ) )
@@ -1887,27 +1892,9 @@ impl Build {
18871892 } ;
18881893
18891894 self . print ( & format ! ( "Detecting iOS SDK path for {}" , sdk) ) ;
1890- let sdk_path = self
1891- . cmd ( "xcrun" )
1892- . arg ( "--show-sdk-path" )
1893- . arg ( "--sdk" )
1894- . arg ( sdk)
1895- . stderr ( Stdio :: inherit ( ) )
1896- . output ( ) ?
1897- . stdout ;
1898-
1899- let sdk_path = match String :: from_utf8 ( sdk_path) {
1900- Ok ( p) => p,
1901- Err ( _) => {
1902- return Err ( Error :: new (
1903- ErrorKind :: IOError ,
1904- "Unable to determine iOS SDK path." ,
1905- ) ) ;
1906- }
1907- } ;
1908-
1895+ let sdk_path = self . apple_sdk_root ( sdk) ?;
19091896 cmd. args . push ( "-isysroot" . into ( ) ) ;
1910- cmd. args . push ( sdk_path. trim ( ) . into ( ) ) ;
1897+ cmd. args . push ( sdk_path) ;
19111898 cmd. args . push ( "-fembed-bitcode" . into ( ) ) ;
19121899 /*
19131900 * TODO we probably ultimately want the -fembed-bitcode-marker flag
@@ -2467,6 +2454,63 @@ impl Build {
24672454 println ! ( "{}" , s) ;
24682455 }
24692456 }
2457+
2458+ fn fix_env_for_apple_os ( & self , cmd : & mut Command ) -> Result < ( ) , Error > {
2459+ let target = self . get_target ( ) ?;
2460+ let host = self . get_host ( ) ?;
2461+ if host. contains ( "apple-darwin" ) && target. contains ( "apple-darwin" ) {
2462+ // If, for example, `cargo` runs during the build of an XCode project, then `SDKROOT` environment variable
2463+ // would represent the current target, and this is the problem for us, if we want to compile something
2464+ // for the host, when host != target.
2465+ // We can not just remove `SDKROOT`, because, again, for example, XCode add to PATH
2466+ // /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
2467+ // and `cc` from this path can not find system include files, like `pthread.h`, if `SDKROOT`
2468+ // is not set
2469+ if let Ok ( sdkroot) = env:: var ( "SDKROOT" ) {
2470+ if !sdkroot. contains ( "MacOSX" ) {
2471+ let macos_sdk = self . apple_sdk_root ( "macosx" ) ?;
2472+ cmd. env ( "SDKROOT" , macos_sdk) ;
2473+ }
2474+ }
2475+ // Additionally, `IPHONEOS_DEPLOYMENT_TARGET` must not be set when using the Xcode linker at
2476+ // "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld",
2477+ // although this is apparently ignored when using the linker at "/usr/bin/ld".
2478+ cmd. env_remove ( "IPHONEOS_DEPLOYMENT_TARGET" ) ;
2479+ }
2480+ Ok ( ( ) )
2481+ }
2482+
2483+ fn apple_sdk_root ( & self , sdk : & str ) -> Result < OsString , Error > {
2484+ let mut cache = self
2485+ . apple_sdk_root_cache
2486+ . lock ( )
2487+ . expect ( "apple_sdk_root_cache lock failed" ) ;
2488+ if let Some ( ret) = cache. get ( sdk) {
2489+ return Ok ( ret. clone ( ) ) ;
2490+ }
2491+
2492+ let sdk_path = self
2493+ . cmd ( "xcrun" )
2494+ . arg ( "--show-sdk-path" )
2495+ . arg ( "--sdk" )
2496+ . arg ( sdk)
2497+ . stderr ( Stdio :: inherit ( ) )
2498+ . output ( ) ?
2499+ . stdout ;
2500+
2501+ let sdk_path = match String :: from_utf8 ( sdk_path) {
2502+ Ok ( p) => p,
2503+ Err ( _) => {
2504+ return Err ( Error :: new (
2505+ ErrorKind :: IOError ,
2506+ "Unable to determine iOS SDK path." ,
2507+ ) ) ;
2508+ }
2509+ } ;
2510+ let ret: OsString = sdk_path. trim ( ) . into ( ) ;
2511+ cache. insert ( sdk. into ( ) , ret. clone ( ) ) ;
2512+ Ok ( ret)
2513+ }
24702514}
24712515
24722516impl Default for Build {
0 commit comments