Rollup merge of #100286 - Thog:rust-lld-macosx-target, r=petrochenkov

Add support for link-flavor rust-lld for macOS

Also refactor iOS, watchOS and tvOS common code.

The ``-arch`` argument was moved to the ``apple_base`` module instead of the target definitions for macOS.
As ld64 requires ``-syslibroot`` to be passed, ``add_apple_sdk`` was modified accordingly.
This commit is contained in:
Michael Goulet 2022-08-10 09:28:18 -07:00 committed by GitHub
commit d0d2f60e49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 66 additions and 56 deletions

View File

@ -2674,11 +2674,16 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
let os = &sess.target.os;
let llvm_target = &sess.target.llvm_target;
if sess.target.vendor != "apple"
|| !matches!(os.as_ref(), "ios" | "tvos" | "watchos")
|| !matches!(os.as_ref(), "ios" | "tvos" | "watchos" | "macos")
|| (flavor != LinkerFlavor::Gcc && flavor != LinkerFlavor::Lld(LldFlavor::Ld64))
{
return;
}
if os == "macos" && flavor != LinkerFlavor::Lld(LldFlavor::Ld64) {
return;
}
let sdk_name = match (arch.as_ref(), os.as_ref()) {
("aarch64", "tvos") => "appletvos",
("x86_64", "tvos") => "appletvsimulator",
@ -2694,6 +2699,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
("aarch64", "watchos") if llvm_target.ends_with("-simulator") => "watchsimulator",
("aarch64", "watchos") => "watchos",
("arm", "watchos") => "watchos",
(_, "macos") => "macosx",
_ => {
sess.err(&format!("unsupported arch `{}` for os `{}`", arch, os));
return;

View File

@ -1,20 +1,20 @@
use crate::spec::{FramePointer, LinkerFlavor, SanitizerSet, Target, TargetOptions};
use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::apple_base::opts("macos");
let arch = "arm64";
let mut base = super::apple_base::opts("macos", arch, "");
base.cpu = "apple-a14".into();
base.max_atomic_width = Some(128);
// FIXME: The leak sanitizer currently fails the tests, see #88132.
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD;
base.add_pre_link_args(LinkerFlavor::Gcc, &["-arch", "arm64"]);
base.link_env_remove.to_mut().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 llvm_target = super::apple_base::macos_llvm_target("arm64");
let llvm_target = super::apple_base::macos_llvm_target(arch);
Target {
llvm_target: llvm_target.into(),

View File

@ -1,8 +1,45 @@
use std::{borrow::Cow, env};
use crate::spec::{cvs, FramePointer, LldFlavor, SplitDebuginfo, TargetOptions};
use crate::spec::{cvs, FramePointer, SplitDebuginfo, TargetOptions};
use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor};
pub fn opts(os: &'static str) -> TargetOptions {
fn pre_link_args(os: &'static str, arch: &'static str, abi: &'static str) -> LinkArgs {
let mut args = LinkArgs::new();
let platform_name = match abi {
"sim" => format!("{}-simulator", os),
"macabi" => "mac-catalyst".to_string(),
_ => os.to_string(),
};
let platform_version = match os.as_ref() {
"ios" => ios_lld_platform_version(),
"tvos" => tvos_lld_platform_version(),
"watchos" => watchos_lld_platform_version(),
"macos" => macos_lld_platform_version(arch),
_ => unreachable!(),
};
if abi != "macabi" {
args.insert(LinkerFlavor::Gcc, vec!["-arch".into(), arch.into()]);
}
args.insert(
LinkerFlavor::Lld(LldFlavor::Ld64),
vec![
"-arch".into(),
arch.into(),
"-platform_version".into(),
platform_name.into(),
platform_version.clone().into(),
platform_version.into(),
],
);
args
}
pub fn opts(os: &'static str, arch: &'static str, abi: &'static str) -> TargetOptions {
// ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6
// either the linker will complain if it is used or the binary will end up
// segfaulting at runtime when run on 10.6. Rust by default supports macOS
@ -24,6 +61,7 @@ pub fn opts(os: &'static str) -> TargetOptions {
// macOS has -dead_strip, which doesn't rely on function_sections
function_sections: false,
dynamic_linking: true,
pre_link_args: pre_link_args(os, arch, abi),
linker_is_gnu: false,
families: cvs!["unix"],
is_like_osx: true,
@ -73,6 +111,11 @@ fn macos_deployment_target(arch: &str) -> (u32, u32) {
.unwrap_or_else(|| macos_default_deployment_target(arch))
}
fn macos_lld_platform_version(arch: &str) -> String {
let (major, minor) = macos_deployment_target(arch);
format!("{}.{}", major, minor)
}
pub fn macos_llvm_target(arch: &str) -> String {
let (major, minor) = macos_deployment_target(arch);
format!("{}-apple-macosx{}.{}.0", arch, major, minor)
@ -109,7 +152,7 @@ pub fn ios_llvm_target(arch: &str) -> String {
format!("{}-apple-ios{}.{}.0", arch, major, minor)
}
pub fn ios_lld_platform_version() -> String {
fn ios_lld_platform_version() -> String {
let (major, minor) = ios_deployment_target();
format!("{}.{}", major, minor)
}
@ -123,7 +166,7 @@ fn tvos_deployment_target() -> (u32, u32) {
deployment_target("TVOS_DEPLOYMENT_TARGET").unwrap_or((7, 0))
}
pub fn tvos_lld_platform_version() -> String {
fn tvos_lld_platform_version() -> String {
let (major, minor) = tvos_deployment_target();
format!("{}.{}", major, minor)
}
@ -132,7 +175,7 @@ fn watchos_deployment_target() -> (u32, u32) {
deployment_target("WATCHOS_DEPLOYMENT_TARGET").unwrap_or((5, 0))
}
pub fn watchos_lld_platform_version() -> String {
fn watchos_lld_platform_version() -> String {
let (major, minor) = watchos_deployment_target();
format!("{}.{}", major, minor)
}

View File

@ -1,4 +1,4 @@
use crate::spec::{cvs, LinkArgs, LinkerFlavor, LldFlavor, TargetOptions};
use crate::spec::{cvs, TargetOptions};
use std::borrow::Cow;
use Arch::*;
@ -61,53 +61,13 @@ fn link_env_remove(arch: Arch) -> Cow<'static, [Cow<'static, str>]> {
}
}
fn pre_link_args(os: &'static str, arch: Arch) -> LinkArgs {
let mut args = LinkArgs::new();
let target_abi = target_abi(arch);
let platform_name = match target_abi {
"sim" => format!("{}-simulator", os),
"macabi" => "mac-catalyst".to_string(),
_ => os.to_string(),
};
let platform_version = match os.as_ref() {
"ios" => super::apple_base::ios_lld_platform_version(),
"tvos" => super::apple_base::tvos_lld_platform_version(),
"watchos" => super::apple_base::watchos_lld_platform_version(),
_ => unreachable!(),
};
let arch_str = target_arch_name(arch);
if target_abi != "macabi" {
args.insert(LinkerFlavor::Gcc, vec!["-arch".into(), arch_str.into()]);
}
args.insert(
LinkerFlavor::Lld(LldFlavor::Ld64),
vec![
"-arch".into(),
arch_str.into(),
"-platform_version".into(),
platform_name.into(),
platform_version.clone().into(),
platform_version.into(),
],
);
args
}
pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
TargetOptions {
abi: target_abi(arch).into(),
cpu: target_cpu(arch).into(),
dynamic_linking: false,
pre_link_args: pre_link_args(os, arch),
link_env_remove: link_env_remove(arch),
has_thread_local: false,
..super::apple_base::opts(os)
..super::apple_base::opts(os, target_arch_name(arch), target_abi(arch))
}
}

View File

@ -1,7 +1,8 @@
use crate::spec::{FramePointer, LinkerFlavor, StackProbeType, Target, TargetOptions};
pub fn target() -> Target {
let mut base = super::apple_base::opts("macos");
// ld64 only understand i386 and not i686
let mut base = super::apple_base::opts("macos", "i386", "");
base.cpu = "yonah".into();
base.max_atomic_width = Some(64);
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]);

View File

@ -2,11 +2,12 @@ use crate::spec::TargetOptions;
use crate::spec::{FramePointer, LinkerFlavor, SanitizerSet, StackProbeType, Target};
pub fn target() -> Target {
let mut base = super::apple_base::opts("macos");
let arch = "x86_64";
let mut base = super::apple_base::opts("macos", arch, "");
base.cpu = "core2".into();
base.max_atomic_width = Some(128); // core2 support cmpxchg16b
base.frame_pointer = FramePointer::Always;
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64", "-arch", "x86_64"]);
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]);
base.link_env_remove.to_mut().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;
@ -16,7 +17,6 @@ pub fn target() -> Target {
// 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);
Target {