Skip to content

Commit

Permalink
Rollup merge of rust-lang#90499 - rusticstuff:macos-target-fixes, r=p…
Browse files Browse the repository at this point in the history
…etrochenkov

Link with default MACOSX_DEPLOYMENT_TARGET if not otherwise specified.

This PR sets the MACOSX_DEPLOYMENT_TARGET environment variable during the linking stage to our default, if it is not specified. This way it matches the deployment target we pass to llvm. If not set the the linker uses Xcode or Xcode commandline tools default which varies by version.

Fixes rust-lang#90342, rust-lang#91082.

Drive-by fixes to make Rust behave more like clang:
* Default to 11.0 deployment target for ARM64 which is the earliest version that had support for it.
* Set the llvm target to `arm64-apple-macosx<deployment target>` instead of `aarch64-apple-macosx<deployment target>`.
  • Loading branch information
matthiaskrgr authored Nov 25, 2021
2 parents 90dd7c0 + b376f56 commit 0780889
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 9 deletions.
6 changes: 3 additions & 3 deletions compiler/rustc_target/src/spec/aarch64_apple_darwin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ pub fn target() -> Target {
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD;

base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), "arm64".to_string()]);
base.link_env.extend(super::apple_base::macos_link_env("arm64"));
base.link_env_remove.extend(super::apple_base::macos_link_env_remove());

// 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 = "aarch64";
let llvm_target = super::apple_base::macos_llvm_target(&arch);
let llvm_target = super::apple_base::macos_llvm_target("arm64");

Target {
llvm_target,
pointer_width: 64,
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".to_string(),
arch: arch.to_string(),
arch: "aarch64".to_string(),
options: TargetOptions {
mcount: "\u{1}mcount".to_string(),
frame_pointer: FramePointer::NonLeaf,
Expand Down
31 changes: 25 additions & 6 deletions compiler/rustc_target/src/spec/apple_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ pub fn opts(os: &str) -> TargetOptions {
// warnings about the usage of ELF TLS.
//
// 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 version = macos_deployment_target();
// TLS is flagged as enabled if it looks to be supported. The architecture
// only matters for default deployment target which is 11.0 for ARM64 and
// 10.7 for everything else.
let has_elf_tls = macos_deployment_target("x86_64") >= (10, 7);

TargetOptions {
os: os.to_string(),
Expand All @@ -31,7 +33,7 @@ pub fn opts(os: &str) -> TargetOptions {
has_rpath: true,
dll_suffix: ".dylib".to_string(),
archive_format: "darwin".to_string(),
has_elf_tls: version >= (10, 7),
has_elf_tls,
abi_return_struct_as_int: true,
emit_debug_gdb_scripts: false,
eh_frame_header: false,
Expand Down Expand Up @@ -63,15 +65,32 @@ fn deployment_target(var_name: &str) -> Option<(u32, u32)> {
.and_then(|(a, b)| a.parse::<u32>().and_then(|a| b.parse::<u32>().map(|b| (a, b))).ok())
}

fn macos_deployment_target() -> (u32, u32) {
deployment_target("MACOSX_DEPLOYMENT_TARGET").unwrap_or((10, 7))
fn macos_default_deployment_target(arch: &str) -> (u32, u32) {
if arch == "arm64" { (11, 0) } else { (10, 7) }
}

fn macos_deployment_target(arch: &str) -> (u32, u32) {
deployment_target("MACOSX_DEPLOYMENT_TARGET")
.unwrap_or_else(|| macos_default_deployment_target(arch))
}

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

pub fn macos_link_env(arch: &str) -> Vec<(String, String)> {
// Use the default deployment target for linking just as with the LLVM target if not
// specified via MACOSX_DEPLOYMENT_TARGET, otherwise the system linker would use its
// default which varies with Xcode version.
if env::var("MACOSX_DEPLOYMENT_TARGET").is_err() {
let default = macos_default_deployment_target(arch);
vec![("MACOSX_DEPLOYMENT_TARGET".to_string(), format!("{}.{}", default.0, default.1))]
} else {
vec![]
}
}

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
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_target/src/spec/i686_apple_darwin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub fn target() -> Target {
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.extend(super::apple_base::macos_link_env("i686"));
base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub fn target() -> Target {
LinkerFlavor::Gcc,
vec!["-m64".to_string(), "-arch".to_string(), "x86_64".to_string()],
);
base.link_env.extend(super::apple_base::macos_link_env("x86_64"));
base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
base.stack_probes = StackProbeType::Call;
Expand Down

0 comments on commit 0780889

Please sign in to comment.