Rollup merge of #98771 - Thog:rust-lld-apple-target, r=petrochenkov

Add support for link-flavor rust-lld for iOS, tvOS and watchOS

This adds support for rust-lld for Apple *OS targets.

This was tested against targets ``aarch64-apple-ios`` and ``aarch64-apple-ios-sim`` with [a simple test program](https://github.com/Thog/rust-lld-apple-target_test).

It currently doesn't work with targets ``armv7-apple-ios`` and ``armv7s-apple-ios`` because of ``symbols.o`` not being generated with the correct CPU subtype. This will require changes in the ``object`` crate to expose an API.

As ``ld64.lld`` requires ``-platform_version`` with the minimal version supported and an sdk version, I made ``rustc_target::apple_base`` public to get access to ``*os_deployment_target``  helper functions and also added ``tvos_deployment_target`` as it was missing.
This commit is contained in:
Matthias Krüger 2022-08-03 22:29:25 +02:00 committed by GitHub
commit 7b0360e516
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 101 additions and 15 deletions

View File

@ -2675,7 +2675,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
let llvm_target = &sess.target.llvm_target; let llvm_target = &sess.target.llvm_target;
if sess.target.vendor != "apple" if sess.target.vendor != "apple"
|| !matches!(os.as_ref(), "ios" | "tvos" | "watchos") || !matches!(os.as_ref(), "ios" | "tvos" | "watchos")
|| flavor != LinkerFlavor::Gcc || (flavor != LinkerFlavor::Gcc && flavor != LinkerFlavor::Lld(LldFlavor::Ld64))
{ {
return; return;
} }
@ -2706,14 +2706,17 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
return; return;
} }
}; };
if llvm_target.contains("macabi") {
cmd.args(&["-target", llvm_target]) match flavor {
} else { LinkerFlavor::Gcc => {
let arch_name = llvm_target.split('-').next().expect("LLVM target must have a hyphen");
cmd.args(&["-arch", arch_name])
}
cmd.args(&["-isysroot", &sdk_root, "-Wl,-syslibroot", &sdk_root]); cmd.args(&["-isysroot", &sdk_root, "-Wl,-syslibroot", &sdk_root]);
} }
LinkerFlavor::Lld(LldFlavor::Ld64) => {
cmd.args(&["-syslibroot", &sdk_root]);
}
_ => unreachable!(),
}
}
fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> { fn get_apple_sdk_root(sdk_name: &str) -> Result<String, String> {
// Following what clang does // Following what clang does

View File

@ -1,9 +1,14 @@
use super::apple_sdk_base::{opts, Arch}; use super::apple_sdk_base::{opts, Arch};
use crate::spec::{FramePointer, Target, TargetOptions}; use crate::spec::{FramePointer, LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let llvm_target = "arm64-apple-ios14.0-macabi";
let mut base = opts("ios", Arch::Arm64_macabi);
base.add_pre_link_args(LinkerFlavor::Gcc, &["-target", llvm_target]);
Target { Target {
llvm_target: "arm64-apple-ios14.0-macabi".into(), llvm_target: llvm_target.into(),
pointer_width: 64, pointer_width: 64,
data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(), data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(),
arch: "aarch64".into(), arch: "aarch64".into(),
@ -21,7 +26,7 @@ pub fn target() -> Target {
-disable-llvm-passes\0\ -disable-llvm-passes\0\
-Os\0" -Os\0"
.into(), .into(),
..opts("ios", Arch::Arm64_macabi) ..base
}, },
} }
} }

View File

