Skip to content

Commit

Permalink
Auto merge of #60378 - froydnj:apple-target-modifications, r=michaelw…
Browse files Browse the repository at this point in the history
…oerister

conditionally modify darwin targets to macosx targets with versions

We need this behavior so that Rust LLVM IR objects match the target triple for Clang LLVM IR objects.  This matching then convinces the linker that yes, you really can do cross-language LTO with objects from different compilers.

The newly-added tests seem to pass locally on x86_64-unknown-linux-gnu.  I haven't done a full test run or tried the new compiler in an cross-language LTO setup yet.
  • Loading branch information
bors committed May 8, 2019
2 parents 33cde4a + 97ba4c9 commit b92d360
Show file tree
Hide file tree
Showing 10 changed files with 157 additions and 12 deletions.
4 changes: 2 additions & 2 deletions src/librustc_metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ impl<'a> CrateLoader<'a> {
Sanitizer::Leak => LSAN_SUPPORTED_TARGETS,
Sanitizer::Memory => MSAN_SUPPORTED_TARGETS,
};
if !supported_targets.contains(&&*self.sess.target.target.llvm_target) {
if !supported_targets.contains(&&*self.sess.opts.target_triple.triple()) {
self.sess.err(&format!("{:?}Sanitizer only works with the `{}` target",
sanitizer,
supported_targets.join("` or `")
Expand All @@ -794,7 +794,7 @@ impl<'a> CrateLoader<'a> {
// firstyear 2017 - during testing I was unable to access an OSX machine
// to make this work on different crate types. As a result, today I have
// only been able to test and support linux as a target.
if self.sess.target.target.llvm_target == "x86_64-unknown-linux-gnu" {
if self.sess.opts.target_triple.triple() == "x86_64-unknown-linux-gnu" {
if !self.sess.crate_types.borrow().iter().all(|ct| {
match *ct {
// Link the runtime
Expand Down
32 changes: 25 additions & 7 deletions src/librustc_target/spec/apple_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,7 @@ pub fn opts() -> TargetOptions {
//
// Here we detect what version is being requested, defaulting to 10.7. ELF
// TLS is flagged as enabled if it looks to be supported.
let deployment_target = env::var("MACOSX_DEPLOYMENT_TARGET").ok();
let version = deployment_target.as_ref().and_then(|s| {
let mut i = s.splitn(2, '.');
i.next().and_then(|a| i.next().map(|b| (a, b)))
}).and_then(|(a, b)| {
a.parse::<u32>().and_then(|a| b.parse::<u32>().map(|b| (a, b))).ok()
}).unwrap_or((10, 7));
let version = macos_deployment_target().unwrap_or((10, 7));

TargetOptions {
// macOS has -dead_strip, which doesn't rely on function_sections
Expand All @@ -40,3 +34,27 @@ pub fn opts() -> TargetOptions {
.. Default::default()
}
}

fn macos_deployment_target() -> Option<(u32, u32)> {
let deployment_target = env::var("MACOSX_DEPLOYMENT_TARGET").ok();
let version = deployment_target.as_ref().and_then(|s| {
let mut i = s.splitn(2, '.');
i.next().and_then(|a| i.next().map(|b| (a, b)))
}).and_then(|(a, b)| {
a.parse::<u32>().and_then(|a| b.parse::<u32>().map(|b| (a, b))).ok()
});

version
}

pub fn macos_llvm_target(arch: &str) -> String {
let version = macos_deployment_target();
let llvm_target = match version {
Some((major, minor)) => {
format!("{}-apple-macosx{}.{}.0", arch, major, minor)
},
None => format!("{}-apple-darwin", arch)
};

llvm_target
}
8 changes: 7 additions & 1 deletion src/librustc_target/spec/i686_apple_darwin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@ pub fn target() -> TargetResult {
base.stack_probes = true;
base.eliminate_frame_pointer = false;

// Clang automatically chooses a more specific target based on
// MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
// correctly, we do too.
let arch = "i686";
let llvm_target = super::apple_base::macos_llvm_target(&arch);

Ok(Target {
llvm_target: "i686-apple-darwin".to_string(),
llvm_target: llvm_target,
target_endian: "little".to_string(),
target_pointer_width: "32".to_string(),
target_c_int_width: "32".to_string(),
Expand Down
10 changes: 8 additions & 2 deletions src/librustc_target/spec/x86_64_apple_darwin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,19 @@ pub fn target() -> TargetResult {
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]);
base.stack_probes = true;

// Clang automatically chooses a more specific target based on
// MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
// correctly, we do too.
let arch = "x86_64";
let llvm_target = super::apple_base::macos_llvm_target(&arch);

Ok(Target {
llvm_target: "x86_64-apple-darwin".to_string(),
llvm_target: llvm_target,
target_endian: "little".to_string(),
target_pointer_width: "64".to_string(),
target_c_int_width: "32".to_string(),
data_layout: "e-m:o-i64:64-f80:128-n8:16:32:64-S128".to_string(),
arch: "x86_64".to_string(),
arch: arch.to_string(),
target_os: "macos".to_string(),
target_env: String::new(),
target_vendor: "apple".to_string(),
Expand Down
26 changes: 26 additions & 0 deletions src/test/codegen/i686-macosx-deployment-target.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Checks that we correctly modify the target when MACOSX_DEPLOYMENT_TARGET is set.
// See issue #60235.

// compile-flags: -O --target=i686-apple-darwin --crate-type=rlib
// rustc-env:MACOSX_DEPLOYMENT_TARGET=10.9
#![feature(no_core, lang_items)]
#![no_core]

#[lang="sized"]
trait Sized { }
#[lang="freeze"]
trait Freeze { }
#[lang="copy"]
trait Copy { }

#[repr(C)]
pub struct Bool {
b: bool,
}

// CHECK: target triple = "i686-apple-macosx10.9.0"
#[no_mangle]
pub extern "C" fn structbool() -> Bool {
Bool { b: true }
}
26 changes: 26 additions & 0 deletions src/test/codegen/i686-no-macosx-deployment-target.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Checks that we leave the target alone MACOSX_DEPLOYMENT_TARGET is unset.
// See issue #60235.

// compile-flags: -O --target=i686-apple-darwin --crate-type=rlib
// unset-rustc-env:MACOSX_DEPLOYMENT_TARGET
#![feature(no_core, lang_items)]
#![no_core]

#[lang="sized"]
trait Sized { }
#[lang="freeze"]
trait Freeze { }
#[lang="copy"]
trait Copy { }

#[repr(C)]
pub struct Bool {
b: bool,
}

// CHECK: target triple = "i686-apple-darwin"
#[no_mangle]
pub extern "C" fn structbool() -> Bool {
Bool { b: true }
}
26 changes: 26 additions & 0 deletions src/test/codegen/x86_64-macosx-deployment-target.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Checks that we correctly modify the target when MACOSX_DEPLOYMENT_TARGET is set.
// See issue #60235.

// compile-flags: -O --target=x86_64-apple-darwin --crate-type=rlib
// rustc-env:MACOSX_DEPLOYMENT_TARGET=10.9
#![feature(no_core, lang_items)]
#![no_core]

#[lang="sized"]
trait Sized { }
#[lang="freeze"]
trait Freeze { }
#[lang="copy"]
trait Copy { }

#[repr(C)]
pub struct Bool {
b: bool,
}

// CHECK: target triple = "x86_64-apple-macosx10.9.0"
#[no_mangle]
pub extern "C" fn structbool() -> Bool {
Bool { b: true }
}
26 changes: 26 additions & 0 deletions src/test/codegen/x86_64-no-macosx-deployment-target.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Checks that we leave the target alone when MACOSX_DEPLOYMENT_TARGET is unset.
// See issue #60235.

// compile-flags: -O --target=x86_64-apple-darwin --crate-type=rlib
// unset-rustc-env:MACOSX_DEPLOYMENT_TARGET
#![feature(no_core, lang_items)]
#![no_core]

#[lang="sized"]
trait Sized { }
#[lang="freeze"]
trait Freeze { }
#[lang="copy"]
trait Copy { }

#[repr(C)]
pub struct Bool {
b: bool,
}

// CHECK: target triple = "x86_64-apple-darwin"
#[no_mangle]
pub extern "C" fn structbool() -> Bool {
Bool { b: true }
}
8 changes: 8 additions & 0 deletions src/tools/compiletest/src/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,9 @@ pub struct TestProps {
pub extern_private: Vec<String>,
// Environment settings to use for compiling
pub rustc_env: Vec<(String, String)>,
// Environment variables to unset prior to compiling.
// Variables are unset before applying 'rustc_env'.
pub unset_rustc_env: Vec<String>,
// Environment settings to use during execution
pub exec_env: Vec<(String, String)>,
// Lines to check if they appear in the expected debugger output
Expand Down Expand Up @@ -373,6 +376,7 @@ impl TestProps {
extern_private: vec![],
revisions: vec![],
rustc_env: vec![],
unset_rustc_env: vec![],
exec_env: vec![],
check_lines: vec![],
build_aux_docs: false,
Expand Down Expand Up @@ -499,6 +503,10 @@ impl TestProps {
self.rustc_env.push(ee);
}

if let Some(ev) = config.parse_name_value_directive(ln, "unset-rustc-env") {
self.unset_rustc_env.push(ev);
}

if let Some(cl) = config.parse_check_line(ln) {
self.check_lines.push(cl);
}
Expand Down
3 changes: 3 additions & 0 deletions src/tools/compiletest/src/runtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1703,6 +1703,9 @@ impl<'test> TestCx<'test> {
add_extern_priv(&private_lib, true);
}

self.props.unset_rustc_env.clone()
.iter()
.fold(&mut rustc, |rustc, v| rustc.env_remove(v));
rustc.envs(self.props.rustc_env.clone());
self.compose_and_run(
rustc,
Expand Down

0 comments on commit b92d360

Please sign in to comment.