diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 160d4c30c0bad..c47d7d85a3769 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -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 diff --git a/src/librustc_target/spec/apple_base.rs b/src/librustc_target/spec/apple_base.rs index c21f7f38ca5a3..9dd343b6c8de8 100644 --- a/src/librustc_target/spec/apple_base.rs +++ b/src/librustc_target/spec/apple_base.rs @@ -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::().and_then(|a| b.parse::().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::().and_then(|a| b.parse::().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 +} diff --git a/src/librustc_target/spec/i686_apple_darwin.rs b/src/librustc_target/spec/i686_apple_darwin.rs index 58c59cc872846..7d804ea53fb31 100644 --- a/src/librustc_target/spec/i686_apple_darwin.rs +++ b/src/librustc_target/spec/i686_apple_darwin.rs @@ -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(), diff --git a/src/librustc_target/spec/x86_64_apple_darwin.rs b/src/librustc_target/spec/x86_64_apple_darwin.rs index c54181741b3cc..182103440f035 100644 --- a/src/librustc_target/spec/x86_64_apple_darwin.rs +++ b/src/librustc_target/spec/x86_64_apple_darwin.rs @@ -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(), diff --git a/src/test/codegen/i686-macosx-deployment-target.rs b/src/test/codegen/i686-macosx-deployment-target.rs new file mode 100644 index 0000000000000..dad376d6677f7 --- /dev/null +++ b/src/test/codegen/i686-macosx-deployment-target.rs @@ -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 } +} diff --git a/src/test/codegen/x86_64-macosx-deployment-target.rs b/src/test/codegen/x86_64-macosx-deployment-target.rs new file mode 100644 index 0000000000000..8e291b7b298d5 --- /dev/null +++ b/src/test/codegen/x86_64-macosx-deployment-target.rs @@ -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 } +}