@@ -120,6 +120,7 @@ pub struct Build {
120
120
warnings : Option < bool > ,
121
121
extra_warnings : Option < bool > ,
122
122
env_cache : Arc < Mutex < HashMap < String , Option < String > > > > ,
123
+ apple_sdk_root_cache : Arc < Mutex < HashMap < String , OsString > > > ,
123
124
}
124
125
125
126
/// Represents the types of errors that may occur while using cc-rs.
@@ -312,6 +313,7 @@ impl Build {
312
313
extra_warnings : None ,
313
314
warnings_into_errors : false ,
314
315
env_cache : Arc :: new ( Mutex :: new ( HashMap :: new ( ) ) ) ,
316
+ apple_sdk_root_cache : Arc :: new ( Mutex :: new ( HashMap :: new ( ) ) ) ,
315
317
}
316
318
}
317
319
@@ -1172,6 +1174,9 @@ impl Build {
1172
1174
cmd. arg ( "-c" ) ;
1173
1175
}
1174
1176
cmd. arg ( & obj. src ) ;
1177
+ if cfg ! ( target_os = "macos" ) {
1178
+ self . fix_env_for_apple_os ( & mut cmd) ?;
1179
+ }
1175
1180
1176
1181
run ( & mut cmd, & name) ?;
1177
1182
Ok ( ( ) )
@@ -1887,27 +1892,9 @@ impl Build {
1887
1892
} ;
1888
1893
1889
1894
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) ?;
1909
1896
cmd. args . push ( "-isysroot" . into ( ) ) ;
1910
- cmd. args . push ( sdk_path. trim ( ) . into ( ) ) ;
1897
+ cmd. args . push ( sdk_path) ;
1911
1898
cmd. args . push ( "-fembed-bitcode" . into ( ) ) ;
1912
1899
/*
1913
1900
* TODO we probably ultimately want the -fembed-bitcode-marker flag
@@ -2467,6 +2454,63 @@ impl Build {
2467
2454
println ! ( "{}" , s) ;
2468
2455
}
2469
2456
}
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
+ }
2470
2514
}
2471
2515
2472
2516
impl Default for Build {
0 commit comments