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<str> = 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<LinkOutputKind, Vec<Cow<'static, str>>>;
+pub type LazyCrtObjects = MaybeLazy<CrtObjects, LazyCrtObjectsState>;
-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<LinkerFlavor, Vec<StaticCow<str>>>;
+pub type LinkArgsCli = BTreeMap<LinkerFlavorCli, Vec<StaticCow<str>>>;
+
+pub type LazyLinkArgs = MaybeLazy<LinkArgs, LazyLinkArgsState>;
+
+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<T: 'static + ToOwned + ?Sized, F> {
+ Lazy(LazyLock<T::Owned, F>),
+ 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<T: 'static + ToOwned + ?Sized, F = fn() -> <T as ToOwned>::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<T, F>,
+}
+
+impl<T: 'static + ?Sized + ToOwned, F: FnOnce() -> T::Owned> MaybeLazy<T, F> {
+ /// 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<T: 'static + ?Sized + ToOwned> MaybeLazy<T> {
+ /// Create a [`MaybeLazy`] from a function pointer.
+ #[inline]
+ pub const fn lazy(a: fn() -> T::Owned) -> Self {
+ Self::lazied(a)
+ }
+}
+
+impl<T: 'static + ?Sized + ToOwned<Owned: Clone>, F: FnOnce() -> T::Owned> Clone
+ for MaybeLazy<T, F>
+{
+ #[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<T: 'static + ?Sized + ToOwned<Owned: Default>, F: FnOnce() -> T::Owned> Default
+ for MaybeLazy<T, F>
+{
+ #[inline]
+ fn default() -> MaybeLazy<T, F> {
+ MaybeLazy::owned(T::Owned::default())
+ }
+}
+
+// `Debug`, `Display` and other traits below are implemented in terms of this `Deref`
+impl<T: 'static + ?Sized + ToOwned<Owned: Borrow<T>>, F: FnOnce() -> T::Owned> Deref
+ for MaybeLazy<T, F>
+{
+ type Target = T;
+
+ #[inline]
+ fn deref(&self) -> &T {
+ match &self.inner {
+ MaybeLazyInner::Lazy(f) => (&**f).borrow(),
+ MaybeLazyInner::Cow(c) => &*c,
+ }
+ }
+}
+
+impl<T: 'static + ?Sized + ToOwned<Owned: Debug> + Debug, F: FnOnce() -> T::Owned> Debug
+ for MaybeLazy<T, F>
+{
+ #[inline]
+ fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ Debug::fmt(&**self, fmt)
+ }
+}
+
+impl<T: 'static + ?Sized + ToOwned<Owned: Display> + Display, F: FnOnce() -> T::Owned> Display
+ for MaybeLazy<T, F>
+{
+ #[inline]
+ fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ Display::fmt(&**self, fmt)
+ }
+}
+
+impl<T: 'static + ?Sized + ToOwned, F: FnOnce() -> T::Owned> AsRef<T> for MaybeLazy<T, F> {
+ #[inline]
+ fn as_ref(&self) -> &T {
+ &**self
+ }
+}
+
+impl<
+ T1: ?Sized + PartialEq<T2> + ToOwned,
+ T2: ?Sized + ToOwned,
+ F1: FnOnce() -> T1::Owned,
+ F2: FnOnce() -> T2::Owned,
+> PartialEq<MaybeLazy<T2, F2>> for MaybeLazy<T1, F1>
+{
+ #[inline]
+ fn eq(&self, other: &MaybeLazy<T2, F2>) -> bool {
+ PartialEq::eq(&**self, &**other)
+ }
+}
+
+impl<F: FnOnce() -> String> PartialEq<&str> for MaybeLazy<str, F> {
+ #[inline]
+ fn eq(&self, other: &&str) -> bool {
+ &**self == *other
+ }
+}
+
+impl<F: FnOnce() -> String> From<&'static str> for MaybeLazy<str, F> {
+ #[inline]
+ fn from(s: &'static str) -> MaybeLazy<str, F> {
+ 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<LinkerFlavor, Vec<StaticCow<str>>>;
-pub type LinkArgsCli = BTreeMap<LinkerFlavorCli, Vec<StaticCow<str>>>;
-
/// 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<str>,
+ pub llvm_target: MaybeLazy<str>,
/// 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::<u32>()
@@ -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 <https://github.com/rustwasm>.
-
-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 {