diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index ecc91ab9a310e..2962b0ab61e7f 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -12,11 +12,13 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(assert_matches)] +#![feature(fn_traits)] #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(min_exhaustive_patterns)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] +#![feature(unboxed_closures)] // tidy-alphabetical-end use std::path::{Path, PathBuf}; diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index 055420090835d..391ec6078c27b 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -1,6 +1,7 @@ use std::{borrow::Cow, env}; -use crate::spec::{add_link_args, add_link_args_iter}; +use crate::spec::link_args::LazyLinkArgsState; +use crate::spec::{add_link_args, add_link_args_iter, MaybeLazy}; use crate::spec::{cvs, Cc, DebuginfoKind, FramePointer, LinkArgs, LinkerFlavor, Lld}; use crate::spec::{SplitDebuginfo, StackProbeType, StaticCow, Target, TargetOptions}; @@ -94,7 +95,10 @@ impl TargetAbi { } } -fn pre_link_args(os: &'static str, arch: Arch, abi: TargetAbi) -> LinkArgs { +pub(crate) type ApplePreLinkArgs = + (/*os:*/ &'static str, /*arch:*/ Arch, /*abi:*/ TargetAbi); + +pub(crate) fn pre_link_args((os, arch, abi): ApplePreLinkArgs) -> LinkArgs { let platform_name: StaticCow = match abi { TargetAbi::Normal => os.into(), TargetAbi::Simulator => format!("{os}-simulator").into(), @@ -114,7 +118,9 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: TargetAbi) -> LinkArgs { }; let sdk_version = min_version.clone(); - let mut args = TargetOptions::link_args( + let mut args = LinkArgs::new(); + add_link_args( + &mut args, LinkerFlavor::Darwin(Cc::No, Lld::No), &["-arch", arch.target_name(), "-platform_version"], ); @@ -151,7 +157,7 @@ pub fn opts(os: &'static str, arch: Arch, abi: TargetAbi) -> 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), + pre_link_args: MaybeLazy::lazied(LazyLinkArgsState::Apple((os, arch, abi))), families: cvs!["unix"], is_like_osx: true, // LLVM notes that macOS 10.11+ and iOS 9+ default diff --git a/compiler/rustc_target/src/spec/base/avr_gnu.rs b/compiler/rustc_target/src/spec/base/avr_gnu.rs index 211d52f5b07ed..27bc5a1c9ea8a 100644 --- a/compiler/rustc_target/src/spec/base/avr_gnu.rs +++ b/compiler/rustc_target/src/spec/base/avr_gnu.rs @@ -4,8 +4,7 @@ use object::elf; /// A base target for AVR devices using the GNU toolchain. /// /// Requires GNU avr-gcc and avr-binutils on the host system. -/// FIXME: Remove the second parameter when const string concatenation is possible. -pub fn target(target_cpu: &'static str, mmcu: &'static str) -> Target { +pub fn target(target_cpu: &'static str) -> Target { Target { arch: "avr".into(), metadata: crate::spec::TargetMetadata { @@ -24,7 +23,10 @@ pub fn target(target_cpu: &'static str, mmcu: &'static str) -> Target { linker: Some("avr-gcc".into()), eh_frame_header: false, - pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[mmcu]), + pre_link_args: TargetOptions::link_args( + LinkerFlavor::Gnu(Cc::Yes, Lld::No), + &["-mmcu=atmega328"], + ), late_link_args: TargetOptions::link_args( LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-lgcc"], diff --git a/compiler/rustc_target/src/spec/base/teeos.rs b/compiler/rustc_target/src/spec/base/teeos.rs index 38d0a6d73140a..d50cf9c0db419 100644 --- a/compiler/rustc_target/src/spec/base/teeos.rs +++ b/compiler/rustc_target/src/spec/base/teeos.rs @@ -1,11 +1,15 @@ -use crate::spec::{add_link_args, Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, TargetOptions}; pub fn opts() -> TargetOptions { - let lld_args = &["-zmax-page-size=4096", "-znow", "-ztext", "--execute-only"]; - let cc_args = &["-Wl,-zmax-page-size=4096", "-Wl,-znow", "-Wl,-ztext", "-mexecute-only"]; - - let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), lld_args); - add_link_args(&mut pre_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), cc_args); + let pre_link_args = { + const LLD_ARGS: &[&str] = &["-zmax-page-size=4096", "-znow", "-ztext", "--execute-only"]; + const CC_ARGS: &[&str] = + &["-Wl,-zmax-page-size=4096", "-Wl,-znow", "-Wl,-ztext", "-mexecute-only"]; + TargetOptions::link_args_list(&[ + (LinkerFlavor::Gnu(Cc::No, Lld::No), LLD_ARGS), + (LinkerFlavor::Gnu(Cc::Yes, Lld::No), CC_ARGS), + ]) + }; TargetOptions { os: "teeos".into(), diff --git a/compiler/rustc_target/src/spec/base/uefi_msvc.rs b/compiler/rustc_target/src/spec/base/uefi_msvc.rs index e8acd6078e2ad..8d908144d58c2 100644 --- a/compiler/rustc_target/src/spec/base/uefi_msvc.rs +++ b/compiler/rustc_target/src/spec/base/uefi_msvc.rs @@ -9,12 +9,13 @@ // the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all // code runs in the same environment, no process separation is supported. -use crate::spec::{base, LinkerFlavor, Lld, PanicStrategy, StackProbeType, TargetOptions}; +use crate::spec::{base, LinkerFlavor, Lld}; +use crate::spec::{PanicStrategy, StackProbeType, TargetOptions}; pub fn opts() -> TargetOptions { let mut base = base::msvc::opts(); - base.add_pre_link_args( + base.pre_link_args = TargetOptions::link_args( LinkerFlavor::Msvc(Lld::No), &[ // Non-standard subsystems have no default entry-point in PE+ files. We have to define diff --git a/compiler/rustc_target/src/spec/base/wasm.rs b/compiler/rustc_target/src/spec/base/wasm.rs index f237391016e77..26d795834fb0b 100644 --- a/compiler/rustc_target/src/spec/base/wasm.rs +++ b/compiler/rustc_target/src/spec/base/wasm.rs @@ -1,7 +1,5 @@ -use crate::spec::{ - add_link_args, cvs, Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy, RelocModel, - TargetOptions, TlsModel, -}; +use crate::spec::{cvs, Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy}; +use crate::spec::{RelocModel, TargetOptions, TlsModel}; pub fn options() -> TargetOptions { macro_rules! args { @@ -48,8 +46,10 @@ pub fn options() -> TargetOptions { }; } - let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::WasmLld(Cc::No), args!("")); - add_link_args(&mut pre_link_args, LinkerFlavor::WasmLld(Cc::Yes), args!("-Wl,")); + let pre_link_args = TargetOptions::link_args_list(&[ + (LinkerFlavor::WasmLld(Cc::No), args!("")), + (LinkerFlavor::WasmLld(Cc::Yes), args!("-Wl,")), + ]); TargetOptions { is_like_wasm: true, diff --git a/compiler/rustc_target/src/spec/base/windows_gnu.rs b/compiler/rustc_target/src/spec/base/windows_gnu.rs index 1357de2dad126..4d8e2c361db59 100644 --- a/compiler/rustc_target/src/spec/base/windows_gnu.rs +++ b/compiler/rustc_target/src/spec/base/windows_gnu.rs @@ -1,78 +1,80 @@ +use crate::spec::crt_objects; use crate::spec::LinkSelfContainedDefault; -use crate::spec::{add_link_args, crt_objects}; use crate::spec::{cvs, Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions}; use std::borrow::Cow; pub fn opts() -> TargetOptions { - let mut pre_link_args = TargetOptions::link_args( - LinkerFlavor::Gnu(Cc::No, Lld::No), - &[ - // Enable ASLR - "--dynamicbase", - // ASLR will rebase it anyway so leaving that option enabled only leads to confusion - "--disable-auto-image-base", - ], - ); - add_link_args( - &mut pre_link_args, - LinkerFlavor::Gnu(Cc::Yes, Lld::No), - &[ - // Tell GCC to avoid linker plugins, because we are not bundling - // them with Windows installer, and Rust does its own LTO anyways. - "-fno-use-linker-plugin", - "-Wl,--dynamicbase", - "-Wl,--disable-auto-image-base", - ], - ); + let pre_link_args = TargetOptions::link_args_list(&[ + ( + LinkerFlavor::Gnu(Cc::No, Lld::No), + &[ + // Enable ASLR + "--dynamicbase", + // ASLR will rebase it anyway so leaving that option enabled only leads to confusion + "--disable-auto-image-base", + ], + ), + ( + LinkerFlavor::Gnu(Cc::Yes, Lld::No), + &[ + // Tell GCC to avoid linker plugins, because we are not bundling + // them with Windows installer, and Rust does its own LTO anyways. + "-fno-use-linker-plugin", + "-Wl,--dynamicbase", + "-Wl,--disable-auto-image-base", + ], + ), + ]); - // Order of `late_link_args*` was found through trial and error to work with various - // mingw-w64 versions (not tested on the CI). It's expected to change from time to time. - let mingw_libs = &[ - "-lmsvcrt", - "-lmingwex", - "-lmingw32", - "-lgcc", // alas, mingw* libraries above depend on libgcc - // mingw's msvcrt is a weird hybrid import library and static library. - // And it seems that the linker fails to use import symbols from msvcrt - // that are required from functions in msvcrt in certain cases. For example - // `_fmode` that is used by an implementation of `__p__fmode` in x86_64. - // The library is purposely listed twice to fix that. - // - // See https://github.com/rust-lang/rust/pull/47483 for some more details. - "-lmsvcrt", - // Math functions missing in MSVCRT (they are present in UCRT) require - // this dependency cycle: `libmingwex.a` -> `libmsvcrt.a` -> `libmingwex.a`. - "-lmingwex", - "-luser32", - "-lkernel32", - ]; - let mut late_link_args = - TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs); - add_link_args(&mut late_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), mingw_libs); + let late_link_args = { + // Order of `late_link_args*` was found through trial and error to work with various + // mingw-w64 versions (not tested on the CI). It's expected to change from time to time. + const MINGW_LIBS: &[&str] = &[ + "-lmsvcrt", + "-lmingwex", + "-lmingw32", + "-lgcc", // alas, mingw* libraries above depend on libgcc + // mingw's msvcrt is a weird hybrid import library and static library. + // And it seems that the linker fails to use import symbols from msvcrt + // that are required from functions in msvcrt in certain cases. For example + // `_fmode` that is used by an implementation of `__p__fmode` in x86_64. + // The library is purposely listed twice to fix that. + // + // See https://github.com/rust-lang/rust/pull/47483 for some more details. + "-lmsvcrt", + // Math functions missing in MSVCRT (they are present in UCRT) require + // this dependency cycle: `libmingwex.a` -> `libmsvcrt.a` -> `libmingwex.a`. + "-lmingwex", + "-luser32", + "-lkernel32", + ]; + TargetOptions::link_args_list(&[ + (LinkerFlavor::Gnu(Cc::No, Lld::No), MINGW_LIBS), + (LinkerFlavor::Gnu(Cc::Yes, Lld::No), MINGW_LIBS), + ]) + }; // If any of our crates are dynamically linked then we need to use // the shared libgcc_s-dw2-1.dll. This is required to support // unwinding across DLL boundaries. - let dynamic_unwind_libs = &["-lgcc_s"]; - let mut late_link_args_dynamic = - TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), dynamic_unwind_libs); - add_link_args( - &mut late_link_args_dynamic, - LinkerFlavor::Gnu(Cc::Yes, Lld::No), - dynamic_unwind_libs, - ); + let late_link_args_dynamic = { + const DYNAMIC_UNWIND_LIBS: &[&str] = &["-lgcc_s"]; + TargetOptions::link_args_list(&[ + (LinkerFlavor::Gnu(Cc::No, Lld::No), DYNAMIC_UNWIND_LIBS), + (LinkerFlavor::Gnu(Cc::Yes, Lld::No), DYNAMIC_UNWIND_LIBS), + ]) + }; // If all of our crates are statically linked then we can get away // with statically linking the libgcc unwinding code. This allows // binaries to be redistributed without the libgcc_s-dw2-1.dll // dependency, but unfortunately break unwinding across DLL // boundaries when unwinding across FFI boundaries. - let static_unwind_libs = &["-lgcc_eh", "-l:libpthread.a"]; - let mut late_link_args_static = - TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), static_unwind_libs); - add_link_args( - &mut late_link_args_static, - LinkerFlavor::Gnu(Cc::Yes, Lld::No), - static_unwind_libs, - ); + let late_link_args_static = { + const STATIC_UNWIND_LIBS: &[&str] = &["-lgcc_eh", "-l:libpthread.a"]; + TargetOptions::link_args_list(&[ + (LinkerFlavor::Gnu(Cc::No, Lld::No), STATIC_UNWIND_LIBS), + (LinkerFlavor::Gnu(Cc::Yes, Lld::No), STATIC_UNWIND_LIBS), + ]) + }; TargetOptions { os: "windows".into(), diff --git a/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs b/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs index 17256e18e24e3..a6bd247cf606f 100644 --- a/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs +++ b/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs @@ -1,26 +1,29 @@ -use crate::spec::{add_link_args, base, Cc, LinkArgs, LinkerFlavor, Lld, TargetOptions}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, TargetOptions}; pub fn opts() -> TargetOptions { let base = base::windows_gnu::opts(); - // FIXME: This should be updated for the exception machinery changes from #67502 - // and inherit from `windows_gnu_base`, at least partially. - let mingw_libs = &[ - "-lwinstorecompat", - "-lruntimeobject", - "-lsynchronization", - "-lvcruntime140_app", - "-lucrt", - "-lwindowsapp", - "-lmingwex", - "-lmingw32", - ]; - let mut late_link_args = - TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs); - add_link_args(&mut late_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), mingw_libs); + let late_link_args = { + // FIXME: This should be updated for the exception machinery changes from #67502 + // and inherit from `windows_gnu_base`, at least partially. + const MINGW_LIBS: &[&str] = &[ + "-lwinstorecompat", + "-lruntimeobject", + "-lsynchronization", + "-lvcruntime140_app", + "-lucrt", + "-lwindowsapp", + "-lmingwex", + "-lmingw32", + ]; + TargetOptions::link_args_list(&[ + (LinkerFlavor::Gnu(Cc::No, Lld::No), MINGW_LIBS), + (LinkerFlavor::Gnu(Cc::Yes, Lld::No), MINGW_LIBS), + ]) + }; // Reset the flags back to empty until the FIXME above is addressed. - let late_link_args_dynamic = LinkArgs::new(); - let late_link_args_static = LinkArgs::new(); + let late_link_args_dynamic = Default::default(); + let late_link_args_static = Default::default(); TargetOptions { abi: "uwp".into(), diff --git a/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs b/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs index 59a7616712541..a4140f4ea4fe7 100644 --- a/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs +++ b/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs @@ -5,7 +5,8 @@ pub fn opts() -> TargetOptions { opts.abi = "uwp".into(); opts.vendor = "uwp".into(); - opts.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &["/APPCONTAINER", "mincore.lib"]); + opts.pre_link_args = + TargetOptions::link_args(LinkerFlavor::Msvc(Lld::No), &["/APPCONTAINER", "mincore.lib"]); opts } diff --git a/compiler/rustc_target/src/spec/crt_objects.rs b/compiler/rustc_target/src/spec/crt_objects.rs index 53f710b8f9e14..c542c690e8f72 100644 --- a/compiler/rustc_target/src/spec/crt_objects.rs +++ b/compiler/rustc_target/src/spec/crt_objects.rs @@ -40,28 +40,42 @@ //! but not gcc's. As a result rustc cannot link with C++ static libraries (#36710) //! when linking in self-contained mode. -use crate::spec::LinkOutputKind; +use crate::spec::{LinkOutputKind, MaybeLazy}; use std::borrow::Cow; use std::collections::BTreeMap; +type LazyCrtObjectsArgs = &'static [(LinkOutputKind, &'static [&'static str])]; +pub struct LazyCrtObjectsState(LazyCrtObjectsArgs); + +impl FnOnce<()> for LazyCrtObjectsState { + type Output = CrtObjects; + extern "rust-call" fn call_once(self, _args: ()) -> Self::Output { + self.0.iter().map(|(z, k)| (*z, k.iter().map(|b| (*b).into()).collect())).collect() + } +} + pub type CrtObjects = BTreeMap>>; +pub type LazyCrtObjects = MaybeLazy; -pub(super) fn new(obj_table: &[(LinkOutputKind, &[&'static str])]) -> CrtObjects { - obj_table.iter().map(|(z, k)| (*z, k.iter().map(|b| (*b).into()).collect())).collect() +#[inline] +pub(super) fn new(obj_table: LazyCrtObjectsArgs) -> LazyCrtObjects { + MaybeLazy::lazied(LazyCrtObjectsState(obj_table)) } -pub(super) fn all(obj: &'static str) -> CrtObjects { - new(&[ - (LinkOutputKind::DynamicNoPicExe, &[obj]), - (LinkOutputKind::DynamicPicExe, &[obj]), - (LinkOutputKind::StaticNoPicExe, &[obj]), - (LinkOutputKind::StaticPicExe, &[obj]), - (LinkOutputKind::DynamicDylib, &[obj]), - (LinkOutputKind::StaticDylib, &[obj]), - ]) +macro_rules! all { + ($obj: literal) => { + new(&[ + (LinkOutputKind::DynamicNoPicExe, &[$obj]), + (LinkOutputKind::DynamicPicExe, &[$obj]), + (LinkOutputKind::StaticNoPicExe, &[$obj]), + (LinkOutputKind::StaticPicExe, &[$obj]), + (LinkOutputKind::DynamicDylib, &[$obj]), + (LinkOutputKind::StaticDylib, &[$obj]), + ]) + }; } -pub(super) fn pre_musl_self_contained() -> CrtObjects { +pub(super) fn pre_musl_self_contained() -> LazyCrtObjects { new(&[ (LinkOutputKind::DynamicNoPicExe, &["crt1.o", "crti.o", "crtbegin.o"]), (LinkOutputKind::DynamicPicExe, &["Scrt1.o", "crti.o", "crtbeginS.o"]), @@ -72,7 +86,7 @@ pub(super) fn pre_musl_self_contained() -> CrtObjects { ]) } -pub(super) fn post_musl_self_contained() -> CrtObjects { +pub(super) fn post_musl_self_contained() -> LazyCrtObjects { new(&[ (LinkOutputKind::DynamicNoPicExe, &["crtend.o", "crtn.o"]), (LinkOutputKind::DynamicPicExe, &["crtendS.o", "crtn.o"]), @@ -83,7 +97,7 @@ pub(super) fn post_musl_self_contained() -> CrtObjects { ]) } -pub(super) fn pre_mingw_self_contained() -> CrtObjects { +pub(super) fn pre_mingw_self_contained() -> LazyCrtObjects { new(&[ (LinkOutputKind::DynamicNoPicExe, &["crt2.o", "rsbegin.o"]), (LinkOutputKind::DynamicPicExe, &["crt2.o", "rsbegin.o"]), @@ -94,19 +108,19 @@ pub(super) fn pre_mingw_self_contained() -> CrtObjects { ]) } -pub(super) fn post_mingw_self_contained() -> CrtObjects { - all("rsend.o") +pub(super) fn post_mingw_self_contained() -> LazyCrtObjects { + all!("rsend.o") } -pub(super) fn pre_mingw() -> CrtObjects { - all("rsbegin.o") +pub(super) fn pre_mingw() -> LazyCrtObjects { + all!("rsbegin.o") } -pub(super) fn post_mingw() -> CrtObjects { - all("rsend.o") +pub(super) fn post_mingw() -> LazyCrtObjects { + all!("rsend.o") } -pub(super) fn pre_wasi_self_contained() -> CrtObjects { +pub(super) fn pre_wasi_self_contained() -> LazyCrtObjects { // Use crt1-command.o instead of crt1.o to enable support for new-style // commands. See https://reviews.llvm.org/D81689 for more info. new(&[ @@ -118,6 +132,6 @@ pub(super) fn pre_wasi_self_contained() -> CrtObjects { ]) } -pub(super) fn post_wasi_self_contained() -> CrtObjects { +pub(super) fn post_wasi_self_contained() -> LazyCrtObjects { new(&[]) } diff --git a/compiler/rustc_target/src/spec/link_args.rs b/compiler/rustc_target/src/spec/link_args.rs new file mode 100644 index 0000000000000..53233ebfa593d --- /dev/null +++ b/compiler/rustc_target/src/spec/link_args.rs @@ -0,0 +1,41 @@ +//! Linker arguments + +use crate::spec::add_link_args; +use crate::spec::{LinkerFlavor, LinkerFlavorCli}; +use crate::spec::{MaybeLazy, StaticCow}; + +use std::collections::BTreeMap; + +pub type LinkArgs = BTreeMap>>; +pub type LinkArgsCli = BTreeMap>>; + +pub type LazyLinkArgs = MaybeLazy; + +pub enum LazyLinkArgsState { + Simple(LinkerFlavor, &'static [&'static str]), + List(&'static [(LinkerFlavor, &'static [&'static str])]), + Apple(super::base::apple::ApplePreLinkArgs), +} + +impl FnOnce<()> for LazyLinkArgsState { + type Output = LinkArgs; + + #[inline] + extern "rust-call" fn call_once(self, _args: ()) -> Self::Output { + match self { + LazyLinkArgsState::Simple(flavor, args) => { + let mut link_args = LinkArgs::new(); + add_link_args(&mut link_args, flavor, args); + link_args + } + LazyLinkArgsState::List(l) => { + let mut link_args = LinkArgs::new(); + for (flavor, args) in l { + add_link_args(&mut link_args, *flavor, args) + } + link_args + } + LazyLinkArgsState::Apple(args) => super::base::apple::pre_link_args(args), + } + } +} diff --git a/compiler/rustc_target/src/spec/maybe_lazy.rs b/compiler/rustc_target/src/spec/maybe_lazy.rs new file mode 100644 index 0000000000000..3694679b01f1c --- /dev/null +++ b/compiler/rustc_target/src/spec/maybe_lazy.rs @@ -0,0 +1,144 @@ +//! A custom LazyLock+Cow suitable for holding borrowed, owned or lazy data. + +use std::borrow::{Borrow, Cow}; +use std::fmt::{Debug, Display}; +use std::ops::Deref; +use std::sync::LazyLock; + +enum MaybeLazyInner { + Lazy(LazyLock), + Cow(Cow<'static, T>), +} + +/// A custom LazyLock+Cow suitable for holding borrowed, owned or lazy data. +/// +/// Technically this structure has 3 states: borrowed, owned and lazy +/// They can all be constructed from the [`MaybeLazy::borrowed`], [`MaybeLazy::owned`] and +/// [`MaybeLazy::lazy`] methods. +#[repr(transparent)] +pub struct MaybeLazy ::Owned> { + // Inner state. + // + // Not to be inlined since we may want in the future to + // make this struct usable to statics and we might need to + // workaround const-eval limitation (particulary around drop). + inner: MaybeLazyInner, +} + +impl T::Owned> MaybeLazy { + /// Create a [`MaybeLazy`] from an borrowed `T`. + #[inline] + pub const fn borrowed(a: &'static T) -> Self { + MaybeLazy { inner: MaybeLazyInner::Cow(Cow::Borrowed(a)) } + } + + /// Create a [`MaybeLazy`] from an borrowed `T`. + #[inline] + pub const fn owned(a: T::Owned) -> Self { + MaybeLazy { inner: MaybeLazyInner::Cow(Cow::Owned(a)) } + } + + /// Create a [`MaybeLazy`] from a function-able `F`. + #[inline] + pub const fn lazied(f: F) -> Self { + MaybeLazy { inner: MaybeLazyInner::Lazy(LazyLock::new(f)) } + } +} + +impl MaybeLazy { + /// Create a [`MaybeLazy`] from a function pointer. + #[inline] + pub const fn lazy(a: fn() -> T::Owned) -> Self { + Self::lazied(a) + } +} + +impl, F: FnOnce() -> T::Owned> Clone + for MaybeLazy +{ + #[inline] + fn clone(&self) -> Self { + MaybeLazy { + inner: MaybeLazyInner::Cow(match &self.inner { + MaybeLazyInner::Lazy(f) => Cow::Owned((*f).to_owned()), + MaybeLazyInner::Cow(c) => c.clone(), + }), + } + } +} + +impl, F: FnOnce() -> T::Owned> Default + for MaybeLazy +{ + #[inline] + fn default() -> MaybeLazy { + MaybeLazy::owned(T::Owned::default()) + } +} + +// `Debug`, `Display` and other traits below are implemented in terms of this `Deref` +impl>, F: FnOnce() -> T::Owned> Deref + for MaybeLazy +{ + type Target = T; + + #[inline] + fn deref(&self) -> &T { + match &self.inner { + MaybeLazyInner::Lazy(f) => (&**f).borrow(), + MaybeLazyInner::Cow(c) => &*c, + } + } +} + +impl + Debug, F: FnOnce() -> T::Owned> Debug + for MaybeLazy +{ + #[inline] + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Debug::fmt(&**self, fmt) + } +} + +impl + Display, F: FnOnce() -> T::Owned> Display + for MaybeLazy +{ + #[inline] + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Display::fmt(&**self, fmt) + } +} + +impl T::Owned> AsRef for MaybeLazy { + #[inline] + fn as_ref(&self) -> &T { + &**self + } +} + +impl< + T1: ?Sized + PartialEq + ToOwned, + T2: ?Sized + ToOwned, + F1: FnOnce() -> T1::Owned, + F2: FnOnce() -> T2::Owned, +> PartialEq> for MaybeLazy +{ + #[inline] + fn eq(&self, other: &MaybeLazy) -> bool { + PartialEq::eq(&**self, &**other) + } +} + +impl String> PartialEq<&str> for MaybeLazy { + #[inline] + fn eq(&self, other: &&str) -> bool { + &**self == *other + } +} + +impl String> From<&'static str> for MaybeLazy { + #[inline] + fn from(s: &'static str) -> MaybeLazy { + MaybeLazy::borrowed(s) + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 42860b1059ed7..19b58d4c7f726 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -38,7 +38,8 @@ use crate::abi::call::Conv; use crate::abi::{Endian, Integer, Size, TargetDataLayout, TargetDataLayoutErrors}; use crate::json::{Json, ToJson}; use crate::spec::abi::Abi; -use crate::spec::crt_objects::CrtObjects; +use crate::spec::crt_objects::{CrtObjects, LazyCrtObjects}; +use crate::spec::link_args::{LazyLinkArgs, LinkArgs, LinkArgsCli}; use rustc_fs_util::try_canonicalize; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; @@ -55,6 +56,8 @@ use tracing::debug; pub mod abi; pub mod crt_objects; +pub mod link_args; +pub mod maybe_lazy; mod base; pub use base::apple::deployment_target as current_apple_deployment_target; @@ -62,6 +65,8 @@ pub use base::apple::platform as current_apple_platform; pub use base::apple::sdk_version as current_apple_sdk_version; pub use base::avr_gnu::ef_avr_arch; +use maybe_lazy::MaybeLazy; + /// Linker is called through a C/C++ compiler. #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] pub enum Cc { @@ -1102,9 +1107,6 @@ impl fmt::Display for LinkOutputKind { } } -pub type LinkArgs = BTreeMap>>; -pub type LinkArgsCli = BTreeMap>>; - /// Which kind of debuginfo does the target use? /// /// Useful in determining whether a target supports Split DWARF (a target with @@ -1879,7 +1881,7 @@ impl TargetWarnings { #[derive(PartialEq, Clone, Debug)] pub struct Target { /// Target triple to pass to LLVM. - pub llvm_target: StaticCow, + pub llvm_target: MaybeLazy, /// Metadata about a target, for example the description or tier. /// Used for generating target documentation. pub metadata: TargetMetadata, @@ -2014,34 +2016,34 @@ pub struct TargetOptions { linker_is_gnu_json: bool, /// Objects to link before and after all other object code. - pub pre_link_objects: CrtObjects, - pub post_link_objects: CrtObjects, + pub pre_link_objects: LazyCrtObjects, + pub post_link_objects: LazyCrtObjects, /// Same as `(pre|post)_link_objects`, but when self-contained linking mode is enabled. - pub pre_link_objects_self_contained: CrtObjects, - pub post_link_objects_self_contained: CrtObjects, + pub pre_link_objects_self_contained: LazyCrtObjects, + pub post_link_objects_self_contained: LazyCrtObjects, /// Behavior for the self-contained linking mode: inferred for some targets, or explicitly /// enabled (in bulk, or with individual components). pub link_self_contained: LinkSelfContainedDefault, /// Linker arguments that are passed *before* any user-defined libraries. - pub pre_link_args: LinkArgs, + pub pre_link_args: LazyLinkArgs, pre_link_args_json: LinkArgsCli, /// Linker arguments that are unconditionally passed after any /// user-defined but before post-link objects. Standard platform /// libraries that should be always be linked to, usually go here. - pub late_link_args: LinkArgs, + pub late_link_args: LazyLinkArgs, late_link_args_json: LinkArgsCli, /// Linker arguments used in addition to `late_link_args` if at least one /// Rust dependency is dynamically linked. - pub late_link_args_dynamic: LinkArgs, + pub late_link_args_dynamic: LazyLinkArgs, late_link_args_dynamic_json: LinkArgsCli, /// Linker arguments used in addition to `late_link_args` if all Rust /// dependencies are statically linked. - pub late_link_args_static: LinkArgs, + pub late_link_args_static: LazyLinkArgs, late_link_args_static_json: LinkArgsCli, /// Linker arguments that are unconditionally passed *after* any /// user-defined libraries. - pub post_link_args: LinkArgs, + pub post_link_args: LazyLinkArgs, post_link_args_json: LinkArgsCli, /// Optional link script applied to `dylib` and `executable` crate types. @@ -2388,14 +2390,14 @@ fn add_link_args(link_args: &mut LinkArgs, flavor: LinkerFlavor, args: &[&'stati } impl TargetOptions { - fn link_args(flavor: LinkerFlavor, args: &[&'static str]) -> LinkArgs { - let mut link_args = LinkArgs::new(); - add_link_args(&mut link_args, flavor, args); - link_args + #[inline] + fn link_args(flavor: LinkerFlavor, args: &'static [&'static str]) -> LazyLinkArgs { + MaybeLazy::lazied(link_args::LazyLinkArgsState::Simple(flavor, args)) } - fn add_pre_link_args(&mut self, flavor: LinkerFlavor, args: &[&'static str]) { - add_link_args(&mut self.pre_link_args, flavor, args); + #[inline] + fn link_args_list(list: &'static [(LinkerFlavor, &'static [&'static str])]) -> LazyLinkArgs { + MaybeLazy::lazied(link_args::LazyLinkArgsState::List(list)) } fn update_from_cli(&mut self) { @@ -2404,14 +2406,14 @@ impl TargetOptions { self.lld_flavor_json, self.linker_is_gnu_json, ); - for (args, args_json) in [ + for (real_args, args_json) in [ (&mut self.pre_link_args, &self.pre_link_args_json), (&mut self.late_link_args, &self.late_link_args_json), (&mut self.late_link_args_dynamic, &self.late_link_args_dynamic_json), (&mut self.late_link_args_static, &self.late_link_args_static_json), (&mut self.post_link_args, &self.post_link_args_json), ] { - args.clear(); + let mut args = LinkArgs::new(); for (flavor, args_json) in args_json { let linker_flavor = self.linker_flavor.with_cli_hints(*flavor); // Normalize to no lld to avoid asserts. @@ -2422,9 +2424,10 @@ impl TargetOptions { _ => linker_flavor, }; if !args.contains_key(&linker_flavor) { - add_link_args_iter(args, linker_flavor, args_json.iter().cloned()); + add_link_args_iter(&mut args, linker_flavor, args_json.iter().cloned()); } } + *real_args = MaybeLazy::owned(args); } } @@ -2506,15 +2509,15 @@ impl Default for TargetOptions { pre_link_objects_self_contained: Default::default(), post_link_objects_self_contained: Default::default(), link_self_contained: LinkSelfContainedDefault::False, - pre_link_args: LinkArgs::new(), + pre_link_args: Default::default(), pre_link_args_json: LinkArgsCli::new(), - late_link_args: LinkArgs::new(), + late_link_args: Default::default(), late_link_args_json: LinkArgsCli::new(), - late_link_args_dynamic: LinkArgs::new(), + late_link_args_dynamic: Default::default(), late_link_args_dynamic_json: LinkArgsCli::new(), - late_link_args_static: LinkArgs::new(), + late_link_args_static: Default::default(), late_link_args_static_json: LinkArgsCli::new(), - post_link_args: LinkArgs::new(), + post_link_args: Default::default(), post_link_args_json: LinkArgsCli::new(), link_env: cvs![], link_env_remove: cvs![], @@ -2734,7 +2737,7 @@ impl Target { }; let mut base = Target { - llvm_target: get_req_field("llvm-target")?.into(), + llvm_target: MaybeLazy::owned(get_req_field("llvm-target")?), metadata: Default::default(), pointer_width: get_req_field("target-pointer-width")? .parse::() @@ -3095,7 +3098,7 @@ impl Target { args.insert(kind, v); } - base.$key_name = args; + base.$key_name = MaybeLazy::owned(args); } } ); ($key_name:ident = $json_name:expr, link_args) => ( { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs index 4e2964174f925..4dd4592478010 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs @@ -1,9 +1,12 @@ use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi}; -use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; +use crate::spec::{FramePointer, MaybeLazy, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64; - let mut base = opts("macos", arch, TargetAbi::Normal); + const ARCH: Arch = Arch::Arm64; + const OS: &'static str = "macos"; + const ABI: TargetAbi = TargetAbi::Normal; + + let mut base = opts(OS, ARCH, ABI); base.cpu = "apple-m1".into(); base.max_atomic_width = Some(128); @@ -14,7 +17,7 @@ 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. - llvm_target: macos_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| macos_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: None, tier: None, @@ -23,7 +26,7 @@ pub fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: arch.target_arch(), + arch: ARCH.target_arch(), options: TargetOptions { mcount: "\u{1}mcount".into(), frame_pointer: FramePointer::NonLeaf, diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs index 20655689772d8..ebf28292551d1 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs @@ -1,9 +1,12 @@ use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi}; -use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; +use crate::spec::{FramePointer, MaybeLazy, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64; - let mut base = opts("ios", arch, TargetAbi::Normal); + const ARCH: Arch = Arch::Arm64; + const OS: &'static str = "ios"; + const ABI: TargetAbi = TargetAbi::Normal; + + let mut base = opts(OS, ARCH, ABI); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; Target { @@ -11,7 +14,7 @@ pub fn target() -> Target { // IPHONEOS_DEPLOYMENT_TARGET. // This is required for the target to pick the right // MACH-O commands, so we do too. - llvm_target: ios_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| ios_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: None, tier: None, @@ -20,7 +23,7 @@ pub fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: arch.target_arch(), + arch: ARCH.target_arch(), options: TargetOptions { features: "+neon,+fp-armv8,+apple-a7".into(), max_atomic_width: Some(128), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs index 4c008f7985e6f..b2c5b1c4527b8 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs @@ -1,13 +1,16 @@ use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch, TargetAbi}; -use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; +use crate::spec::{FramePointer, MaybeLazy, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64; - let mut base = opts("ios", arch, TargetAbi::MacCatalyst); + const ARCH: Arch = Arch::Arm64; + const OS: &'static str = "ios"; + const ABI: TargetAbi = TargetAbi::MacCatalyst; + + let mut base = opts(OS, ARCH, ABI); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD; Target { - llvm_target: mac_catalyst_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| mac_catalyst_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: None, tier: None, @@ -16,7 +19,7 @@ pub fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: arch.target_arch(), + arch: ARCH.target_arch(), options: TargetOptions { features: "+neon,+fp-armv8,+apple-a12".into(), max_atomic_width: Some(128), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs index 4a63abdf5419f..a444993553d12 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs @@ -1,9 +1,12 @@ use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi}; -use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; +use crate::spec::{FramePointer, MaybeLazy, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64; - let mut base = opts("ios", arch, TargetAbi::Simulator); + const ARCH: Arch = Arch::Arm64; + const OS: &'static str = "ios"; + const ABI: TargetAbi = TargetAbi::Simulator; + + let mut base = opts(OS, ARCH, ABI); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; Target { @@ -11,7 +14,7 @@ pub fn target() -> Target { // IPHONEOS_DEPLOYMENT_TARGET. // This is required for the simulator target to pick the right // MACH-O commands, so we do too. - llvm_target: ios_sim_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| ios_sim_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: None, tier: None, @@ -20,7 +23,7 @@ pub fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: arch.target_arch(), + arch: ARCH.target_arch(), options: TargetOptions { features: "+neon,+fp-armv8,+apple-a7".into(), max_atomic_width: Some(128), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs index 3310e6c9e8a41..3434789425727 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs @@ -1,10 +1,13 @@ use crate::spec::base::apple::{opts, tvos_llvm_target, Arch, TargetAbi}; -use crate::spec::{FramePointer, Target, TargetOptions}; +use crate::spec::{FramePointer, MaybeLazy, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64; + const ARCH: Arch = Arch::Arm64; + const OS: &'static str = "tvos"; + const ABI: TargetAbi = TargetAbi::Normal; + Target { - llvm_target: tvos_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| tvos_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: None, tier: None, @@ -13,12 +16,12 @@ pub fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: arch.target_arch(), + arch: ARCH.target_arch(), options: TargetOptions { features: "+neon,+fp-armv8,+apple-a7".into(), max_atomic_width: Some(128), frame_pointer: FramePointer::NonLeaf, - ..opts("tvos", arch, TargetAbi::Normal) + ..opts(OS, ARCH, ABI) }, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs index b901c663afaef..3d71d01785b07 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs @@ -1,10 +1,13 @@ use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch, TargetAbi}; -use crate::spec::{FramePointer, Target, TargetOptions}; +use crate::spec::{FramePointer, MaybeLazy, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64; + const ARCH: Arch = Arch::Arm64; + const OS: &'static str = "tvos"; + const ABI: TargetAbi = TargetAbi::Normal; + Target { - llvm_target: tvos_sim_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| tvos_sim_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: None, tier: None, @@ -13,12 +16,12 @@ pub fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: arch.target_arch(), + arch: ARCH.target_arch(), options: TargetOptions { features: "+neon,+fp-armv8,+apple-a7".into(), max_atomic_width: Some(128), frame_pointer: FramePointer::NonLeaf, - ..opts("tvos", arch, TargetAbi::Simulator) + ..opts(OS, ARCH, ABI) }, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs index b0798e5e4f580..0e6590ea4c445 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs @@ -1,13 +1,16 @@ use crate::spec::base::apple::{opts, visionos_llvm_target, Arch, TargetAbi}; -use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; +use crate::spec::{FramePointer, MaybeLazy, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64; - let mut base = opts("visionos", arch, TargetAbi::Normal); + const OS: &str = "visionos"; + const ABI: TargetAbi = TargetAbi::Normal; + const ARCH: Arch = Arch::Arm64; + + let mut base = opts(OS, ARCH, ABI); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; Target { - llvm_target: visionos_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| visionos_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: Some("ARM64 Apple visionOS".into()), tier: Some(3), @@ -16,7 +19,7 @@ pub fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: arch.target_arch(), + arch: ARCH.target_arch(), options: TargetOptions { features: "+neon,+fp-armv8,+apple-a16".into(), max_atomic_width: Some(128), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs index 7b2d2b6a8e442..152a2487cec04 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs @@ -1,13 +1,16 @@ use crate::spec::base::apple::{opts, visionos_sim_llvm_target, Arch, TargetAbi}; -use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; +use crate::spec::{FramePointer, MaybeLazy, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64; - let mut base = opts("visionos", arch, TargetAbi::Simulator); + const OS: &str = "visionos"; + const ABI: TargetAbi = TargetAbi::Simulator; + const ARCH: Arch = Arch::Arm64; + + let mut base = opts(OS, ARCH, ABI); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; Target { - llvm_target: visionos_sim_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| visionos_sim_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: Some("ARM64 Apple visionOS simulator".into()), tier: Some(3), @@ -16,7 +19,7 @@ pub fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: arch.target_arch(), + arch: ARCH.target_arch(), options: TargetOptions { features: "+neon,+fp-armv8,+apple-a16".into(), max_atomic_width: Some(128), diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs index a00a97a133f60..ae5920b0ea819 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs @@ -2,7 +2,11 @@ use crate::spec::base::apple::{opts, Arch, TargetAbi}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let base = opts("watchos", Arch::Arm64, TargetAbi::Normal); + const ARCH: Arch = Arch::Arm64; + const OS: &'static str = "watchos"; + const ABI: TargetAbi = TargetAbi::Normal; + + let base = opts(OS, ARCH, ABI); Target { llvm_target: "aarch64-apple-watchos".into(), metadata: crate::spec::TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs index e2f80b7b7a888..17e0ea966feb9 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs @@ -1,14 +1,17 @@ use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch, TargetAbi}; -use crate::spec::{FramePointer, Target, TargetOptions}; +use crate::spec::{FramePointer, MaybeLazy, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64; + const ARCH: Arch = Arch::Arm64; + const OS: &'static str = "watchos"; + const ABI: TargetAbi = TargetAbi::Simulator; + Target { // Clang automatically chooses a more specific target based on // WATCHOS_DEPLOYMENT_TARGET. // This is required for the simulator target to pick the right // MACH-O commands, so we do too. - llvm_target: watchos_sim_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| watchos_sim_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: None, tier: None, @@ -17,12 +20,12 @@ pub fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: arch.target_arch(), + arch: ARCH.target_arch(), options: TargetOptions { features: "+neon,+fp-armv8,+apple-a7".into(), max_atomic_width: Some(128), frame_pointer: FramePointer::NonLeaf, - ..opts("watchos", arch, TargetAbi::Simulator) + ..opts(OS, ARCH, ABI) }, } } diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_illumos.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_illumos.rs index 6f253c2a22393..14337f4d8e83c 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_illumos.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_illumos.rs @@ -1,8 +1,8 @@ -use crate::spec::{base, Cc, LinkerFlavor, SanitizerSet, Target}; +use crate::spec::{base, Cc, LinkerFlavor, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::illumos::opts(); - base.add_pre_link_args(LinkerFlavor::Unix(Cc::Yes), &["-std=c99"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Unix(Cc::Yes), &["-std=c99"]); base.max_atomic_width = Some(128); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI; base.features = "+v8a".into(); diff --git a/compiler/rustc_target/src/spec/targets/aarch64_unknown_uefi.rs b/compiler/rustc_target/src/spec/targets/aarch64_unknown_uefi.rs index de4a56ae03da3..2f35a3e6ec92c 100644 --- a/compiler/rustc_target/src/spec/targets/aarch64_unknown_uefi.rs +++ b/compiler/rustc_target/src/spec/targets/aarch64_unknown_uefi.rs @@ -1,13 +1,13 @@ // This defines the aarch64 target for UEFI systems as described in the UEFI specification. See the // uefi-base module for generic UEFI options. -use crate::spec::{base, LinkerFlavor, Lld, Target}; +use crate::spec::{base, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::uefi_msvc::opts(); base.max_atomic_width = Some(128); - base.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &["/machine:arm64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Msvc(Lld::No), &["/machine:arm64"]); base.features = "+v8a".into(); Target { diff --git a/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs index 3ca8c9969c2d5..682ddc5c2c67d 100644 --- a/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs +++ b/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs @@ -1,11 +1,15 @@ use crate::spec::base::apple::{opts, watchos_llvm_target, Arch, TargetAbi}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{MaybeLazy, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64_32; - let base = opts("watchos", arch, TargetAbi::Normal); + const OS: &str = "watchos"; + const ARCH: Arch = Arch::Arm64_32; + const ABI: TargetAbi = TargetAbi::Normal; + + let base = opts(OS, ARCH, ABI); + Target { - llvm_target: watchos_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| watchos_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: None, tier: None, diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs index 90be518638e93..c0795dcba6be6 100644 --- a/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs @@ -1,9 +1,12 @@ use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi}; -use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; +use crate::spec::{FramePointer, MaybeLazy, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64e; - let mut base = opts("macos", arch, TargetAbi::Normal); + const ARCH: Arch = Arch::Arm64e; + const OS: &'static str = "macos"; + const ABI: TargetAbi = TargetAbi::Normal; + + let mut base = opts(OS, ARCH, ABI); base.cpu = "apple-m1".into(); base.max_atomic_width = Some(128); @@ -14,7 +17,7 @@ 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. - llvm_target: macos_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| macos_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: None, tier: None, @@ -23,7 +26,7 @@ pub fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: arch.target_arch(), + arch: ARCH.target_arch(), options: TargetOptions { mcount: "\u{1}mcount".into(), frame_pointer: FramePointer::NonLeaf, diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs index 56470d29eae00..42f74d53c305d 100644 --- a/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs @@ -1,9 +1,12 @@ use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi}; -use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions}; +use crate::spec::{FramePointer, MaybeLazy, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Arm64e; - let mut base = opts("ios", arch, TargetAbi::Normal); + const ARCH: Arch = Arch::Arm64e; + const OS: &'static str = "ios"; + const ABI: TargetAbi = TargetAbi::Normal; + + let mut base = opts(OS, ARCH, ABI); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; Target { @@ -11,7 +14,7 @@ pub fn target() -> Target { // IPHONEOS_DEPLOYMENT_TARGET. // This is required for the target to pick the right // MACH-O commands, so we do too. - llvm_target: ios_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| ios_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: None, tier: None, @@ -20,7 +23,7 @@ pub fn target() -> Target { }, pointer_width: 64, data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(), - arch: arch.target_arch(), + arch: ARCH.target_arch(), options: TargetOptions { features: "+neon,+fp-armv8,+apple-a12,+v8.3a,+pauth".into(), max_atomic_width: Some(128), diff --git a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs index aedfb88102462..cd329bd2c68d1 100644 --- a/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs @@ -1,11 +1,10 @@ -use crate::spec::{add_link_args, base, LinkerFlavor, Lld, Target}; +use crate::spec::{base, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::windows_msvc::opts(); base.max_atomic_width = Some(128); base.features = "+v8a,+neon,+fp-armv8".into(); - add_link_args( - &mut base.late_link_args, + base.late_link_args = TargetOptions::link_args( LinkerFlavor::Msvc(Lld::No), &["/machine:arm64ec", "softintrin.lib"], ); diff --git a/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs b/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs index e798ef4735436..6a1194c3ece7d 100644 --- a/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/targets/armv7_linux_androideabi.rs @@ -10,7 +10,8 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, SanitizerSet, Target, TargetOptio pub fn target() -> Target { let mut base = base::android::opts(); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-march=armv7-a"]); + base.pre_link_args = + TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-march=armv7-a"]); Target { llvm_target: "armv7-none-linux-android".into(), metadata: crate::spec::TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs index 5c675c22ef511..0dbd06e587a9a 100644 --- a/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs +++ b/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs @@ -2,7 +2,10 @@ use crate::spec::base::apple::{opts, Arch, TargetAbi}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Armv7k; + const ARCH: Arch = Arch::Armv7k; + const OS: &'static str = "watchos"; + const ABI: TargetAbi = TargetAbi::Normal; + Target { llvm_target: "armv7k-apple-watchos".into(), metadata: crate::spec::TargetMetadata { @@ -13,13 +16,13 @@ pub fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128".into(), - arch: arch.target_arch(), + arch: ARCH.target_arch(), options: TargetOptions { features: "+v7,+vfp4,+neon".into(), max_atomic_width: Some(64), dynamic_linking: false, position_independent_executables: true, - ..opts("watchos", arch, TargetAbi::Normal) + ..opts(OS, ARCH, ABI) }, } } diff --git a/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs b/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs index 4dd475e3a82da..f5693647040ca 100644 --- a/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs @@ -1,10 +1,13 @@ use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{MaybeLazy, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::Armv7s; + const ARCH: Arch = Arch::Armv7s; + const OS: &'static str = "ios"; + const ABI: TargetAbi = TargetAbi::Normal; + Target { - llvm_target: ios_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| ios_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: None, tier: None, @@ -13,11 +16,11 @@ pub fn target() -> Target { }, pointer_width: 32, data_layout: "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".into(), - arch: arch.target_arch(), + arch: ARCH.target_arch(), options: TargetOptions { features: "+v7,+vfp4,+neon".into(), max_atomic_width: Some(64), - ..opts("ios", arch, TargetAbi::Normal) + ..opts(OS, ARCH, ABI) }, } } diff --git a/compiler/rustc_target/src/spec/targets/avr_unknown_gnu_atmega328.rs b/compiler/rustc_target/src/spec/targets/avr_unknown_gnu_atmega328.rs index bf01413a80adf..2afe598c9f08a 100644 --- a/compiler/rustc_target/src/spec/targets/avr_unknown_gnu_atmega328.rs +++ b/compiler/rustc_target/src/spec/targets/avr_unknown_gnu_atmega328.rs @@ -1,5 +1,5 @@ use crate::spec::{base, Target}; pub fn target() -> Target { - base::avr_gnu::target("atmega328", "-mmcu=atmega328") + base::avr_gnu::target("atmega328") } diff --git a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs index c03a0974bc1cb..747c881524621 100644 --- a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs @@ -1,17 +1,19 @@ use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{MaybeLazy, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::I386; + const ARCH: Arch = Arch::I386; + const OS: &'static str = "ios"; // i386-apple-ios is a simulator target, even though it isn't declared // that way in the target name like the other ones... - let abi = TargetAbi::Simulator; + const ABI: TargetAbi = TargetAbi::Simulator; + Target { // Clang automatically chooses a more specific target based on // IPHONEOS_DEPLOYMENT_TARGET. // This is required for the target to pick the right // MACH-O commands, so we do too. - llvm_target: ios_sim_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| ios_sim_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: None, tier: None, @@ -22,7 +24,7 @@ pub fn target() -> Target { data_layout: "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i128:128-f64:32:64-f80:128-n8:16:32-S128" .into(), - arch: arch.target_arch(), - options: TargetOptions { max_atomic_width: Some(64), ..opts("ios", arch, abi) }, + arch: ARCH.target_arch(), + options: TargetOptions { max_atomic_width: Some(64), ..opts(OS, ARCH, ABI) }, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs index aea6a1ac4ecea..adface04134a3 100644 --- a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs @@ -1,12 +1,16 @@ use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi}; -use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, TargetOptions}; +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, MaybeLazy, Target, TargetOptions}; pub fn target() -> Target { // ld64 only understands i386 and not i686 - let arch = Arch::I386; - let mut base = opts("macos", arch, TargetAbi::Normal); + const ARCH: Arch = Arch::I386; + const OS: &'static str = "macos"; + const ABI: TargetAbi = TargetAbi::Normal; + + let mut base = opts(OS, ARCH, ABI); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m32"]); + base.pre_link_args = + TargetOptions::link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m32"]); base.frame_pointer = FramePointer::Always; Target { @@ -15,7 +19,7 @@ pub fn target() -> Target { // correctly, we do too. // // While ld64 doesn't understand i686, LLVM does. - llvm_target: macos_llvm_target(Arch::I686).into(), + llvm_target: MaybeLazy::lazy(|| macos_llvm_target(Arch::I686)), metadata: crate::spec::TargetMetadata { description: None, tier: None, @@ -26,7 +30,7 @@ pub fn target() -> Target { data_layout: "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-\ i128:128-f64:32:64-f80:128-n8:16:32-S128" .into(), - arch: arch.target_arch(), + arch: ARCH.target_arch(), options: TargetOptions { mcount: "\u{1}mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs index 66e09416dde90..ae298fc9a4c41 100644 --- a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnu.rs @@ -1,4 +1,5 @@ -use crate::spec::{base, Cc, FramePointer, LinkerFlavor, Lld, Target}; +use crate::spec::{base, Cc, FramePointer}; +use crate::spec::{LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::windows_gnu::opts(); @@ -9,11 +10,10 @@ pub fn target() -> Target { // Mark all dynamic libraries and executables as compatible with the larger 4GiB address // space available to x86 Windows binaries on x86_64. - base.add_pre_link_args( - LinkerFlavor::Gnu(Cc::No, Lld::No), - &["-m", "i386pe", "--large-address-aware"], - ); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-Wl,--large-address-aware"]); + base.pre_link_args = TargetOptions::link_args_list(&[ + (LinkerFlavor::Gnu(Cc::No, Lld::No), &["-m", "i386pe", "--large-address-aware"]), + (LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-Wl,--large-address-aware"]), + ]); Target { llvm_target: "i686-pc-windows-gnu".into(), diff --git a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnullvm.rs index 7a2d28aec9c08..ba9a20251577d 100644 --- a/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/targets/i686_pc_windows_gnullvm.rs @@ -1,4 +1,4 @@ -use crate::spec::{base, Cc, FramePointer, LinkerFlavor, Lld, Target}; +use crate::spec::{base, Cc, FramePointer, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::windows_gnullvm::opts(); @@ -9,7 +9,7 @@ pub fn target() -> Target { // Mark all dynamic libraries and executables as compatible with the larger 4GiB address // space available to x86 Windows binaries on x86_64. - base.add_pre_link_args( + base.pre_link_args = TargetOptions::link_args( LinkerFlavor::Gnu(Cc::No, Lld::No), &["-m", "i386pe", "--large-address-aware"], ); diff --git a/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs index 970b43ad109ba..b27c7dd09ab8b 100644 --- a/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/i686_pc_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{base, LinkerFlavor, Lld, SanitizerSet, Target}; +use crate::spec::{base, LinkerFlavor, Lld, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::windows_msvc::opts(); @@ -6,7 +6,7 @@ pub fn target() -> Target { base.max_atomic_width = Some(64); base.supported_sanitizers = SanitizerSet::ADDRESS; - base.add_pre_link_args( + base.pre_link_args = TargetOptions::link_args( LinkerFlavor::Msvc(Lld::No), &[ // Mark all dynamic libraries and executables as compatible with the larger 4GiB address diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_freebsd.rs index 5826906e9d8ed..97454046b2f21 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_freebsd.rs @@ -1,10 +1,11 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::freebsd::opts(); base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "-Wl,-znotext"]); + base.pre_link_args = + TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "-Wl,-znotext"]); base.stack_probes = StackProbeType::Inline; Target { diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_haiku.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_haiku.rs index 5f66911b39a14..35960eb7f082d 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_haiku.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_haiku.rs @@ -1,10 +1,10 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::haiku::opts(); base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); base.stack_probes = StackProbeType::Inline; Target { diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_hurd_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_hurd_gnu.rs index a67105f24ca2e..83136d600ba2b 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_hurd_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_hurd_gnu.rs @@ -1,10 +1,10 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::hurd_gnu::opts(); base.cpu = "pentiumpro".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); base.stack_probes = StackProbeType::Inline; Target { diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_linux_gnu.rs index 1d4916cabfdf3..a908994845729 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_linux_gnu.rs @@ -1,11 +1,12 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld}; +use crate::spec::{SanitizerSet, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::linux_gnu::opts(); base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); base.supported_sanitizers = SanitizerSet::ADDRESS; - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); base.stack_probes = StackProbeType::Inline; Target { diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs index c3b9b71802b18..f39eba801cca5 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_linux_musl.rs @@ -1,10 +1,13 @@ -use crate::spec::{base, Cc, FramePointer, LinkerFlavor, Lld, StackProbeType, Target}; +use crate::spec::{ + base, Cc, FramePointer, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions, +}; pub fn target() -> Target { let mut base = base::linux_musl::opts(); base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "-Wl,-melf_i386"]); + base.pre_link_args = + TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "-Wl,-melf_i386"]); base.stack_probes = StackProbeType::Inline; // The unwinder used by i686-unknown-linux-musl, the LLVM libunwind diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_netbsd.rs index 87eba1fb856f0..ac7ea5ff15d62 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_netbsd.rs @@ -4,7 +4,7 @@ pub fn target() -> Target { let mut base = base::netbsd::opts(); base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); base.stack_probes = StackProbeType::Inline; Target { diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_openbsd.rs index 0436f39f5b11c..02b87aa919ccc 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_openbsd.rs @@ -1,10 +1,11 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::openbsd::opts(); base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "-fuse-ld=lld"]); + base.pre_link_args = + TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "-fuse-ld=lld"]); base.stack_probes = StackProbeType::Inline; Target { diff --git a/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs index 83252fadb78ea..0f6307ea35d61 100644 --- a/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/targets/i686_unknown_redox.rs @@ -1,11 +1,11 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::redox::opts(); base.cpu = "pentiumpro".into(); base.plt_by_default = false; base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); // don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved base.stack_probes = StackProbeType::Call; diff --git a/compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs index 77dcd645728f1..c88433537bb6f 100644 --- a/compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/i686_uwp_windows_gnu.rs @@ -1,4 +1,5 @@ -use crate::spec::{base, Cc, FramePointer, LinkerFlavor, Lld, Target}; +use crate::spec::{base, Cc, FramePointer}; +use crate::spec::{LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::windows_uwp_gnu::opts(); @@ -8,11 +9,10 @@ pub fn target() -> Target { // Mark all dynamic libraries and executables as compatible with the larger 4GiB address // space available to x86 Windows binaries on x86_64. - base.add_pre_link_args( - LinkerFlavor::Gnu(Cc::No, Lld::No), - &["-m", "i386pe", "--large-address-aware"], - ); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-Wl,--large-address-aware"]); + base.pre_link_args = TargetOptions::link_args_list(&[ + (LinkerFlavor::Gnu(Cc::No, Lld::No), &["-m", "i386pe", "--large-address-aware"]), + (LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-Wl,--large-address-aware"]), + ]); Target { llvm_target: "i686-pc-windows-gnu".into(), diff --git a/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs index ae1a44e44a85a..d97900b4ab929 100644 --- a/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/i686_win7_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{base, LinkerFlavor, Lld, Target}; +use crate::spec::{base, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::windows_msvc::opts(); @@ -6,7 +6,7 @@ pub fn target() -> Target { base.max_atomic_width = Some(64); base.vendor = "win7".into(); - base.add_pre_link_args( + base.pre_link_args = TargetOptions::link_args( LinkerFlavor::Msvc(Lld::No), &[ // Mark all dynamic libraries and executables as compatible with the larger 4GiB address diff --git a/compiler/rustc_target/src/spec/targets/i686_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/i686_wrs_vxworks.rs index e4d0b674cc4c3..9e23ce188ad4c 100644 --- a/compiler/rustc_target/src/spec/targets/i686_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/targets/i686_wrs_vxworks.rs @@ -1,10 +1,10 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::vxworks::opts(); base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); base.stack_probes = StackProbeType::Inline; Target { diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs b/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs index 481df71c1a65a..1cab3395a8f0a 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_ibm_aix.rs @@ -1,9 +1,9 @@ -use crate::spec::{base, Cc, LinkerFlavor, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::aix::opts(); base.max_atomic_width = Some(64); - base.add_pre_link_args( + base.pre_link_args = TargetOptions::link_args( LinkerFlavor::Unix(Cc::No), &["-b64", "-bpT:0x100000000", "-bpD:0x110000000", "-bcdtors:all:0:s"], ); diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs index b1b981823b89d..12c2c9e247dfd 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_freebsd.rs @@ -4,7 +4,7 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOpt pub fn target() -> Target { let mut base = base::freebsd::opts(); base.cpu = "ppc64".into(); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs index ac10630d94404..b44ba19b2b2df 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_gnu.rs @@ -4,7 +4,7 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOpt pub fn target() -> Target { let mut base = base::linux_gnu::opts(); base.cpu = "ppc64".into(); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs index 663f06cf0c67b..b250315213fb4 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs @@ -4,7 +4,7 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOpt pub fn target() -> Target { let mut base = base::linux_musl::opts(); base.cpu = "ppc64".into(); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs index 5611352c951c7..ccd829f53ec43 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_openbsd.rs @@ -4,7 +4,7 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOpt pub fn target() -> Target { let mut base = base::openbsd::opts(); base.cpu = "ppc64".into(); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs index 22b45042aa667..2dfe1b90d04ad 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64_wrs_vxworks.rs @@ -4,7 +4,7 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOpt pub fn target() -> Target { let mut base = base::vxworks::opts(); base.cpu = "ppc64".into(); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; diff --git a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs index 812b5928966f6..7deb248aa9fc7 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_freebsd.rs @@ -3,7 +3,7 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOpt pub fn target() -> Target { let mut base = base::freebsd::opts(); base.cpu = "ppc64le".into(); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; diff --git a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs index e3c4b3b585c2a..2515f011f24f8 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_gnu.rs @@ -3,7 +3,7 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOpt pub fn target() -> Target { let mut base = base::linux_gnu::opts(); base.cpu = "ppc64le".into(); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; diff --git a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs index 497a40ade81e8..7d25e1359afba 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc64le_unknown_linux_musl.rs @@ -3,7 +3,7 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOpt pub fn target() -> Target { let mut base = base::linux_musl::opts(); base.cpu = "ppc64le".into(); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.stack_probes = StackProbeType::Inline; diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_freebsd.rs index 194bb0566f18f..7b2acb20ec51d 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_freebsd.rs @@ -4,7 +4,7 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOpt pub fn target() -> Target { let mut base = base::freebsd::opts(); // Extra hint to linker that we are generating secure-PLT code. - base.add_pre_link_args( + base.pre_link_args = TargetOptions::link_args( LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "--target=powerpc-unknown-freebsd13.0"], ); diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs index b88b2fbf80948..fd2a367a85844 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnu.rs @@ -3,7 +3,7 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOpt pub fn target() -> Target { let mut base = base::linux_gnu::opts(); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); base.max_atomic_width = Some(32); base.stack_probes = StackProbeType::Inline; diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs index b09c4cd21e046..fe8c7aad73079 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_gnuspe.rs @@ -3,7 +3,7 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOpt pub fn target() -> Target { let mut base = base::linux_gnu::opts(); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mspe"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mspe"]); base.max_atomic_width = Some(32); base.stack_probes = StackProbeType::Inline; diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs index 67b19e9048916..5fa90e242ad48 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs @@ -3,7 +3,7 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOpt pub fn target() -> Target { let mut base = base::linux_musl::opts(); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); base.max_atomic_width = Some(32); base.stack_probes = StackProbeType::Inline; diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_netbsd.rs index c592cd3f6fd2d..a13a1fbd8c0bb 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_netbsd.rs @@ -3,7 +3,7 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOpt pub fn target() -> Target { let mut base = base::netbsd::opts(); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); base.max_atomic_width = Some(32); base.stack_probes = StackProbeType::Inline; diff --git a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs index 91925ce151dfd..a89ea8f5fda4c 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks.rs @@ -3,7 +3,8 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOpt pub fn target() -> Target { let mut base = base::vxworks::opts(); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "--secure-plt"]); + base.pre_link_args = + TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "--secure-plt"]); base.max_atomic_width = Some(32); base.stack_probes = StackProbeType::Inline; diff --git a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs index 7640feb28e3c9..2affe53a05c33 100644 --- a/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs +++ b/compiler/rustc_target/src/spec/targets/powerpc_wrs_vxworks_spe.rs @@ -3,7 +3,8 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOpt pub fn target() -> Target { let mut base = base::vxworks::opts(); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mspe", "--secure-plt"]); + base.pre_link_args = + TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mspe", "--secure-plt"]); base.max_atomic_width = Some(32); base.stack_probes = StackProbeType::Inline; diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs index 42944367cf666..3e4bbf538af5e 100644 --- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs @@ -4,7 +4,7 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::netbsd::opts(); base.cpu = "v9".into(); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); Target { diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs index f0bf55d33e684..d9c3e63da1a65 100644 --- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs @@ -1,11 +1,11 @@ use crate::abi::Endian; -use crate::spec::{base, Cc, LinkerFlavor, Lld, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::openbsd::opts(); base.endian = Endian::Big; base.cpu = "v9".into(); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); Target { diff --git a/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs index c10f9d82d4636..eff9d4deea9b8 100644 --- a/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs @@ -1,12 +1,13 @@ use crate::abi::Endian; -use crate::spec::{base, Cc, LinkerFlavor, Lld, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::linux_gnu::opts(); base.endian = Endian::Big; base.cpu = "v9".into(); base.max_atomic_width = Some(32); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mv8plus"]); + base.pre_link_args = + TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mv8plus"]); Target { llvm_target: "sparc-unknown-linux-gnu".into(), diff --git a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs index a42243f59dc4d..99a163af92709 100644 --- a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs +++ b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs @@ -1,10 +1,10 @@ use crate::abi::Endian; -use crate::spec::{base, Cc, LinkerFlavor, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::solaris::opts(); base.endian = Endian::Big; - base.add_pre_link_args(LinkerFlavor::Unix(Cc::Yes), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Unix(Cc::Yes), &["-m64"]); // llvm calls this "v9" base.cpu = "v9".into(); base.vendor = "sun".into(); diff --git a/compiler/rustc_target/src/spec/targets/thumbv7a_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/thumbv7a_pc_windows_msvc.rs index 13e1e349b0402..836740144e67e 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7a_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7a_pc_windows_msvc.rs @@ -9,7 +9,7 @@ pub fn target() -> Target { // should be smart enough to insert branch islands only // where necessary, but this is not the observed behavior. // Disabling the LBR optimization works around the issue. - base.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &["/OPT:NOLBR"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Msvc(Lld::No), &["/OPT:NOLBR"]); Target { llvm_target: "thumbv7a-pc-windows-msvc".into(), diff --git a/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs b/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs index d50e63b92175d..8f07873826ba6 100644 --- a/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/targets/thumbv7neon_linux_androideabi.rs @@ -10,7 +10,8 @@ use crate::spec::{base, Cc, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::android::opts(); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-march=armv7-a"]); + base.pre_link_args = + TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-march=armv7-a"]); Target { llvm_target: "armv7-none-linux-android".into(), metadata: crate::spec::TargetMetadata { diff --git a/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs b/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs index 195ff46cf9d25..d61ce747aca1a 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_unknown_emscripten.rs @@ -1,10 +1,9 @@ -use crate::spec::{ - base, cvs, LinkArgs, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions, -}; +use crate::spec::{base, cvs, LinkerFlavor, PanicStrategy}; +use crate::spec::{RelocModel, Target, TargetOptions}; pub fn target() -> Target { // Reset flags for non-Em flavors back to empty to satisfy sanity checking tests. - let pre_link_args = LinkArgs::new(); + let pre_link_args = Default::default(); let post_link_args = TargetOptions::link_args(LinkerFlavor::EmCc, &["-sABORTING_MALLOC=0"]); let opts = TargetOptions { diff --git a/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs b/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs index 23f4772c39cb5..62a8794212d60 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs @@ -9,30 +9,31 @@ //! //! This target is more or less managed by the Rust and WebAssembly Working //! Group nowadays at . - -use crate::spec::{base, Cc, LinkerFlavor, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut options = base::wasm::options(); options.os = "unknown".into(); - options.add_pre_link_args( - LinkerFlavor::WasmLld(Cc::No), - &[ - // For now this target just never has an entry symbol no matter the output - // type, so unconditionally pass this. - "--no-entry", - ], - ); - options.add_pre_link_args( - LinkerFlavor::WasmLld(Cc::Yes), - &[ - // Make sure clang uses LLD as its linker and is configured appropriately - // otherwise - "--target=wasm32-unknown-unknown", - "-Wl,--no-entry", - ], - ); + options.pre_link_args = TargetOptions::link_args_list(&[ + ( + LinkerFlavor::WasmLld(Cc::No), + &[ + // For now this target just never has an entry symbol no matter the output + // type, so unconditionally pass this. + "--no-entry", + ], + ), + ( + LinkerFlavor::WasmLld(Cc::Yes), + &[ + // Make sure clang uses LLD as its linker and is configured appropriately + // otherwise + "--target=wasm32-unknown-unknown", + "-Wl,--no-entry", + ], + ), + ]); Target { llvm_target: "wasm32-unknown-unknown".into(), diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs index 4c2d222b590e4..2fe82cb571540 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs @@ -12,6 +12,7 @@ use crate::spec::crt_objects; use crate::spec::LinkSelfContainedDefault; +use crate::spec::TargetOptions; use crate::spec::{base, Cc, LinkerFlavor, Target}; pub fn target() -> Target { @@ -19,7 +20,8 @@ pub fn target() -> Target { options.os = "wasi".into(); options.env = "p1".into(); - options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::Yes), &["--target=wasm32-wasi"]); + options.pre_link_args = + TargetOptions::link_args(LinkerFlavor::WasmLld(Cc::Yes), &["--target=wasm32-wasi"]); options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained(); options.post_link_objects_self_contained = crt_objects::post_wasi_self_contained(); diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs index 38af48ab2665a..72e4e03bac707 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_wasip1_threads.rs @@ -7,7 +7,9 @@ //! //! Historically this target was known as `wasm32-wasi-preview1-threads`. -use crate::spec::{base, crt_objects, Cc, LinkSelfContainedDefault, LinkerFlavor, Target}; +use crate::spec::{ + base, crt_objects, Cc, LinkSelfContainedDefault, LinkerFlavor, Target, TargetOptions, +}; pub fn target() -> Target { let mut options = base::wasm::options(); @@ -15,19 +17,18 @@ pub fn target() -> Target { options.os = "wasi".into(); options.env = "p1".into(); - options.add_pre_link_args( - LinkerFlavor::WasmLld(Cc::No), - &["--import-memory", "--export-memory", "--shared-memory"], - ); - options.add_pre_link_args( - LinkerFlavor::WasmLld(Cc::Yes), - &[ - "--target=wasm32-wasip1-threads", - "-Wl,--import-memory", - "-Wl,--export-memory,", - "-Wl,--shared-memory", - ], - ); + options.pre_link_args = TargetOptions::link_args_list(&[ + (LinkerFlavor::WasmLld(Cc::No), &["--import-memory", "--export-memory", "--shared-memory"]), + ( + LinkerFlavor::WasmLld(Cc::Yes), + &[ + "--target=wasm32-wasip1-threads", + "-Wl,--import-memory", + "-Wl,--export-memory,", + "-Wl,--shared-memory", + ], + ), + ]); options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained(); options.post_link_objects_self_contained = crt_objects::post_wasi_self_contained(); diff --git a/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs b/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs index 8edde36dac623..28883ee3c77a7 100644 --- a/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs +++ b/compiler/rustc_target/src/spec/targets/wasm64_unknown_unknown.rs @@ -7,30 +7,32 @@ //! the standard library is available, most of it returns an error immediately //! (e.g. trying to create a TCP stream or something like that). -use crate::spec::{base, Cc, LinkerFlavor, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut options = base::wasm::options(); options.os = "unknown".into(); - options.add_pre_link_args( - LinkerFlavor::WasmLld(Cc::No), - &[ - // For now this target just never has an entry symbol no matter the output - // type, so unconditionally pass this. - "--no-entry", - "-mwasm64", - ], - ); - options.add_pre_link_args( - LinkerFlavor::WasmLld(Cc::Yes), - &[ - // Make sure clang uses LLD as its linker and is configured appropriately - // otherwise - "--target=wasm64-unknown-unknown", - "-Wl,--no-entry", - ], - ); + options.pre_link_args = TargetOptions::link_args_list(&[ + ( + LinkerFlavor::WasmLld(Cc::No), + &[ + // For now this target just never has an entry symbol no matter the output + // type, so unconditionally pass this. + "--no-entry", + "-mwasm64", + ], + ), + ( + LinkerFlavor::WasmLld(Cc::Yes), + &[ + // Make sure clang uses LLD as its linker and is configured appropriately + // otherwise + "--target=wasm64-unknown-unknown", + "-Wl,--no-entry", + ], + ), + ]); // Any engine that implements wasm64 will surely implement the rest of these // features since they were all merged into the official spec by the time diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs index 21acd750df2dc..bd59dc3f813bd 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs @@ -1,13 +1,17 @@ use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi}; -use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet}; +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, MaybeLazy, SanitizerSet}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::X86_64; - let mut base = opts("macos", arch, TargetAbi::Normal); + const ARCH: Arch = Arch::X86_64; + const OS: &'static str = "macos"; + const ABI: TargetAbi = TargetAbi::Normal; + + let mut base = opts(OS, ARCH, ABI); base.max_atomic_width = Some(128); // penryn+ supports cmpxchg16b base.frame_pointer = FramePointer::Always; - base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = + TargetOptions::link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD; @@ -15,7 +19,7 @@ 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. - llvm_target: macos_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| macos_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: None, tier: None, @@ -25,7 +29,7 @@ pub fn target() -> Target { pointer_width: 64, data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: arch.target_arch(), + arch: ARCH.target_arch(), options: TargetOptions { mcount: "\u{1}mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs index ec61b7967646e..e59dbe0c6c761 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs @@ -1,15 +1,18 @@ use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi}; -use crate::spec::{SanitizerSet, Target, TargetOptions}; +use crate::spec::{MaybeLazy, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::X86_64; + const ARCH: Arch = Arch::X86_64; + const OS: &'static str = "ios"; + const ABI: TargetAbi = TargetAbi::Simulator; + // x86_64-apple-ios is a simulator target, even though it isn't declared // that way in the target name like the other ones... - let mut base = opts("ios", arch, TargetAbi::Simulator); + let mut base = opts(OS, ARCH, ABI); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD; Target { - llvm_target: ios_sim_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| ios_sim_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: None, tier: None, @@ -19,7 +22,7 @@ pub fn target() -> Target { pointer_width: 64, data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: arch.target_arch(), + arch: ARCH.target_arch(), options: TargetOptions { max_atomic_width: Some(128), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs index bd967ee972b32..04d0bc7775200 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs @@ -1,13 +1,16 @@ use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch, TargetAbi}; -use crate::spec::{SanitizerSet, Target, TargetOptions}; +use crate::spec::{MaybeLazy, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::X86_64; - let mut base = opts("ios", arch, TargetAbi::MacCatalyst); + const ARCH: Arch = Arch::X86_64; + const OS: &'static str = "ios"; + const ABI: TargetAbi = TargetAbi::MacCatalyst; + + let mut base = opts(OS, ARCH, ABI); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD; Target { - llvm_target: mac_catalyst_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| mac_catalyst_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: None, tier: None, @@ -17,7 +20,7 @@ pub fn target() -> Target { pointer_width: 64, data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: arch.target_arch(), + arch: ARCH.target_arch(), options: TargetOptions { max_atomic_width: Some(128), ..base }, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs index 55b2e1afcd392..d6495f83c8ff9 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs @@ -1,13 +1,16 @@ use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch, TargetAbi}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{MaybeLazy, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::X86_64; // x86_64-apple-tvos is a simulator target, even though it isn't declared // that way in the target name like the other ones... - let abi = TargetAbi::Simulator; + + const ARCH: Arch = Arch::X86_64; + const OS: &'static str = "tvos"; + const ABI: TargetAbi = TargetAbi::Simulator; + Target { - llvm_target: tvos_sim_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| tvos_sim_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: None, tier: None, @@ -17,7 +20,7 @@ pub fn target() -> Target { pointer_width: 64, data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: arch.target_arch(), - options: TargetOptions { max_atomic_width: Some(128), ..opts("tvos", arch, abi) }, + arch: ARCH.target_arch(), + options: TargetOptions { max_atomic_width: Some(128), ..opts(OS, ARCH, ABI) }, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs index a783eff15b261..a00e94a1a713c 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs @@ -1,10 +1,13 @@ use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch, TargetAbi}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{MaybeLazy, Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::X86_64; + const ARCH: Arch = Arch::X86_64; + const OS: &'static str = "watchos"; + const ABI: TargetAbi = TargetAbi::Simulator; + Target { - llvm_target: watchos_sim_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| watchos_sim_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: None, tier: None, @@ -14,10 +17,7 @@ pub fn target() -> Target { pointer_width: 64, data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: arch.target_arch(), - options: TargetOptions { - max_atomic_width: Some(128), - ..opts("watchos", arch, TargetAbi::Simulator) - }, + arch: ARCH.target_arch(), + options: TargetOptions { max_atomic_width: Some(128), ..opts(OS, ARCH, ABI) }, } } diff --git a/compiler/rustc_target/src/spec/targets/x86_64_linux_android.rs b/compiler/rustc_target/src/spec/targets/x86_64_linux_android.rs index 92711bbe246b7..7fa499c29657b 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_linux_android.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_linux_android.rs @@ -9,7 +9,7 @@ pub fn target() -> Target { // https://developer.android.com/ndk/guides/abis.html#86-64 base.features = "+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::Inline; base.supports_xray = true; diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs index 4dbe049a4b782..df7b124f81008 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_solaris.rs @@ -1,8 +1,8 @@ -use crate::spec::{base, Cc, LinkerFlavor, SanitizerSet, StackProbeType, Target}; +use crate::spec::{base, Cc, LinkerFlavor, SanitizerSet, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::solaris::opts(); - base.add_pre_link_args(LinkerFlavor::Unix(Cc::Yes), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Unix(Cc::Yes), &["-m64"]); base.cpu = "x86-64".into(); base.plt_by_default = false; base.vendor = "pc".into(); diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnu.rs index de0f17246c3dc..cfc158eadf284 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnu.rs @@ -1,4 +1,4 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::windows_gnu::opts(); @@ -6,11 +6,10 @@ pub fn target() -> Target { base.features = "+cx16,+sse3,+sahf".into(); base.plt_by_default = false; // Use high-entropy 64 bit address space for ASLR - base.add_pre_link_args( - LinkerFlavor::Gnu(Cc::No, Lld::No), - &["-m", "i386pep", "--high-entropy-va"], - ); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64", "-Wl,--high-entropy-va"]); + base.pre_link_args = TargetOptions::link_args_list(&[ + (LinkerFlavor::Gnu(Cc::No, Lld::No), &["-m", "i386pep", "--high-entropy-va"]), + (LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64", "-Wl,--high-entropy-va"]), + ]); base.max_atomic_width = Some(128); base.linker = Some("x86_64-w64-mingw32-gcc".into()); diff --git a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs index b485970bb416d..a19e53ce93dc1 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_pc_windows_gnullvm.rs @@ -1,11 +1,11 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::windows_gnullvm::opts(); base.cpu = "x86-64".into(); base.features = "+cx16,+sse3,+sahf".into(); base.plt_by_default = false; - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(128); base.linker = Some("x86_64-w64-mingw32-clang".into()); diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_dragonfly.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_dragonfly.rs index aef95e373cbfa..38d0eb6bbb5f4 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_dragonfly.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_dragonfly.rs @@ -1,11 +1,11 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::dragonfly::opts(); base.cpu = "x86-64".into(); base.plt_by_default = false; base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::Inline; Target { diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_freebsd.rs index 15146a5ef7299..2cbf9d91f2717 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_freebsd.rs @@ -1,11 +1,13 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target}; +use crate::spec::{ + base, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetOptions, +}; pub fn target() -> Target { let mut base = base::freebsd::opts(); base.cpu = "x86-64".into(); base.plt_by_default = false; base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::Inline; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::MEMORY | SanitizerSet::THREAD; diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_haiku.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_haiku.rs index 9f62eb1fa270d..6956fc788e12d 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_haiku.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_haiku.rs @@ -1,11 +1,11 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::haiku::opts(); base.cpu = "x86-64".into(); base.plt_by_default = false; base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::Inline; // This option is required to build executables on Haiku x86_64 base.position_independent_executables = true; diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_illumos.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_illumos.rs index c52cdf466abe7..d861b6e81d392 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_illumos.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_illumos.rs @@ -1,8 +1,9 @@ -use crate::spec::{base, Cc, LinkerFlavor, SanitizerSet, Target}; +use crate::spec::{base, Cc, LinkerFlavor, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::illumos::opts(); - base.add_pre_link_args(LinkerFlavor::Unix(Cc::Yes), &["-m64", "-std=c99"]); + base.pre_link_args = + TargetOptions::link_args(LinkerFlavor::Unix(Cc::Yes), &["-m64", "-std=c99"]); base.cpu = "x86-64".into(); base.plt_by_default = false; base.max_atomic_width = Some(64); diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs index bd12d4d8af0e0..55eb001b4995f 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnu.rs @@ -1,11 +1,13 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target}; +use crate::spec::{ + base, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetOptions, +}; pub fn target() -> Target { let mut base = base::linux_gnu::opts(); base.cpu = "x86-64".into(); base.plt_by_default = false; base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::Inline; base.static_position_independent_executables = true; base.supported_sanitizers = SanitizerSet::ADDRESS diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs index f6e0b051e8f54..2853b78fe6615 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_gnux32.rs @@ -1,11 +1,11 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::linux_gnu::opts(); base.cpu = "x86-64".into(); base.abi = "x32".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mx32"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mx32"]); base.stack_probes = StackProbeType::Inline; base.has_thread_local = false; // BUG(GabrielMajeri): disabling the PLT on x86_64 Linux with x32 ABI diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs index 66237f071028d..669de753c01e6 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_musl.rs @@ -1,11 +1,13 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target}; +use crate::spec::{ + base, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetOptions, +}; pub fn target() -> Target { let mut base = base::linux_musl::opts(); base.cpu = "x86-64".into(); base.plt_by_default = false; base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::Inline; base.static_position_independent_executables = true; base.supported_sanitizers = SanitizerSet::ADDRESS diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_ohos.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_ohos.rs index db8db1d253824..dbe6433d543bb 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_ohos.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_linux_ohos.rs @@ -1,10 +1,12 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target}; +use crate::spec::{ + base, Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetOptions, +}; pub fn target() -> Target { let mut base = base::linux_ohos::opts(); base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::Inline; base.static_position_independent_executables = true; base.supported_sanitizers = SanitizerSet::ADDRESS diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_netbsd.rs index 38ae3a4fe4248..222f90bc147e6 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_netbsd.rs @@ -7,7 +7,7 @@ pub fn target() -> Target { base.cpu = "x86-64".into(); base.plt_by_default = false; base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::Inline; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_openbsd.rs index 4d7eba2421394..cd076fc15d931 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_openbsd.rs @@ -1,11 +1,11 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::openbsd::opts(); base.cpu = "x86-64".into(); base.plt_by_default = false; base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::Inline; base.supports_xray = true; diff --git a/compiler/rustc_target/src/spec/targets/x86_64_unknown_redox.rs b/compiler/rustc_target/src/spec/targets/x86_64_unknown_redox.rs index 99f5d9dc41d29..7b85a05f53ecd 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_unknown_redox.rs @@ -1,11 +1,11 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::redox::opts(); base.cpu = "x86-64".into(); base.plt_by_default = false; base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::Inline; Target { diff --git a/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_gnu.rs index aef6fd1a7814e..2b9ea5a295728 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_uwp_windows_gnu.rs @@ -1,4 +1,4 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::windows_uwp_gnu::opts(); @@ -6,11 +6,10 @@ pub fn target() -> Target { base.features = "+cx16,+sse3,+sahf".into(); base.plt_by_default = false; // Use high-entropy 64 bit address space for ASLR - base.add_pre_link_args( - LinkerFlavor::Gnu(Cc::No, Lld::No), - &["-m", "i386pep", "--high-entropy-va"], - ); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64", "-Wl,--high-entropy-va"]); + base.pre_link_args = TargetOptions::link_args_list(&[ + (LinkerFlavor::Gnu(Cc::No, Lld::No), &["-m", "i386pep", "--high-entropy-va"]), + (LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64", "-Wl,--high-entropy-va"]), + ]); base.max_atomic_width = Some(128); Target { diff --git a/compiler/rustc_target/src/spec/targets/x86_64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/targets/x86_64_wrs_vxworks.rs index b956d228c17fe..adb23c8c3ab91 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64_wrs_vxworks.rs @@ -1,11 +1,11 @@ -use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = base::vxworks::opts(); base.cpu = "x86-64".into(); base.plt_by_default = false; base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::Inline; base.disable_redzone = true; diff --git a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs index fe6cbca32c748..1be5856b4ca32 100644 --- a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs @@ -1,13 +1,17 @@ use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi}; -use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet}; +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, MaybeLazy, SanitizerSet}; use crate::spec::{Target, TargetOptions}; pub fn target() -> Target { - let arch = Arch::X86_64h; - let mut base = opts("macos", arch, TargetAbi::Normal); + const ARCH: Arch = Arch::X86_64h; + const OS: &'static str = "macos"; + const ABI: TargetAbi = TargetAbi::Normal; + + let mut base = opts(OS, ARCH, ABI); base.max_atomic_width = Some(128); base.frame_pointer = FramePointer::Always; - base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]); + base.pre_link_args = + TargetOptions::link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD; @@ -33,7 +37,7 @@ 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. - llvm_target: macos_llvm_target(arch).into(), + llvm_target: MaybeLazy::lazy(|| macos_llvm_target(ARCH)), metadata: crate::spec::TargetMetadata { description: None, tier: None, @@ -43,7 +47,7 @@ pub fn target() -> Target { pointer_width: 64, data_layout: "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(), - arch: arch.target_arch(), + arch: ARCH.target_arch(), options: TargetOptions { mcount: "\u{1}mcount".into(), ..base }, } } diff --git a/compiler/rustc_target/src/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs index 3be18ef3127d5..e84aa598c20ed 100644 --- a/compiler/rustc_target/src/spec/tests/tests_impl.rs +++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs @@ -37,7 +37,7 @@ impl Target { &self.late_link_args_static, &self.post_link_args, ] { - for (&flavor, flavor_args) in args { + for (&flavor, flavor_args) in &**args { assert!(!flavor_args.is_empty()); // Check that flavors mentioned in link args are compatible with the default flavor. match self.linker_flavor {