@ -109,15 +109,34 @@ pub fn ios_llvm_target(arch: &str) -> String {
format!("{}-apple-ios{}.{}.0", arch, major, minor) format!("{}-apple-ios{}.{}.0", arch, major, minor)
} }
pub fn ios_lld_platform_version() -> String {
let (major, minor) = ios_deployment_target();
format!("{}.{}", major, minor)
}
pub fn ios_sim_llvm_target(arch: &str) -> String { pub fn ios_sim_llvm_target(arch: &str) -> String {
let (major, minor) = ios_deployment_target(); let (major, minor) = ios_deployment_target();
format!("{}-apple-ios{}.{}.0-simulator", arch, major, minor) format!("{}-apple-ios{}.{}.0-simulator", arch, major, minor)
} }
fn tvos_deployment_target() -> (u32, u32) {
deployment_target("TVOS_DEPLOYMENT_TARGET").unwrap_or((7, 0))
}
pub fn tvos_lld_platform_version() -> String {
let (major, minor) = tvos_deployment_target();
format!("{}.{}", major, minor)
}
fn watchos_deployment_target() -> (u32, u32) { fn watchos_deployment_target() -> (u32, u32) {
deployment_target("WATCHOS_DEPLOYMENT_TARGET").unwrap_or((5, 0)) deployment_target("WATCHOS_DEPLOYMENT_TARGET").unwrap_or((5, 0))
} }
pub fn watchos_lld_platform_version() -> String {
let (major, minor) = watchos_deployment_target();
format!("{}.{}", major, minor)
}
pub fn watchos_sim_llvm_target(arch: &str) -> String { pub fn watchos_sim_llvm_target(arch: &str) -> String {
let (major, minor) = watchos_deployment_target(); let (major, minor) = watchos_deployment_target();
format!("{}-apple-watchos{}.{}.0-simulator", arch, major, minor) format!("{}-apple-watchos{}.{}.0-simulator", arch, major, minor)

View File

@ -1,4 +1,4 @@
use crate::{spec::cvs, spec::TargetOptions}; use crate::spec::{cvs, LinkArgs, LinkerFlavor, LldFlavor, TargetOptions};
use std::borrow::Cow; use std::borrow::Cow;
use Arch::*; use Arch::*;
@ -17,6 +17,18 @@ pub enum Arch {
Arm64_sim, Arm64_sim,
} }
fn target_arch_name(arch: Arch) -> &'static str {
match arch {
Armv7 => "armv7",
Armv7k => "armv7k",
Armv7s => "armv7s",
Arm64 | Arm64_macabi | Arm64_sim => "arm64",
Arm64_32 => "arm64_32",
I386 => "i386",
X86_64 | X86_64_macabi => "x86_64",
}
}
fn target_abi(arch: Arch) -> &'static str { fn target_abi(arch: Arch) -> &'static str {
match arch { match arch {
Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 => "", Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | X86_64 => "",
@ -49,11 +61,51 @@ 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 { pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
TargetOptions { TargetOptions {
abi: target_abi(arch).into(), abi: target_abi(arch).into(),
cpu: target_cpu(arch).into(), cpu: target_cpu(arch).into(),
dynamic_linking: false, dynamic_linking: false,
pre_link_args: pre_link_args(os, arch),
link_env_remove: link_env_remove(arch), link_env_remove: link_env_remove(arch),
has_thread_local: false, has_thread_local: false,
..super::apple_base::opts(os) ..super::apple_base::opts(os)

View File

@ -46,7 +46,10 @@ impl Target {
) )
} }
(LinkerFlavor::Gcc, LldFlavor::Ld64) => { (LinkerFlavor::Gcc, LldFlavor::Ld64) => {
assert_matches!(flavor, LinkerFlavor::Gcc) assert_matches!(
flavor,
LinkerFlavor::Lld(LldFlavor::Ld64) | LinkerFlavor::Gcc
)
} }
(LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link), LldFlavor::Link) => { (LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link), LldFlavor::Link) => {
assert_matches!( assert_matches!(

View File

@ -1,10 +1,14 @@
use super::apple_sdk_base::{opts, Arch}; use super::apple_sdk_base::{opts, Arch};
use crate::spec::{StackProbeType, Target, TargetOptions}; use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let base = opts("ios", Arch::X86_64_macabi); let llvm_target = "x86_64-apple-ios13.0-macabi";
let mut base = opts("ios", Arch::X86_64_macabi);
base.add_pre_link_args(LinkerFlavor::Gcc, &["-target", llvm_target]);
Target { Target {
llvm_target: "x86_64-apple-ios13.0-macabi".into(), llvm_target: llvm_target.into(),
pointer_width: 64, pointer_width: 64,
data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
.into(), .into(),