diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index ecc91ab9a310e..2962b0ab61e7f 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -12,11 +12,13 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![doc(rust_logo)] #![feature(assert_matches)] +#![feature(fn_traits)] #![feature(iter_intersperse)] #![feature(let_chains)] #![feature(min_exhaustive_patterns)] #![feature(rustc_attrs)] #![feature(rustdoc_internals)] +#![feature(unboxed_closures)] // tidy-alphabetical-end use std::path::{Path, PathBuf}; diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs index 055420090835d..391ec6078c27b 100644 --- a/compiler/rustc_target/src/spec/base/apple/mod.rs +++ b/compiler/rustc_target/src/spec/base/apple/mod.rs @@ -1,6 +1,7 @@ use std::{borrow::Cow, env}; -use crate::spec::{add_link_args, add_link_args_iter}; +use crate::spec::link_args::LazyLinkArgsState; +use crate::spec::{add_link_args, add_link_args_iter, MaybeLazy}; use crate::spec::{cvs, Cc, DebuginfoKind, FramePointer, LinkArgs, LinkerFlavor, Lld}; use crate::spec::{SplitDebuginfo, StackProbeType, StaticCow, Target, TargetOptions}; @@ -94,7 +95,10 @@ impl TargetAbi { } } -fn pre_link_args(os: &'static str, arch: Arch, abi: TargetAbi) -> LinkArgs { +pub(crate) type ApplePreLinkArgs = + (/*os:*/ &'static str, /*arch:*/ Arch, /*abi:*/ TargetAbi); + +pub(crate) fn pre_link_args((os, arch, abi): ApplePreLinkArgs) -> LinkArgs { let platform_name: StaticCow = match abi { TargetAbi::Normal => os.into(), TargetAbi::Simulator => format!("{os}-simulator").into(), @@ -114,7 +118,9 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: TargetAbi) -> LinkArgs { }; let sdk_version = min_version.clone(); - let mut args = TargetOptions::link_args( + let mut args = LinkArgs::new(); + add_link_args( + &mut args, LinkerFlavor::Darwin(Cc::No, Lld::No), &["-arch", arch.target_name(), "-platform_version"], ); @@ -151,7 +157,7 @@ pub fn opts(os: &'static str, arch: Arch, abi: TargetAbi) -> TargetOptions { // macOS has -dead_strip, which doesn't rely on function_sections function_sections: false, dynamic_linking: true, - pre_link_args: pre_link_args(os, arch, abi), + pre_link_args: MaybeLazy::lazied(LazyLinkArgsState::Apple((os, arch, abi))), families: cvs!["unix"], is_like_osx: true, // LLVM notes that macOS 10.11+ and iOS 9+ default diff --git a/compiler/rustc_target/src/spec/base/avr_gnu.rs b/compiler/rustc_target/src/spec/base/avr_gnu.rs index 211d52f5b07ed..27bc5a1c9ea8a 100644 --- a/compiler/rustc_target/src/spec/base/avr_gnu.rs +++ b/compiler/rustc_target/src/spec/base/avr_gnu.rs @@ -4,8 +4,7 @@ use object::elf; /// A base target for AVR devices using the GNU toolchain. /// /// Requires GNU avr-gcc and avr-binutils on the host system. -/// FIXME: Remove the second parameter when const string concatenation is possible. -pub fn target(target_cpu: &'static str, mmcu: &'static str) -> Target { +pub fn target(target_cpu: &'static str) -> Target { Target { arch: "avr".into(), metadata: crate::spec::TargetMetadata { @@ -24,7 +23,10 @@ pub fn target(target_cpu: &'static str, mmcu: &'static str) -> Target { linker: Some("avr-gcc".into()), eh_frame_header: false, - pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[mmcu]), + pre_link_args: TargetOptions::link_args( + LinkerFlavor::Gnu(Cc::Yes, Lld::No), + &["-mmcu=atmega328"], + ), late_link_args: TargetOptions::link_args( LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-lgcc"], diff --git a/compiler/rustc_target/src/spec/base/teeos.rs b/compiler/rustc_target/src/spec/base/teeos.rs index 38d0a6d73140a..d50cf9c0db419 100644 --- a/compiler/rustc_target/src/spec/base/teeos.rs +++ b/compiler/rustc_target/src/spec/base/teeos.rs @@ -1,11 +1,15 @@ -use crate::spec::{add_link_args, Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, TargetOptions}; pub fn opts() -> TargetOptions { - let lld_args = &["-zmax-page-size=4096", "-znow", "-ztext", "--execute-only"]; - let cc_args = &["-Wl,-zmax-page-size=4096", "-Wl,-znow", "-Wl,-ztext", "-mexecute-only"]; - - let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), lld_args); - add_link_args(&mut pre_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), cc_args); + let pre_link_args = { + const LLD_ARGS: &[&str] = &["-zmax-page-size=4096", "-znow", "-ztext", "--execute-only"]; + const CC_ARGS: &[&str] = + &["-Wl,-zmax-page-size=4096", "-Wl,-znow", "-Wl,-ztext", "-mexecute-only"]; + TargetOptions::link_args_list(&[ + (LinkerFlavor::Gnu(Cc::No, Lld::No), LLD_ARGS), + (LinkerFlavor::Gnu(Cc::Yes, Lld::No), CC_ARGS), + ]) + }; TargetOptions { os: "teeos".into(), diff --git a/compiler/rustc_target/src/spec/base/uefi_msvc.rs b/compiler/rustc_target/src/spec/base/uefi_msvc.rs index e8acd6078e2ad..8d908144d58c2 100644 --- a/compiler/rustc_target/src/spec/base/uefi_msvc.rs +++ b/compiler/rustc_target/src/spec/base/uefi_msvc.rs @@ -9,12 +9,13 @@ // the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all // code runs in the same environment, no process separation is supported. -use crate::spec::{base, LinkerFlavor, Lld, PanicStrategy, StackProbeType, TargetOptions}; +use crate::spec::{base, LinkerFlavor, Lld}; +use crate::spec::{PanicStrategy, StackProbeType, TargetOptions}; pub fn opts() -> TargetOptions { let mut base = base::msvc::opts(); - base.add_pre_link_args( + base.pre_link_args = TargetOptions::link_args( LinkerFlavor::Msvc(Lld::No), &[ // Non-standard subsystems have no default entry-point in PE+ files. We have to define diff --git a/compiler/rustc_target/src/spec/base/wasm.rs b/compiler/rustc_target/src/spec/base/wasm.rs index f237391016e77..26d795834fb0b 100644 --- a/compiler/rustc_target/src/spec/base/wasm.rs +++ b/compiler/rustc_target/src/spec/base/wasm.rs @@ -1,7 +1,5 @@ -use crate::spec::{ - add_link_args, cvs, Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy, RelocModel, - TargetOptions, TlsModel, -}; +use crate::spec::{cvs, Cc, LinkSelfContainedDefault, LinkerFlavor, PanicStrategy}; +use crate::spec::{RelocModel, TargetOptions, TlsModel}; pub fn options() -> TargetOptions { macro_rules! args { @@ -48,8 +46,10 @@ pub fn options() -> TargetOptions { }; } - let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::WasmLld(Cc::No), args!("")); - add_link_args(&mut pre_link_args, LinkerFlavor::WasmLld(Cc::Yes), args!("-Wl,")); + let pre_link_args = TargetOptions::link_args_list(&[ + (LinkerFlavor::WasmLld(Cc::No), args!("")), + (LinkerFlavor::WasmLld(Cc::Yes), args!("-Wl,")), + ]); TargetOptions { is_like_wasm: true, diff --git a/compiler/rustc_target/src/spec/base/windows_gnu.rs b/compiler/rustc_target/src/spec/base/windows_gnu.rs index 1357de2dad126..4d8e2c361db59 100644 --- a/compiler/rustc_target/src/spec/base/windows_gnu.rs +++ b/compiler/rustc_target/src/spec/base/windows_gnu.rs @@ -1,78 +1,80 @@ +use crate::spec::crt_objects; use crate::spec::LinkSelfContainedDefault; -use crate::spec::{add_link_args, crt_objects}; use crate::spec::{cvs, Cc, DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions}; use std::borrow::Cow; pub fn opts() -> TargetOptions { - let mut pre_link_args = TargetOptions::link_args( - LinkerFlavor::Gnu(Cc::No, Lld::No), - &[ - // Enable ASLR - "--dynamicbase", - // ASLR will rebase it anyway so leaving that option enabled only leads to confusion - "--disable-auto-image-base", - ], - ); - add_link_args( - &mut pre_link_args, - LinkerFlavor::Gnu(Cc::Yes, Lld::No), - &[ - // Tell GCC to avoid linker plugins, because we are not bundling - // them with Windows installer, and Rust does its own LTO anyways. - "-fno-use-linker-plugin", - "-Wl,--dynamicbase", - "-Wl,--disable-auto-image-base", - ], - ); + let pre_link_args = TargetOptions::link_args_list(&[ + ( + LinkerFlavor::Gnu(Cc::No, Lld::No), + &[ + // Enable ASLR + "--dynamicbase", + // ASLR will rebase it anyway so leaving that option enabled only leads to confusion + "--disable-auto-image-base", + ], + ), + ( + LinkerFlavor::Gnu(Cc::Yes, Lld::No), + &[ + // Tell GCC to avoid linker plugins, because we are not bundling + // them with Windows installer, and Rust does its own LTO anyways. + "-fno-use-linker-plugin", + "-Wl,--dynamicbase", + "-Wl,--disable-auto-image-base", + ], + ), + ]); - // Order of `late_link_args*` was found through trial and error to work with various - // mingw-w64 versions (not tested on the CI). It's expected to change from time to time. - let mingw_libs = &[ - "-lmsvcrt", - "-lmingwex", - "-lmingw32", - "-lgcc", // alas, mingw* libraries above depend on libgcc - // mingw's msvcrt is a weird hybrid import library and static library. - // And it seems that the linker fails to use import symbols from msvcrt - // that are required from functions in msvcrt in certain cases. For example - // `_fmode` that is used by an implementation of `__p__fmode` in x86_64. - // The library is purposely listed twice to fix that. - // - // See https://github.com/rust-lang/rust/pull/47483 for some more details. - "-lmsvcrt", - // Math functions missing in MSVCRT (they are present in UCRT) require - // this dependency cycle: `libmingwex.a` -> `libmsvcrt.a` -> `libmingwex.a`. - "-lmingwex", - "-luser32", - "-lkernel32", - ]; - let mut late_link_args = - TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs); - add_link_args(&mut late_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), mingw_libs); + let late_link_args = { + // Order of `late_link_args*` was found through trial and error to work with various + // mingw-w64 versions (not tested on the CI). It's expected to change from time to time. + const MINGW_LIBS: &[&str] = &[ + "-lmsvcrt", + "-lmingwex", + "-lmingw32", + "-lgcc", // alas, mingw* libraries above depend on libgcc + // mingw's msvcrt is a weird hybrid import library and static library. + // And it seems that the linker fails to use import symbols from msvcrt + // that are required from functions in msvcrt in certain cases. For example + // `_fmode` that is used by an implementation of `__p__fmode` in x86_64. + // The library is purposely listed twice to fix that. + // + // See https://github.com/rust-lang/rust/pull/47483 for some more details. + "-lmsvcrt", + // Math functions missing in MSVCRT (they are present in UCRT) require + // this dependency cycle: `libmingwex.a` -> `libmsvcrt.a` -> `libmingwex.a`. + "-lmingwex", + "-luser32", + "-lkernel32", + ]; + TargetOptions::link_args_list(&[ + (LinkerFlavor::Gnu(Cc::No, Lld::No), MINGW_LIBS), + (LinkerFlavor::Gnu(Cc::Yes, Lld::No), MINGW_LIBS), + ]) + }; // If any of our crates are dynamically linked then we need to use // the shared libgcc_s-dw2-1.dll. This is required to support // unwinding across DLL boundaries. - let dynamic_unwind_libs = &["-lgcc_s"]; - let mut late_link_args_dynamic = - TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), dynamic_unwind_libs); - add_link_args( - &mut late_link_args_dynamic, - LinkerFlavor::Gnu(Cc::Yes, Lld::No), - dynamic_unwind_libs, - ); + let late_link_args_dynamic = { + const DYNAMIC_UNWIND_LIBS: &[&str] = &["-lgcc_s"]; + TargetOptions::link_args_list(&[ + (LinkerFlavor::Gnu(Cc::No, Lld::No), DYNAMIC_UNWIND_LIBS), + (LinkerFlavor::Gnu(Cc::Yes, Lld::No), DYNAMIC_UNWIND_LIBS), + ]) + }; // If all of our crates are statically linked then we can get away // with statically linking the libgcc unwinding code. This allows // binaries to be redistributed without the libgcc_s-dw2-1.dll // dependency, but unfortunately break unwinding across DLL // boundaries when unwinding across FFI boundaries. - let static_unwind_libs = &["-lgcc_eh", "-l:libpthread.a"]; - let mut late_link_args_static = - TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), static_unwind_libs); - add_link_args( - &mut late_link_args_static, - LinkerFlavor::Gnu(Cc::Yes, Lld::No), - static_unwind_libs, - ); + let late_link_args_static = { + const STATIC_UNWIND_LIBS: &[&str] = &["-lgcc_eh", "-l:libpthread.a"]; + TargetOptions::link_args_list(&[ + (LinkerFlavor::Gnu(Cc::No, Lld::No), STATIC_UNWIND_LIBS), + (LinkerFlavor::Gnu(Cc::Yes, Lld::No), STATIC_UNWIND_LIBS), + ]) + }; TargetOptions { os: "windows".into(), diff --git a/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs b/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs index 17256e18e24e3..a6bd247cf606f 100644 --- a/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs +++ b/compiler/rustc_target/src/spec/base/windows_uwp_gnu.rs @@ -1,26 +1,29 @@ -use crate::spec::{add_link_args, base, Cc, LinkArgs, LinkerFlavor, Lld, TargetOptions}; +use crate::spec::{base, Cc, LinkerFlavor, Lld, TargetOptions}; pub fn opts() -> TargetOptions { let base = base::windows_gnu::opts(); - // FIXME: This should be updated for the exception machinery changes from #67502 - // and inherit from `windows_gnu_base`, at least partially. - let mingw_libs = &[ - "-lwinstorecompat", - "-lruntimeobject", - "-lsynchronization", - "-lvcruntime140_app", - "-lucrt", - "-lwindowsapp", - "-lmingwex", - "-lmingw32", - ]; - let mut late_link_args = - TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs); - add_link_args(&mut late_link_args, LinkerFlavor::Gnu(Cc::Yes, Lld::No), mingw_libs); + let late_link_args = { + // FIXME: This should be updated for the exception machinery changes from #67502 + // and inherit from `windows_gnu_base`, at least partially. + const MINGW_LIBS: &[&str] = &[ + "-lwinstorecompat", + "-lruntimeobject", + "-lsynchronization", + "-lvcruntime140_app", + "-lucrt", + "-lwindowsapp", + "-lmingwex", + "-lmingw32", + ]; + TargetOptions::link_args_list(&[ + (LinkerFlavor::Gnu(Cc::No, Lld::No), MINGW_LIBS), + (LinkerFlavor::Gnu(Cc::Yes, Lld::No), MINGW_LIBS), + ]) + }; // Reset the flags back to empty until the FIXME above is addressed. - let late_link_args_dynamic = LinkArgs::new(); - let late_link_args_static = LinkArgs::new(); + let late_link_args_dynamic = Default::default(); + let late_link_args_static = Default::default(); TargetOptions { abi: "uwp".into(), diff --git a/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs b/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs index 59a7616712541..a4140f4ea4fe7 100644 --- a/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs +++ b/compiler/rustc_target/src/spec/base/windows_uwp_msvc.rs @@ -5,7 +5,8 @@ pub fn opts() -> TargetOptions { opts.abi = "uwp".into(); opts.vendor = "uwp".into(); - opts.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &["/APPCONTAINER", "mincore.lib"]); + opts.pre_link_args = + TargetOptions::link_args(LinkerFlavor::Msvc(Lld::No), &["/APPCONTAINER", "mincore.lib"]); opts } diff --git a/compiler/rustc_target/src/spec/link_args.rs b/compiler/rustc_target/src/spec/link_args.rs new file mode 100644 index 0000000000000..53233ebfa593d --- /dev/null +++ b/compiler/rustc_target/src/spec/link_args.rs @@ -0,0 +1,41 @@ +//! Linker arguments + +use crate::spec::add_link_args; +use crate::spec::{LinkerFlavor, LinkerFlavorCli}; +use crate::spec::{MaybeLazy, StaticCow}; + +use std::collections::BTreeMap; + +pub type LinkArgs = BTreeMap>>; +pub type LinkArgsCli = BTreeMap>>; + +pub type LazyLinkArgs = MaybeLazy; + +pub enum LazyLinkArgsState { + Simple(LinkerFlavor, &'static [&'static str]), + List(&'static [(LinkerFlavor, &'static [&'static str])]), + Apple(super::base::apple::ApplePreLinkArgs), +} + +impl FnOnce<()> for LazyLinkArgsState { + type Output = LinkArgs; + + #[inline] + extern "rust-call" fn call_once(self, _args: ()) -> Self::Output { + match self { + LazyLinkArgsState::Simple(flavor, args) => { + let mut link_args = LinkArgs::new(); + add_link_args(&mut link_args, flavor, args); + link_args + } + LazyLinkArgsState::List(l) => { + let mut link_args = LinkArgs::new(); + for (flavor, args) in l { + add_link_args(&mut link_args, *flavor, args) + } + link_args + } + LazyLinkArgsState::Apple(args) => super::base::apple::pre_link_args(args), + } + } +} diff --git a/compiler/rustc_target/src/spec/maybe_lazy.rs b/compiler/rustc_target/src/spec/maybe_lazy.rs new file mode 100644 index 0000000000000..3694679b01f1c --- /dev/null +++ b/compiler/rustc_target/src/spec/maybe_lazy.rs @@ -0,0 +1,144 @@ +//! A custom LazyLock+Cow suitable for holding borrowed, owned or lazy data. + +use std::borrow::{Borrow, Cow}; +use std::fmt::{Debug, Display}; +use std::ops::Deref; +use std::sync::LazyLock; + +enum MaybeLazyInner { + Lazy(LazyLock), + Cow(Cow<'static, T>), +} + +/// A custom LazyLock+Cow suitable for holding borrowed, owned or lazy data. +/// +/// Technically this structure has 3 states: borrowed, owned and lazy +/// They can all be constructed from the [`MaybeLazy::borrowed`], [`MaybeLazy::owned`] and +/// [`MaybeLazy::lazy`] methods. +#[repr(transparent)] +pub struct MaybeLazy ::Owned> { + // Inner state. + // + // Not to be inlined since we may want in the future to + // make this struct usable to statics and we might need to + // workaround const-eval limitation (particulary around drop). + inner: MaybeLazyInner, +} + +impl T::Owned> MaybeLazy { + /// Create a [`MaybeLazy`] from an borrowed `T`. + #[inline] + pub const fn borrowed(a: &'static T) -> Self { + MaybeLazy { inner: MaybeLazyInner::Cow(Cow::Borrowed(a)) } + } + + /// Create a [`MaybeLazy`] from an borrowed `T`. + #[inline] + pub const fn owned(a: T::Owned) -> Self { + MaybeLazy { inner: MaybeLazyInner::Cow(Cow::Owned(a)) } + } + + /// Create a [`MaybeLazy`] from a function-able `F`. + #[inline] + pub const fn lazied(f: F) -> Self { + MaybeLazy { inner: MaybeLazyInner::Lazy(LazyLock::new(f)) } + } +} + +impl MaybeLazy { + /// Create a [`MaybeLazy`] from a function pointer. + #[inline] + pub const fn lazy(a: fn() -> T::Owned) -> Self { + Self::lazied(a) + } +} + +impl, F: FnOnce() -> T::Owned> Clone + for MaybeLazy +{ + #[inline] + fn clone(&self) -> Self { + MaybeLazy { + inner: MaybeLazyInner::Cow(match &self.inner { + MaybeLazyInner::Lazy(f) => Cow::Owned((*f).to_owned()), + MaybeLazyInner::Cow(c) => c.clone(), + }), + } + } +} + +impl, F: FnOnce() -> T::Owned> Default + for MaybeLazy +{ + #[inline] + fn default() -> MaybeLazy { + MaybeLazy::owned(T::Owned::default()) + } +} + +// `Debug`, `Display` and other traits below are implemented in terms of this `Deref` +impl>, F: FnOnce() -> T::Owned> Deref + for MaybeLazy +{ + type Target = T; + + #[inline] + fn deref(&self) -> &T { + match &self.inner { + MaybeLazyInner::Lazy(f) => (&**f).borrow(), + MaybeLazyInner::Cow(c) => &*c, + } + } +} + +impl + Debug, F: FnOnce() -> T::Owned> Debug + for MaybeLazy +{ + #[inline] + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Debug::fmt(&**self, fmt) + } +} + +impl + Display, F: FnOnce() -> T::Owned> Display + for MaybeLazy +{ + #[inline] + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Display::fmt(&**self, fmt) + } +} + +impl T::Owned> AsRef for MaybeLazy { + #[inline] + fn as_ref(&self) -> &T { + &**self + } +} + +impl< + T1: ?Sized + PartialEq + ToOwned, + T2: ?Sized + ToOwned, + F1: FnOnce() -> T1::Owned, + F2: FnOnce() -> T2::Owned, +> PartialEq> for MaybeLazy +{ + #[inline] + fn eq(&self, other: &MaybeLazy) -> bool { + PartialEq::eq(&**self, &**other) + } +} + +impl String> PartialEq<&str> for MaybeLazy { + #[inline] + fn eq(&self, other: &&str) -> bool { + &**self == *other + } +} + +impl String> From<&'static str> for MaybeLazy { + #[inline] + fn from(s: &'static str) -> MaybeLazy { + MaybeLazy::borrowed(s) + } +} diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 607eeac7ccdc3..da6c2e0321567 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -39,6 +39,8 @@ 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::link_args::{LazyLinkArgs, LinkArgs, LinkArgsCli}; +use crate::spec::maybe_lazy::MaybeLazy; use rustc_fs_util::try_canonicalize; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; @@ -55,6 +57,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; @@ -1102,9 +1106,6 @@ impl fmt::Display for LinkOutputKind { } } -pub type LinkArgs = BTreeMap>>; -pub type LinkArgsCli = BTreeMap>>; - /// Which kind of debuginfo does the target use? /// /// Useful in determining whether a target supports Split DWARF (a target with @@ -2041,24 +2042,24 @@ pub struct TargetOptions { 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. @@ -2405,14 +2406,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) { @@ -2421,14 +2422,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. @@ -2439,9 +2440,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); } } @@ -2523,15 +2525,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![], 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 7f05358e01610..02ba88ba95195 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 429303170b6b8..f3fd5706cff78 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/arm64ec_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/targets/arm64ec_pc_windows_msvc.rs index 21cb38868fb92..56d36aed24f3a 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 8f6a58a1b4982..5331523d1871b 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/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/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs index 02f6bec4692fc..d73d8ca65f74b 100644 --- a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs @@ -6,7 +6,8 @@ pub fn target() -> Target { let arch = Arch::I386; let mut base = opts("macos", arch, TargetAbi::Normal); 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 { 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 4b0f4bf3ecd25..17293effd11da 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 5bb082014298a..0574f07f6df3e 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 cce21fcacb1c5..eb068022436be 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 84ef00f06c810..3b02f891c5269 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 ad8c0f7f582e7..0b368d2c00a29 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 5584435a0ad9d..9848271b8503e 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 d1ab1f73b511b..21b5bc3be2b0c 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 255148fca9a31..ed415ec7bcaef 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 d6df801234c66..3ab3d60cb131f 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 851bea80fb830..261d0a3970c73 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 cd488d0532c2f..4dbc6181a8d42 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 973c75eeca6e1..7497f45cc7d5c 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 bda43e7a2b0f1..1709f54d68bf7 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 6eb5bba0fcd99..73230417a31a9 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 53b84479a4919..f1a4ea69dfe75 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 0d0484dd17480..0c2977b4a2aae 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 2922c921e17d1..4a73572d0c2e3 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 dd2ec27420762..f279e0f6b0a5a 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 ea295cf169e0e..7346b2d580f1a 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 dc70bd238a749..6ddaa71b1852b 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 dbfbd69b95b17..01fa57da50686 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 2f7acccfae83b..a822a2350d826 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 2ecafbb08bc33..4c12a4d3c0be7 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 04b2309fdc887..4495b3f456f24 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 108e468eb66ba..fa95dcfb2e39e 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 3ee6cd46c8535..0a3f4ac6e1740 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 5d107d6e60ecd..275f6da435a37 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 aea525a69123f..461bbe9994a7a 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 69bb6e1fb60e4..dde8f3d40bb37 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 08f6eaf836176..eb13be4f1c675 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/sparcv9_sun_solaris.rs b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs index 1c0adadece0be..f766e273c8014 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 e36aa5ab395da..3226c5717a9ea 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 c562f57252e59..de91c9c2333f0 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 46257a272d1e1..5fbcd87933166 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 bf92f30e8b372..24116519a0a24 100644 --- a/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs +++ b/compiler/rustc_target/src/spec/targets/wasm32_unknown_unknown.rs @@ -9,30 +9,31 @@ //! //! This target is more or less managed by the Rust and WebAssembly Working //! Group nowadays at . - -use crate::spec::{base, Cc, LinkerFlavor, Target}; +use crate::spec::{base, Cc, LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut options = base::wasm::options(); options.os = "unknown".into(); - options.add_pre_link_args( - LinkerFlavor::WasmLld(Cc::No), - &[ - // For now this target just never has an entry symbol no matter the output - // type, so unconditionally pass this. - "--no-entry", - ], - ); - options.add_pre_link_args( - LinkerFlavor::WasmLld(Cc::Yes), - &[ - // Make sure clang uses LLD as its linker and is configured appropriately - // otherwise - "--target=wasm32-unknown-unknown", - "-Wl,--no-entry", - ], - ); + options.pre_link_args = TargetOptions::link_args_list(&[ + ( + LinkerFlavor::WasmLld(Cc::No), + &[ + // For now this target just never has an entry symbol no matter the output + // type, so unconditionally pass this. + "--no-entry", + ], + ), + ( + LinkerFlavor::WasmLld(Cc::Yes), + &[ + // Make sure clang uses LLD as its linker and is configured appropriately + // otherwise + "--target=wasm32-unknown-unknown", + "-Wl,--no-entry", + ], + ), + ]); Target { llvm_target: "wasm32-unknown-unknown".into(), diff --git a/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs b/compiler/rustc_target/src/spec/targets/wasm32_wasip1.rs index a8e7f22c06894..e065a2181c71b 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 4e60806f3a736..922497a90399c 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 bc49a3c9f70d0..aef132ea74043 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 94638ae62f834..2c92be52d7c72 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 @@ -7,7 +7,8 @@ pub fn target() -> Target { let mut base = opts("macos", arch, TargetAbi::Normal); 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; 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 257093b75545d..777e11c254dd4 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 697daf590ad01..2575bdca8f55e 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 89a9bb1e1cc53..4564e1f61c18d 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 acf0fd421bac9..a771dffea38e6 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 171a6f2a51e7c..de5174ac7284e 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 4692b5a3c74ef..806c1b3bb7142 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 b593b79e7bbd4..df4c8f600ed38 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 d683a44202740..d7a62c1b02175 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 4a92d4ef9d5ca..15a7268685487 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 3c7db0095a148..40a696fc66767 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 109fc3c0728d8..2c203b508e27d 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 c1d888899fc21..7ad4eaefcfe00 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 d413caf4aaf77..18e74b1f08698 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 8f1c3ef9bc7bb..38d5b61f70005 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 ae38f63f034f7..7cca8ab77381d 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 c71bc9ed92317..56bfa64d2e5e0 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 7b40f7366d0f3..8e6ca49c0b689 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 72cbc1be9310b..8fd92350d1a81 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 @@ -7,7 +7,8 @@ pub fn target() -> Target { let mut base = opts("macos", arch, TargetAbi::Normal); 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; 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 {