Skip to content

Fix sysroot on macOS when cross-compiling and SDKROOT is set #64254

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from Sep 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/librustc_codegen_ssa/back/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub struct Command {
program: Program,
args: Vec<OsString>,
env: Vec<(OsString, OsString)>,
env_remove: Vec<OsString>,
}

#[derive(Clone)]
Expand Down Expand Up @@ -41,6 +42,7 @@ impl Command {
program,
args: Vec::new(),
env: Vec::new(),
env_remove: Vec::new(),
}
}

Expand Down Expand Up @@ -75,6 +77,17 @@ impl Command {
self.env.push((key.to_owned(), value.to_owned()));
}

pub fn env_remove<K>(&mut self, key: K) -> &mut Command
where K: AsRef<OsStr>,
{
self._env_remove(key.as_ref());
self
}

fn _env_remove(&mut self, key: &OsStr) {
self.env_remove.push(key.to_owned());
}

pub fn output(&mut self) -> io::Result<Output> {
self.command().output()
}
Expand All @@ -100,6 +113,9 @@ impl Command {
};
ret.args(&self.args);
ret.envs(self.env.clone());
for k in &self.env_remove {
ret.env_remove(k);
}
return ret
}

Expand Down
3 changes: 3 additions & 0 deletions src/librustc_codegen_ssa/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,9 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>(sess: &'a Session,
for &(ref k, ref v) in &sess.target.target.options.link_env {
cmd.env(k, v);
}
for k in &sess.target.target.options.link_env_remove {
cmd.env_remove(k);
}

if sess.opts.debugging_opts.print_link_args {
println!("{:?}", &cmd);
Expand Down
16 changes: 16 additions & 0 deletions src/librustc_target/spec/apple_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,19 @@ pub fn macos_llvm_target(arch: &str) -> String {
let (major, minor) = macos_deployment_target();
format!("{}-apple-macosx{}.{}.0", arch, major, minor)
}

pub fn macos_link_env_remove() -> Vec<String> {
let mut env_remove = Vec::with_capacity(2);
// Remove the `SDKROOT` environment variable if it's clearly set for the wrong platform, which
// may occur when we're linking a custom build script while targeting iOS for example.
if let Some(sdkroot) = env::var("SDKROOT").ok() {
if sdkroot.contains("iPhoneOS.platform") || sdkroot.contains("iPhoneSimulator.platform") {
env_remove.push("SDKROOT".to_string())
}
}
// Additionally, `IPHONEOS_DEPLOYMENT_TARGET` must not be set when using the Xcode linker at
// "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld",
// although this is apparently ignored when using the linker at "/usr/bin/ld".
env_remove.push("IPHONEOS_DEPLOYMENT_TARGET".to_string());
env_remove
}
23 changes: 20 additions & 3 deletions src/librustc_target/spec/apple_ios_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,18 @@ pub fn get_sdk_root(sdk_name: &str) -> Result<String, String> {
// SDKROOT; for rustc, the user or build system can set it, or we
// can fall back to checking for xcrun on PATH.)
if let Some(sdkroot) = env::var("SDKROOT").ok() {
let sdkroot_path = Path::new(&sdkroot);
if sdkroot_path.is_absolute() && sdkroot_path != Path::new("/") && sdkroot_path.exists() {
return Ok(sdkroot);
let p = Path::new(&sdkroot);
match sdk_name {
// Ignore `SDKROOT` if it's clearly set for the wrong platform.
"iphoneos" if sdkroot.contains("iPhoneSimulator.platform")
|| sdkroot.contains("MacOSX.platform") => (),
"iphonesimulator" if sdkroot.contains("iPhoneOS.platform")
|| sdkroot.contains("MacOSX.platform") => (),
"macosx10.15" if sdkroot.contains("iPhoneOS.platform")
|| sdkroot.contains("iPhoneSimulator.platform") => (),
// Ignore `SDKROOT` if it's not a valid path.
_ if !p.is_absolute() || p == Path::new("/") || !p.exists() => (),
_ => return Ok(sdkroot),
}
}
let res = Command::new("xcrun")
Expand Down Expand Up @@ -100,13 +109,21 @@ fn target_cpu(arch: Arch) -> String {
}.to_string()
}

fn link_env_remove(arch: Arch) -> Vec<String> {
match arch {
Armv7 | Armv7s | Arm64 | I386 | X86_64 => vec!["MACOSX_DEPLOYMENT_TARGET".to_string()],
X86_64_macabi => vec!["IPHONEOS_DEPLOYMENT_TARGET".to_string()],
}
}

pub fn opts(arch: Arch) -> Result<TargetOptions, String> {
let pre_link_args = build_pre_link_args(arch)?;
Ok(TargetOptions {
cpu: target_cpu(arch),
dynamic_linking: false,
executables: true,
pre_link_args,
link_env_remove: link_env_remove(arch),
has_elf_tls: false,
eliminate_frame_pointer: false,
.. super::apple_base::opts()
Expand Down
1 change: 1 addition & 0 deletions src/librustc_target/spec/i686_apple_darwin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub fn target() -> TargetResult {
base.cpu = "yonah".to_string();
base.max_atomic_width = Some(64);
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]);
base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
base.stack_probes = true;
base.eliminate_frame_pointer = false;

Expand Down
7 changes: 6 additions & 1 deletion src/librustc_target/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,8 +580,10 @@ pub struct TargetOptions {
/// user-defined libraries.
pub post_link_args: LinkArgs,

/// Environment variables to be set before invoking the linker.
/// Environment variables to be set for the linker invocation.
pub link_env: Vec<(String, String)>,
/// Environment variables to be removed for the linker invocation.
pub link_env_remove: Vec<String>,

/// Extra arguments to pass to the external assembler (when used)
pub asm_args: Vec<String>,
Expand Down Expand Up @@ -843,6 +845,7 @@ impl Default for TargetOptions {
post_link_objects_crt: Vec::new(),
late_link_args: LinkArgs::new(),
link_env: Vec::new(),
link_env_remove: Vec::new(),
archive_format: "gnu".to_string(),
custom_unwind_resume: false,
allow_asm: true,
Expand Down Expand Up @@ -1118,6 +1121,7 @@ impl Target {
key!(post_link_objects_crt, list);
key!(post_link_args, link_args);
key!(link_env, env);
key!(link_env_remove, list);
key!(asm_args, list);
key!(cpu);
key!(features);
Expand Down Expand Up @@ -1334,6 +1338,7 @@ impl ToJson for Target {
target_option_val!(post_link_objects_crt);
target_option_val!(link_args - post_link_args);
target_option_val!(env - link_env);
target_option_val!(link_env_remove);
target_option_val!(asm_args);
target_option_val!(cpu);
target_option_val!(features);
Expand Down
1 change: 1 addition & 0 deletions src/librustc_target/spec/x86_64_apple_darwin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub fn target() -> TargetResult {
base.max_atomic_width = Some(128); // core2 support cmpxchg16b
base.eliminate_frame_pointer = false;
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]);
base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
base.stack_probes = true;

// Clang automatically chooses a more specific target based on
Expand Down