Auto merge of #60378 - froydnj:apple-target-modifications, r=michaelwoerister
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.
This commit is contained in:
commit
b92d360c6c
|
@ -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 `")
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
@ -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,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(),
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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 }
|
||||
}
|
|
@ -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 }
|
||||
}
|
|
@ -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 }
|
||||
}
|
|
@ -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 }
|
||||
}
|
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue