Skip to content

Commit a970b0a

Browse files
authored
handle wrong SDKROOT for macos->macos build (#537)
fixes #530
1 parent 369eeac commit a970b0a

File tree

1 file changed

+64
-20
lines changed

1 file changed

+64
-20
lines changed

src/lib.rs

+64-20
Original file line numberDiff line numberDiff line change
@@ -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

24722516
impl Default for Build {

0 commit comments

Comments
 (0)