diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 13a7b6be947ec..8197872bf30a4 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -2675,7 +2675,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { let llvm_target = &sess.target.llvm_target; if sess.target.vendor != "apple" || !matches!(os.as_ref(), "ios" | "tvos" | "watchos") - || flavor != LinkerFlavor::Gcc + || (flavor != LinkerFlavor::Gcc && flavor != LinkerFlavor::Lld(LldFlavor::Ld64)) { return; } @@ -2706,13 +2706,16 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { return; } }; - if llvm_target.contains("macabi") { - cmd.args(&["-target", llvm_target]) - } else { - let arch_name = llvm_target.split('-').next().expect("LLVM target must have a hyphen"); - cmd.args(&["-arch", arch_name]) + + match flavor { + LinkerFlavor::Gcc => { + cmd.args(&["-isysroot", &sdk_root, "-Wl,-syslibroot", &sdk_root]); + } + LinkerFlavor::Lld(LldFlavor::Ld64) => { + cmd.args(&["-syslibroot", &sdk_root]); + } + _ => unreachable!(), } - cmd.args(&["-isysroot", &sdk_root, "-Wl,-syslibroot", &sdk_root]); } fn get_apple_sdk_root(sdk_name: &str) -> Result { diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs index 57634cbbfb1e3..1dad07a9a42a4 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs @@ -1,9 +1,14 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{FramePointer, Target, TargetOptions}; +use crate::spec::{FramePointer, LinkerFlavor, Target, TargetOptions}; 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 { - llvm_target: "arm64-apple-ios14.0-macabi".into(), + llvm_target: llvm_target.into(), pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(), arch: "aarch64".into(), @@ -21,7 +26,7 @@ pub fn target() -> Target { -disable-llvm-passes\0\ -Os\0" .into(), - ..opts("ios", Arch::Arm64_macabi) + ..base }, } } diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index 9bfae46ef32d2..15e4fb9be6303 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -109,15 +109,34 @@ pub fn ios_llvm_target(arch: &str) -> String { 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 { let (major, minor) = ios_deployment_target(); 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) { 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 { let (major, minor) = watchos_deployment_target(); format!("{}-apple-watchos{}.{}.0-simulator", arch, major, minor) diff --git a/compiler/rustc_target/src/spec/apple_sdk_base.rs b/compiler/rustc_target/src/spec/apple_sdk_base.rs index 0328ea98c48cb..d77558f0f8429 100644 --- a/compiler/rustc_target/src/spec/apple_sdk_base.rs +++ b/compiler/rustc_target/src/spec/apple_sdk_base.rs @@ -1,4 +1,4 @@ -use crate::{spec::cvs, spec::TargetOptions}; +use crate::spec::{cvs, LinkArgs, LinkerFlavor, LldFlavor, TargetOptions}; use std::borrow::Cow; use Arch::*; @@ -17,6 +17,18 @@ pub enum Arch { 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 { match arch { 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 { 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) diff --git a/compiler/rustc_target/src/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs index c7c5a23190102..1db6db78b17e4 100644 --- a/compiler/rustc_target/src/spec/tests/tests_impl.rs +++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs @@ -46,7 +46,10 @@ impl Target { ) } (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) => { assert_matches!( diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs index c75632571ad38..2122bcd37fc07 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs @@ -1,10 +1,14 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{StackProbeType, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; 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 { - llvm_target: "x86_64-apple-ios13.0-macabi".into(), + llvm_target: llvm_target.into(), 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" .into(),