diff --git a/src/cargo/core/compiler/compilation.rs b/src/cargo/core/compiler/compilation.rs index 47c64c49775..ba7c09d75d3 100644 --- a/src/cargo/core/compiler/compilation.rs +++ b/src/cargo/core/compiler/compilation.rs @@ -6,7 +6,7 @@ use std::path::PathBuf; use semver::Version; use super::BuildContext; -use crate::core::{Edition, Package, PackageId, Target}; +use crate::core::{compiler::Kind, Edition, Package, PackageId, Target}; use crate::util::{self, join_paths, process, CargoResult, CfgExpr, Config, ProcessBuilder}; pub struct Doctest { @@ -117,6 +117,7 @@ impl<'cfg> Compilation<'cfg> { &self, pkg: &Package, target: &Target, + kind: Kind, is_primary: bool, ) -> CargoResult { let rustc = if is_primary { @@ -128,6 +129,15 @@ impl<'cfg> Compilation<'cfg> { }; let mut p = self.fill_env(rustc, pkg, true)?; + // Invoking cargo build from an Xcode project targeting iOS or iOS Simulator used to fail to + // build any crate with a custom build script, because the wrong linker was invoked for the + // custom build script. This is because Xcode sets SDKROOT for the target platform (the + // build script must be built for the host platform instead) + if kind == Kind::Host { + #[cfg(target_os = "macos")] + p.env("SDKROOT", get_sdk_root("macosx")?); + } + if target.edition() != Edition::Edition2015 { p.arg(format!("--edition={}", target.edition())); } @@ -308,3 +318,21 @@ fn target_runner(bcx: &BuildContext<'_, '_>) -> CargoResult CargoResult { + let res = process("xcrun") + .arg("--show-sdk-path") + .arg("--sdk") + .arg(sdk_name) + .exec_with_output(); + + match res { + Ok(output) => Ok(String::from_utf8(output.stdout).unwrap().trim().to_string()), + Err(e) => Err(failure::format_err!( + "failed to get {} SDK path: {}", + sdk_name, + e + )), + } +} diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 5567537f095..958245dad4c 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -602,7 +602,7 @@ fn prepare_rustc<'a, 'cfg>( let mut base = cx .compilation - .rustc_process(unit.pkg, unit.target, is_primary)?; + .rustc_process(unit.pkg, unit.target, unit.kind, is_primary)?; base.inherit_jobserver(&cx.jobserver); build_base_args(cx, &mut base, unit, crate_types)?; build_deps_args(&mut base, cx, unit)?;