From 572b6a9c604288c356242f7a67d8174bbdbae19d Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sat, 6 Aug 2022 21:08:46 +0300 Subject: [PATCH] rustc_target: Refactor internal linker flavors In accordance with the design from https://github.com/rust-lang/rust/pull/96827#issuecomment-1208441595 --- compiler/rustc_codegen_ssa/src/back/link.rs | 75 +++--- compiler/rustc_codegen_ssa/src/back/linker.rs | 82 +++---- .../src/spec/aarch64_apple_ios_macabi.rs | 4 +- .../aarch64_nintendo_switch_freestanding.rs | 4 +- .../src/spec/aarch64_unknown_none.rs | 4 +- .../spec/aarch64_unknown_none_softfloat.rs | 4 +- .../src/spec/aarch64_unknown_uefi.rs | 4 +- compiler/rustc_target/src/spec/apple_base.rs | 22 +- .../src/spec/armebv7r_none_eabi.rs | 5 +- .../src/spec/armebv7r_none_eabihf.rs | 5 +- .../rustc_target/src/spec/armv4t_none_eabi.rs | 4 +- .../src/spec/armv6k_nintendo_3ds.rs | 5 +- .../src/spec/armv7_linux_androideabi.rs | 4 +- .../rustc_target/src/spec/armv7a_none_eabi.rs | 4 +- .../src/spec/armv7a_none_eabihf.rs | 4 +- .../rustc_target/src/spec/armv7r_none_eabi.rs | 5 +- .../src/spec/armv7r_none_eabihf.rs | 5 +- .../rustc_target/src/spec/avr_gnu_base.rs | 9 +- .../rustc_target/src/spec/fuchsia_base.rs | 6 +- compiler/rustc_target/src/spec/hermit_base.rs | 6 +- .../src/spec/hexagon_unknown_linux_musl.rs | 4 +- .../src/spec/i686_apple_darwin.rs | 4 +- .../src/spec/i686_pc_windows_gnu.rs | 9 +- .../src/spec/i686_pc_windows_msvc.rs | 4 +- .../src/spec/i686_unknown_freebsd.rs | 4 +- .../src/spec/i686_unknown_haiku.rs | 4 +- .../src/spec/i686_unknown_linux_gnu.rs | 4 +- .../src/spec/i686_unknown_linux_musl.rs | 4 +- .../src/spec/i686_unknown_netbsd.rs | 4 +- .../src/spec/i686_unknown_openbsd.rs | 4 +- .../src/spec/i686_uwp_windows_gnu.rs | 9 +- .../rustc_target/src/spec/i686_wrs_vxworks.rs | 4 +- .../rustc_target/src/spec/illumos_base.rs | 6 +- compiler/rustc_target/src/spec/l4re_base.rs | 5 +- .../rustc_target/src/spec/mipsel_sony_psp.rs | 10 +- .../src/spec/mipsel_unknown_none.rs | 5 +- compiler/rustc_target/src/spec/mod.rs | 229 ++++++++++++++---- .../rustc_target/src/spec/msp430_none_elf.rs | 4 +- compiler/rustc_target/src/spec/msvc_base.rs | 8 +- .../src/spec/nvptx64_nvidia_cuda.rs | 1 - .../src/spec/powerpc64_unknown_freebsd.rs | 4 +- .../src/spec/powerpc64_unknown_linux_gnu.rs | 4 +- .../src/spec/powerpc64_unknown_linux_musl.rs | 4 +- .../src/spec/powerpc64_unknown_openbsd.rs | 4 +- .../src/spec/powerpc64_wrs_vxworks.rs | 4 +- .../src/spec/powerpc64le_unknown_freebsd.rs | 4 +- .../src/spec/powerpc64le_unknown_linux_gnu.rs | 4 +- .../spec/powerpc64le_unknown_linux_musl.rs | 4 +- .../src/spec/powerpc_unknown_freebsd.rs | 7 +- .../src/spec/powerpc_unknown_linux_gnu.rs | 4 +- .../src/spec/powerpc_unknown_linux_gnuspe.rs | 4 +- .../src/spec/powerpc_unknown_linux_musl.rs | 4 +- .../src/spec/powerpc_unknown_netbsd.rs | 4 +- .../src/spec/powerpc_wrs_vxworks.rs | 4 +- .../src/spec/powerpc_wrs_vxworks_spe.rs | 4 +- .../src/spec/riscv32i_unknown_none_elf.rs | 5 +- .../src/spec/riscv32im_unknown_none_elf.rs | 5 +- .../src/spec/riscv32imac_unknown_none_elf.rs | 5 +- .../src/spec/riscv32imac_unknown_xous_elf.rs | 5 +- .../src/spec/riscv32imc_esp_espidf.rs | 4 +- .../src/spec/riscv32imc_unknown_none_elf.rs | 5 +- .../src/spec/riscv64gc_unknown_none_elf.rs | 6 +- .../src/spec/riscv64imac_unknown_none_elf.rs | 6 +- .../rustc_target/src/spec/solaris_base.rs | 4 +- .../src/spec/sparc64_unknown_netbsd.rs | 4 +- .../src/spec/sparc64_unknown_openbsd.rs | 4 +- .../src/spec/sparc_unknown_linux_gnu.rs | 4 +- .../src/spec/sparcv9_sun_solaris.rs | 4 +- .../rustc_target/src/spec/tests/tests_impl.rs | 85 +++---- compiler/rustc_target/src/spec/thumb_base.rs | 5 +- .../src/spec/thumbv4t_none_eabi.rs | 7 +- .../src/spec/thumbv7a_pc_windows_msvc.rs | 4 +- .../src/spec/thumbv7neon_linux_androideabi.rs | 4 +- .../rustc_target/src/spec/uefi_msvc_base.rs | 7 +- .../src/spec/wasm32_unknown_unknown.rs | 8 +- compiler/rustc_target/src/spec/wasm32_wasi.rs | 6 +- .../src/spec/wasm64_unknown_unknown.rs | 8 +- compiler/rustc_target/src/spec/wasm_base.rs | 9 +- .../rustc_target/src/spec/windows_gnu_base.rs | 28 ++- .../src/spec/windows_gnullvm_base.rs | 10 +- .../src/spec/windows_uwp_gnu_base.rs | 7 +- .../src/spec/windows_uwp_msvc_base.rs | 4 +- .../src/spec/x86_64_apple_darwin.rs | 6 +- .../src/spec/x86_64_apple_ios_macabi.rs | 4 +- .../src/spec/x86_64_fortanix_unknown_sgx.rs | 8 +- .../src/spec/x86_64_linux_android.rs | 4 +- .../src/spec/x86_64_pc_solaris.rs | 4 +- .../src/spec/x86_64_pc_windows_gnu.rs | 9 +- .../src/spec/x86_64_pc_windows_gnullvm.rs | 4 +- .../src/spec/x86_64_sun_solaris.rs | 4 +- .../src/spec/x86_64_unknown_dragonfly.rs | 4 +- .../src/spec/x86_64_unknown_freebsd.rs | 4 +- .../src/spec/x86_64_unknown_haiku.rs | 4 +- .../src/spec/x86_64_unknown_illumos.rs | 4 +- .../src/spec/x86_64_unknown_linux_gnu.rs | 4 +- .../src/spec/x86_64_unknown_linux_gnux32.rs | 4 +- .../src/spec/x86_64_unknown_linux_musl.rs | 4 +- .../src/spec/x86_64_unknown_netbsd.rs | 4 +- .../src/spec/x86_64_unknown_none.rs | 4 +- .../spec/x86_64_unknown_none_linuxkernel.rs | 4 +- .../src/spec/x86_64_unknown_openbsd.rs | 4 +- .../src/spec/x86_64_unknown_redox.rs | 4 +- .../src/spec/x86_64_uwp_windows_gnu.rs | 9 +- .../src/spec/x86_64_wrs_vxworks.rs | 4 +- 104 files changed, 569 insertions(+), 438 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index bb57fca74a21e..6131bb4baf5ac 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -23,8 +23,8 @@ use rustc_session::{filesearch, Session}; use rustc_span::symbol::Symbol; use rustc_span::DebuggerVisualizerFile; use rustc_target::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault}; -use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor, SplitDebuginfo}; -use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, SanitizerSet, Target}; +use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy}; +use rustc_target::spec::{RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, Target}; use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder}; use super::command::Command; @@ -748,8 +748,7 @@ fn link_natively<'a>( // then it should not default to linking executables as pie. Different // versions of gcc seem to use different quotes in the error message so // don't check for them. - if sess.target.linker_is_gnu - && flavor != LinkerFlavor::Ld + if matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _)) && unknown_arg_regex.is_match(&out) && out.contains("-no-pie") && cmd.get_args().iter().any(|e| e.to_string_lossy() == "-no-pie") @@ -767,8 +766,7 @@ fn link_natively<'a>( // Detect '-static-pie' used with an older version of gcc or clang not supporting it. // Fallback from '-static-pie' to '-static' in that case. - if sess.target.linker_is_gnu - && flavor != LinkerFlavor::Ld + if matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _)) && unknown_arg_regex.is_match(&out) && (out.contains("-static-pie") || out.contains("--no-dynamic-linker")) && cmd.get_args().iter().any(|e| e.to_string_lossy() == "-static-pie") @@ -903,7 +901,7 @@ fn link_natively<'a>( // install the Visual Studio build tools. if let Some(code) = prog.status.code() { if sess.target.is_like_msvc - && flavor == LinkerFlavor::Msvc + && flavor == LinkerFlavor::Msvc(Lld::No) // Respect the command line override && sess.opts.cg.linker.is_none() // Match exactly "link.exe" @@ -1187,7 +1185,10 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { // only the linker flavor is known; use the default linker for the selected flavor (None, Some(flavor)) => Some(( PathBuf::from(match flavor { - LinkerFlavor::Gcc => { + LinkerFlavor::Gnu(Cc::Yes, _) + | LinkerFlavor::Darwin(Cc::Yes, _) + | LinkerFlavor::WasmLld(Cc::Yes) + | LinkerFlavor::Unix(Cc::Yes) => { if cfg!(any(target_os = "solaris", target_os = "illumos")) { // On historical Solaris systems, "cc" may have // been Sun Studio, which is not flag-compatible @@ -1200,9 +1201,14 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { "cc" } } - LinkerFlavor::Ld => "ld", - LinkerFlavor::Lld(_) => "lld", - LinkerFlavor::Msvc => "link.exe", + LinkerFlavor::Gnu(_, Lld::Yes) + | LinkerFlavor::Darwin(_, Lld::Yes) + | LinkerFlavor::WasmLld(..) + | LinkerFlavor::Msvc(Lld::Yes) => "lld", + LinkerFlavor::Gnu(..) | LinkerFlavor::Darwin(..) | LinkerFlavor::Unix(..) => { + "ld" + } + LinkerFlavor::Msvc(..) => "link.exe", LinkerFlavor::EmCc => { if cfg!(windows) { "emcc.bat" @@ -1227,15 +1233,20 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { || stem == "clang" || stem.ends_with("-clang") { - LinkerFlavor::Gcc + LinkerFlavor::from_cli(LinkerFlavorCli::Gcc, &sess.target) } else if stem == "wasm-ld" || stem.ends_with("-wasm-ld") { - LinkerFlavor::Lld(LldFlavor::Wasm) - } else if stem == "ld" || stem == "ld.lld" || stem.ends_with("-ld") { - LinkerFlavor::Ld - } else if stem == "link" || stem == "lld-link" { - LinkerFlavor::Msvc + LinkerFlavor::WasmLld(Cc::No) + } else if stem == "ld" || stem.ends_with("-ld") { + LinkerFlavor::from_cli(LinkerFlavorCli::Ld, &sess.target) + } else if stem == "ld.lld" { + LinkerFlavor::Gnu(Cc::No, Lld::Yes) + } else if stem == "link" { + LinkerFlavor::Msvc(Lld::No) + } else if stem == "lld-link" { + LinkerFlavor::Msvc(Lld::Yes) } else if stem == "lld" || stem == "rust-lld" { - LinkerFlavor::Lld(sess.target.lld_flavor) + let lld_flavor = sess.target.linker_flavor.lld_flavor(); + LinkerFlavor::from_cli(LinkerFlavorCli::Lld(lld_flavor), &sess.target) } else { // fall back to the value in the target spec sess.target.linker_flavor @@ -1249,7 +1260,8 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) { // linker and linker flavor specified via command line have precedence over what the target // specification specifies - let linker_flavor = sess.opts.cg.linker_flavor.map(LinkerFlavor::from_cli); + let linker_flavor = + sess.opts.cg.linker_flavor.map(|flavor| LinkerFlavor::from_cli(flavor, &sess.target)); if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), linker_flavor) { return ret; } @@ -1320,7 +1332,7 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) { let verbatim = lib.verbatim.unwrap_or(false); if sess.target.is_like_msvc { Some(format!("{}{}", name, if verbatim { "" } else { ".lib" })) - } else if sess.target.linker_is_gnu { + } else if sess.target.linker_flavor.is_gnu() { Some(format!("-l{}{}", if verbatim { ":" } else { "" }, name)) } else { Some(format!("-l{}", name)) @@ -1607,7 +1619,7 @@ fn add_pre_link_objects( let empty = Default::default(); let objects = if self_contained { &opts.pre_link_objects_self_contained - } else if !(sess.target.os == "fuchsia" && flavor == LinkerFlavor::Gcc) { + } else if !(sess.target.os == "fuchsia" && matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _))) { &opts.pre_link_objects } else { &empty @@ -1647,7 +1659,7 @@ fn add_pre_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) fn add_link_script(cmd: &mut dyn Linker, sess: &Session, tmpdir: &Path, crate_type: CrateType) { match (crate_type, &sess.target.link_script) { (CrateType::Cdylib | CrateType::Executable, Some(script)) => { - if !sess.target.linker_is_gnu { + if !sess.target.linker_flavor.is_gnu() { sess.fatal("can only use link script when linking with GNU-like linker"); } @@ -1890,7 +1902,7 @@ fn add_rpath_args( out_filename: out_filename.to_path_buf(), has_rpath: sess.target.has_rpath, is_like_osx: sess.target.is_like_osx, - linker_is_gnu: sess.target.linker_is_gnu, + linker_is_gnu: sess.target.linker_flavor.is_gnu(), }; cmd.args(&rpath::get_rpath_flags(&mut rpath_config)); } @@ -2104,7 +2116,7 @@ fn add_order_independent_options( if sess.target.os == "fuchsia" && crate_type == CrateType::Executable - && flavor != LinkerFlavor::Gcc + && !matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _)) { let prefix = if sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::ADDRESS) { "asan/" @@ -2717,12 +2729,12 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { let llvm_target = &sess.target.llvm_target; if sess.target.vendor != "apple" || !matches!(os.as_ref(), "ios" | "tvos" | "watchos" | "macos") - || (flavor != LinkerFlavor::Gcc && flavor != LinkerFlavor::Lld(LldFlavor::Ld64)) + || !matches!(flavor, LinkerFlavor::Darwin(..)) { return; } - if os == "macos" && flavor != LinkerFlavor::Lld(LldFlavor::Ld64) { + if os == "macos" && !matches!(flavor, LinkerFlavor::Darwin(Cc::No, _)) { return; } @@ -2756,10 +2768,10 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { }; match flavor { - LinkerFlavor::Gcc => { + LinkerFlavor::Darwin(Cc::Yes, _) => { cmd.args(&["-isysroot", &sdk_root, "-Wl,-syslibroot", &sdk_root]); } - LinkerFlavor::Lld(LldFlavor::Ld64) => { + LinkerFlavor::Darwin(Cc::No, _) => { cmd.args(&["-syslibroot", &sdk_root]); } _ => unreachable!(), @@ -2822,7 +2834,10 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result { fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { if let Some(ld_impl) = sess.opts.unstable_opts.gcc_ld { - if let LinkerFlavor::Gcc = flavor { + if let LinkerFlavor::Gnu(Cc::Yes, _) + | LinkerFlavor::Darwin(Cc::Yes, _) + | LinkerFlavor::WasmLld(Cc::Yes) = flavor + { match ld_impl { LdImpl::Lld => { // Implement the "self-contained" part of -Zgcc-ld @@ -2837,7 +2852,7 @@ fn add_gcc_ld_path(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) { // Implement the "linker flavor" part of -Zgcc-ld // by asking cc to use some kind of lld. cmd.arg("-fuse-ld=lld"); - if sess.target.lld_flavor != LldFlavor::Ld { + if !flavor.is_gnu() { // Tell clang to use a non-default LLD flavor. // Gcc doesn't understand the target option, but we currently assume // that gcc is not used for Apple and Wasm targets (#97402). diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs index 2cd746ccb6a6e..c71d332475a5f 100644 --- a/compiler/rustc_codegen_ssa/src/back/linker.rs +++ b/compiler/rustc_codegen_ssa/src/back/linker.rs @@ -16,7 +16,7 @@ use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo, S use rustc_middle::ty::TyCtxt; use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip}; use rustc_session::Session; -use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor}; +use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, Lld}; use cc::windows_registry; @@ -56,8 +56,13 @@ pub fn get_linker<'a>( let mut cmd = match linker.to_str() { Some(linker) if cfg!(windows) && linker.ends_with(".bat") => Command::bat_script(linker), _ => match flavor { - LinkerFlavor::Lld(f) => Command::lld(linker, f), - LinkerFlavor::Msvc if sess.opts.cg.linker.is_none() && sess.target.linker.is_none() => { + LinkerFlavor::Gnu(Cc::No, Lld::Yes) + | LinkerFlavor::Darwin(Cc::No, Lld::Yes) + | LinkerFlavor::WasmLld(Cc::No) + | LinkerFlavor::Msvc(Lld::Yes) => Command::lld(linker, flavor.lld_flavor()), + LinkerFlavor::Msvc(Lld::No) + if sess.opts.cg.linker.is_none() && sess.target.linker.is_none() => + { Command::new(msvc_tool.as_ref().map_or(linker, |t| t.path())) } _ => Command::new(linker), @@ -68,9 +73,7 @@ pub fn get_linker<'a>( // To comply with the Windows App Certification Kit, // MSVC needs to link with the Store versions of the runtime libraries (vcruntime, msvcrt, etc). let t = &sess.target; - if (flavor == LinkerFlavor::Msvc || flavor == LinkerFlavor::Lld(LldFlavor::Link)) - && t.vendor == "uwp" - { + if matches!(flavor, LinkerFlavor::Msvc(..)) && t.vendor == "uwp" { if let Some(ref tool) = msvc_tool { let original_path = tool.path(); if let Some(ref root_lib_path) = original_path.ancestors().nth(4) { @@ -126,23 +129,22 @@ pub fn get_linker<'a>( // to the linker args construction. assert!(cmd.get_args().is_empty() || sess.target.vendor == "uwp"); match flavor { - LinkerFlavor::Gcc => { - Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: false }) - as Box - } - LinkerFlavor::Ld if sess.target.os == "l4re" => { + LinkerFlavor::Unix(Cc::No) if sess.target.os == "l4re" => { Box::new(L4Bender::new(cmd, sess)) as Box } - LinkerFlavor::Lld(LldFlavor::Ld) - | LinkerFlavor::Lld(LldFlavor::Ld64) - | LinkerFlavor::Ld => { - Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: true }) - as Box - } - LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => { - Box::new(MsvcLinker { cmd, sess }) as Box - } - LinkerFlavor::Lld(LldFlavor::Wasm) => Box::new(WasmLd::new(cmd, sess)) as Box, + LinkerFlavor::WasmLld(Cc::No) => Box::new(WasmLd::new(cmd, sess)) as Box, + LinkerFlavor::Gnu(cc, _) + | LinkerFlavor::Darwin(cc, _) + | LinkerFlavor::WasmLld(cc) + | LinkerFlavor::Unix(cc) => Box::new(GccLinker { + cmd, + sess, + target_cpu, + hinted_static: false, + is_ld: cc == Cc::No, + is_gnu: flavor.is_gnu(), + }) as Box, + LinkerFlavor::Msvc(..) => Box::new(MsvcLinker { cmd, sess }) as Box, LinkerFlavor::EmCc => Box::new(EmLinker { cmd, sess }) as Box, LinkerFlavor::Bpf => Box::new(BpfLinker { cmd, sess }) as Box, LinkerFlavor::Ptx => Box::new(PtxLinker { cmd, sess }) as Box, @@ -211,6 +213,7 @@ pub struct GccLinker<'a> { hinted_static: bool, // Keeps track of the current hinting mode. // Link as ld is_ld: bool, + is_gnu: bool, } impl<'a> GccLinker<'a> { @@ -359,7 +362,7 @@ impl<'a> Linker for GccLinker<'a> { fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path) { match output_kind { LinkOutputKind::DynamicNoPicExe => { - if !self.is_ld && self.sess.target.linker_is_gnu { + if !self.is_ld && self.is_gnu { self.cmd.arg("-no-pie"); } } @@ -373,7 +376,7 @@ impl<'a> Linker for GccLinker<'a> { LinkOutputKind::StaticNoPicExe => { // `-static` works for both gcc wrapper and ld. self.cmd.arg("-static"); - if !self.is_ld && self.sess.target.linker_is_gnu { + if !self.is_ld && self.is_gnu { self.cmd.arg("-no-pie"); } } @@ -432,31 +435,25 @@ impl<'a> Linker for GccLinker<'a> { // has -needed-l{} / -needed_library {} // but we have no way to detect that here. self.sess.warn("`as-needed` modifier not implemented yet for ld64"); - } else if self.sess.target.linker_is_gnu && !self.sess.target.is_like_windows { + } else if self.is_gnu && !self.sess.target.is_like_windows { self.linker_arg("--no-as-needed"); } else { self.sess.warn("`as-needed` modifier not supported for current linker"); } } self.hint_dynamic(); - self.cmd.arg(format!( - "-l{}{lib}", - if verbatim && self.sess.target.linker_is_gnu { ":" } else { "" }, - )); + self.cmd.arg(format!("-l{}{lib}", if verbatim && self.is_gnu { ":" } else { "" },)); if !as_needed { if self.sess.target.is_like_osx { // See above FIXME comment - } else if self.sess.target.linker_is_gnu && !self.sess.target.is_like_windows { + } else if self.is_gnu && !self.sess.target.is_like_windows { self.linker_arg("--as-needed"); } } } fn link_staticlib(&mut self, lib: &str, verbatim: bool) { self.hint_static(); - self.cmd.arg(format!( - "-l{}{lib}", - if verbatim && self.sess.target.linker_is_gnu { ":" } else { "" }, - )); + self.cmd.arg(format!("-l{}{lib}", if verbatim && self.is_gnu { ":" } else { "" },)); } fn link_rlib(&mut self, lib: &Path) { self.hint_static(); @@ -511,10 +508,7 @@ impl<'a> Linker for GccLinker<'a> { let target = &self.sess.target; if !target.is_like_osx { self.linker_arg("--whole-archive"); - self.cmd.arg(format!( - "-l{}{lib}", - if verbatim && self.sess.target.linker_is_gnu { ":" } else { "" }, - )); + self.cmd.arg(format!("-l{}{lib}", if verbatim && self.is_gnu { ":" } else { "" },)); self.linker_arg("--no-whole-archive"); } else { // -force_load is the macOS equivalent of --whole-archive, but it @@ -559,21 +553,19 @@ impl<'a> Linker for GccLinker<'a> { // eliminate the metadata. If we're building an executable, however, // --gc-sections drops the size of hello world from 1.8MB to 597K, a 67% // reduction. - } else if (self.sess.target.linker_is_gnu || self.sess.target.is_like_wasm) - && !keep_metadata - { + } else if (self.is_gnu || self.sess.target.is_like_wasm) && !keep_metadata { self.linker_arg("--gc-sections"); } } fn no_gc_sections(&mut self) { - if self.sess.target.linker_is_gnu || self.sess.target.is_like_wasm { + if self.is_gnu || self.sess.target.is_like_wasm { self.linker_arg("--no-gc-sections"); } } fn optimize(&mut self) { - if !self.sess.target.linker_is_gnu && !self.sess.target.is_like_wasm { + if !self.is_gnu && !self.sess.target.is_like_wasm { return; } @@ -587,7 +579,7 @@ impl<'a> Linker for GccLinker<'a> { } fn pgo_gen(&mut self) { - if !self.sess.target.linker_is_gnu { + if !self.is_gnu { return; } @@ -758,13 +750,13 @@ impl<'a> Linker for GccLinker<'a> { fn add_no_exec(&mut self) { if self.sess.target.is_like_windows { self.linker_arg("--nxcompat"); - } else if self.sess.target.linker_is_gnu { + } else if self.is_gnu { self.linker_arg("-znoexecstack"); } } fn add_as_needed(&mut self) { - if self.sess.target.linker_is_gnu && !self.sess.target.is_like_windows { + if self.is_gnu && !self.sess.target.is_like_windows { self.linker_arg("--as-needed"); } else if self.sess.target.is_like_solaris { // -z ignore is the Solaris equivalent to the GNU ld --as-needed option diff --git a/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs index 1dad07a9a42a4..2d2671549cf51 100644 --- a/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/aarch64_apple_ios_macabi.rs @@ -1,11 +1,11 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{FramePointer, LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { let llvm_target = "arm64-apple-ios14.0-macabi"; let mut base = opts("ios", Arch::Arm64_macabi); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-target", llvm_target]); + base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-target", llvm_target]); Target { llvm_target: llvm_target.into(), diff --git a/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs b/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs index b301ce68a1ce1..529e98d2cf31c 100644 --- a/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs +++ b/compiler/rustc_target/src/spec/aarch64_nintendo_switch_freestanding.rs @@ -1,4 +1,4 @@ -use super::{LinkerFlavor, LldFlavor, PanicStrategy, RelroLevel, Target, TargetOptions}; +use super::{Cc, LinkerFlavor, Lld, PanicStrategy, RelroLevel, Target, TargetOptions}; const LINKER_SCRIPT: &str = include_str!("./aarch64_nintendo_switch_freestanding_linker_script.ld"); @@ -10,7 +10,7 @@ pub fn target() -> Target { data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(), arch: "aarch64".into(), options: TargetOptions { - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), link_script: Some(LINKER_SCRIPT.into()), os: "horizon".into(), diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_none.rs b/compiler/rustc_target/src/spec/aarch64_unknown_none.rs index d3fd7051a1289..4ae6d4120c995 100644 --- a/compiler/rustc_target/src/spec/aarch64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_none.rs @@ -6,11 +6,11 @@ // // For example, `-C target-cpu=cortex-a53`. -use super::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, Target, TargetOptions}; +use super::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { let opts = TargetOptions { - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), features: "+strict-align,+neon,+fp-armv8".into(), relocation_model: RelocModel::Static, diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs b/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs index 6316abe1ba9f2..2385cb69abbef 100644 --- a/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_none_softfloat.rs @@ -6,12 +6,12 @@ // // For example, `-C target-cpu=cortex-a53`. -use super::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, Target, TargetOptions}; +use super::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { let opts = TargetOptions { abi: "softfloat".into(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), features: "+strict-align,-neon,-fp-armv8".into(), relocation_model: RelocModel::Static, diff --git a/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs b/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs index 3ef04c6766870..817ff2422a203 100644 --- a/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs +++ b/compiler/rustc_target/src/spec/aarch64_unknown_uefi.rs @@ -2,13 +2,13 @@ // uefi-base module for generic UEFI options. use super::uefi_msvc_base; -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, Lld, Target}; pub fn target() -> Target { let mut base = uefi_msvc_base::opts(); base.max_atomic_width = Some(128); - base.add_pre_link_args(LinkerFlavor::Msvc, &["/machine:arm64"]); + base.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &["/machine:arm64"]); Target { llvm_target: "aarch64-unknown-windows".into(), diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs index 2c72bf88a41e8..40bc59ca145e5 100644 --- a/compiler/rustc_target/src/spec/apple_base.rs +++ b/compiler/rustc_target/src/spec/apple_base.rs @@ -1,7 +1,7 @@ use std::{borrow::Cow, env}; -use crate::spec::{cvs, DebuginfoKind, FramePointer, SplitDebuginfo, StaticCow, TargetOptions}; -use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor}; +use crate::spec::{cvs, Cc, DebuginfoKind, FramePointer, LinkArgs}; +use crate::spec::{LinkerFlavor, Lld, SplitDebuginfo, StaticCow, TargetOptions}; fn pre_link_args(os: &'static str, arch: &'static str, abi: &'static str) -> LinkArgs { let platform_name: StaticCow = match abi { @@ -20,17 +20,16 @@ fn pre_link_args(os: &'static str, arch: &'static str, abi: &'static str) -> Lin .into(); let mut args = TargetOptions::link_args( - LinkerFlavor::Lld(LldFlavor::Ld64), + LinkerFlavor::Darwin(Cc::No, Lld::No), &["-arch", arch, "-platform_version"], ); - // Manually add owned args unsupported by link arg building helpers. - args.entry(LinkerFlavor::Lld(LldFlavor::Ld64)).or_default().extend([ - platform_name, - platform_version.clone(), - platform_version, - ]); + super::add_link_args_iter( + &mut args, + LinkerFlavor::Darwin(Cc::No, Lld::No), + [platform_name, platform_version.clone(), platform_version].into_iter(), + ); if abi != "macabi" { - super::add_link_args(&mut args, LinkerFlavor::Gcc, &["-arch", arch]); + super::add_link_args(&mut args, LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-arch", arch]); } args @@ -55,11 +54,11 @@ pub fn opts(os: &'static str, arch: &'static str, abi: &'static str) -> TargetOp TargetOptions { os: os.into(), vendor: "apple".into(), + linker_flavor: LinkerFlavor::Darwin(Cc::Yes, Lld::No), // 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), - linker_is_gnu: false, families: cvs!["unix"], is_like_osx: true, default_dwarf_version: 2, @@ -71,7 +70,6 @@ pub fn opts(os: &'static str, arch: &'static str, abi: &'static str) -> TargetOp abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, eh_frame_header: false, - lld_flavor: LldFlavor::Ld64, debuginfo_kind: DebuginfoKind::DwarfDsym, // The historical default for macOS targets is to run `dsymutil` which diff --git a/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs index 511693abe9807..8c65d6afcc182 100644 --- a/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/armebv7r_none_eabi.rs @@ -1,8 +1,7 @@ // Targets the Big endian Cortex-R4/R5 processor (ARMv7-R) use crate::abi::Endian; -use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -13,7 +12,7 @@ pub fn target() -> Target { options: TargetOptions { abi: "eabi".into(), endian: Endian::Big, - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), relocation_model: RelocModel::Static, panic_strategy: PanicStrategy::Abort, diff --git a/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs index 5df4a0a1583fb..7013bc60d16ba 100644 --- a/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/armebv7r_none_eabihf.rs @@ -1,8 +1,7 @@ // Targets the Cortex-R4F/R5F processor (ARMv7-R) use crate::abi::Endian; -use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -13,7 +12,7 @@ pub fn target() -> Target { options: TargetOptions { abi: "eabihf".into(), endian: Endian::Big, - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), relocation_model: RelocModel::Static, panic_strategy: PanicStrategy::Abort, diff --git a/compiler/rustc_target/src/spec/armv4t_none_eabi.rs b/compiler/rustc_target/src/spec/armv4t_none_eabi.rs index 797dfe52bd149..7ac1aab3b43c8 100644 --- a/compiler/rustc_target/src/spec/armv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/armv4t_none_eabi.rs @@ -16,7 +16,7 @@ //! The default link script is very likely wrong, so you should use //! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script. -use crate::spec::{cvs, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions}; +use crate::spec::{cvs, Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -35,7 +35,7 @@ pub fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), options: TargetOptions { abi: "eabi".into(), - linker_flavor: LinkerFlavor::Ld, + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::No), linker: Some("arm-none-eabi-ld".into()), asm_args: cvs!["-mthumb-interwork", "-march=armv4t", "-mlittle-endian",], // Force-enable 32-bit atomics, which allows the use of atomic load/store only. diff --git a/compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs b/compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs index 1bba3939397b7..40ec6f961f544 100644 --- a/compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs +++ b/compiler/rustc_target/src/spec/armv6k_nintendo_3ds.rs @@ -1,4 +1,4 @@ -use crate::spec::{cvs, LinkerFlavor, RelocModel, Target, TargetOptions}; +use crate::spec::{cvs, Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions}; /// A base target for Nintendo 3DS devices using the devkitARM toolchain. /// @@ -6,7 +6,7 @@ use crate::spec::{cvs, LinkerFlavor, RelocModel, Target, TargetOptions}; pub fn target() -> Target { let pre_link_args = TargetOptions::link_args( - LinkerFlavor::Gcc, + LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-specs=3dsx.specs", "-mtune=mpcore", "-mfloat-abi=hard", "-mtp=soft"], ); @@ -21,7 +21,6 @@ pub fn target() -> Target { env: "newlib".into(), vendor: "nintendo".into(), abi: "eabihf".into(), - linker_flavor: LinkerFlavor::Gcc, cpu: "mpcore".into(), families: cvs!["unix"], linker: Some("arm-none-eabi-gcc".into()), diff --git a/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs b/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs index 38c117a495e60..402e0fd92363e 100644 --- a/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/armv7_linux_androideabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, SanitizerSet, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, SanitizerSet, Target, TargetOptions}; // This target if is for the baseline of the Android v7a ABI // in thumb mode. It's named armv7-* instead of thumbv7-* @@ -10,7 +10,7 @@ use crate::spec::{LinkerFlavor, SanitizerSet, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::android_base::opts(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-march=armv7-a"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-march=armv7-a"]); Target { llvm_target: "armv7-none-linux-android".into(), pointer_width: 32, diff --git a/compiler/rustc_target/src/spec/armv7a_none_eabi.rs b/compiler/rustc_target/src/spec/armv7a_none_eabi.rs index cb5cbe15836fe..4e20fb3256975 100644 --- a/compiler/rustc_target/src/spec/armv7a_none_eabi.rs +++ b/compiler/rustc_target/src/spec/armv7a_none_eabi.rs @@ -14,12 +14,12 @@ // - `relocation-model` set to `static`; also no PIE, no relro and no dynamic // linking. rationale: matches `thumb` targets -use super::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, Target, TargetOptions}; +use super::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { let opts = TargetOptions { abi: "eabi".into(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), features: "+v7,+thumb2,+soft-float,-neon,+strict-align".into(), relocation_model: RelocModel::Static, diff --git a/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs b/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs index fb5dd2e7574fc..ae70129ae5182 100644 --- a/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/armv7a_none_eabihf.rs @@ -5,12 +5,12 @@ // changes (list in `armv7a_none_eabi.rs`) to bring it closer to the bare-metal // `thumb` & `aarch64` targets. -use super::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, Target, TargetOptions}; +use super::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { let opts = TargetOptions { abi: "eabihf".into(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), features: "+v7,+vfp3,-d32,+thumb2,-neon,+strict-align".into(), relocation_model: RelocModel::Static, diff --git a/compiler/rustc_target/src/spec/armv7r_none_eabi.rs b/compiler/rustc_target/src/spec/armv7r_none_eabi.rs index 5f1da09b31722..25f301ccce744 100644 --- a/compiler/rustc_target/src/spec/armv7r_none_eabi.rs +++ b/compiler/rustc_target/src/spec/armv7r_none_eabi.rs @@ -1,7 +1,6 @@ // Targets the Little-endian Cortex-R4/R5 processor (ARMv7-R) -use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -12,7 +11,7 @@ pub fn target() -> Target { options: TargetOptions { abi: "eabi".into(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), relocation_model: RelocModel::Static, panic_strategy: PanicStrategy::Abort, diff --git a/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs index 0038ed0df8bd3..40449759dd377 100644 --- a/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs +++ b/compiler/rustc_target/src/spec/armv7r_none_eabihf.rs @@ -1,7 +1,6 @@ // Targets the Little-endian Cortex-R4F/R5F processor (ARMv7-R) -use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -12,7 +11,7 @@ pub fn target() -> Target { options: TargetOptions { abi: "eabihf".into(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), relocation_model: RelocModel::Static, panic_strategy: PanicStrategy::Abort, diff --git a/compiler/rustc_target/src/spec/avr_gnu_base.rs b/compiler/rustc_target/src/spec/avr_gnu_base.rs index 8cca33cc43b35..9c3406b53130e 100644 --- a/compiler/rustc_target/src/spec/avr_gnu_base.rs +++ b/compiler/rustc_target/src/spec/avr_gnu_base.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, RelocModel, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions}; /// A base target for AVR devices using the GNU toolchain. /// @@ -17,8 +17,11 @@ 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::Gcc, &[mmcu]), - late_link_args: TargetOptions::link_args(LinkerFlavor::Gcc, &["-lgcc"]), + pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[mmcu]), + late_link_args: TargetOptions::link_args( + LinkerFlavor::Gnu(Cc::Yes, Lld::No), + &["-lgcc"], + ), max_atomic_width: Some(0), atomic_cas: false, relocation_model: RelocModel::Static, diff --git a/compiler/rustc_target/src/spec/fuchsia_base.rs b/compiler/rustc_target/src/spec/fuchsia_base.rs index 962ad0c66d914..4c2775850d132 100644 --- a/compiler/rustc_target/src/spec/fuchsia_base.rs +++ b/compiler/rustc_target/src/spec/fuchsia_base.rs @@ -1,4 +1,4 @@ -use crate::spec::{crt_objects, cvs, LinkOutputKind, LinkerFlavor, LldFlavor, TargetOptions}; +use crate::spec::{crt_objects, cvs, Cc, LinkOutputKind, LinkerFlavor, Lld, TargetOptions}; pub fn opts() -> TargetOptions { // This mirrors the linker options provided by clang. We presume lld for @@ -7,7 +7,7 @@ pub fn opts() -> TargetOptions { // // https://github.com/llvm/llvm-project/blob/db9322b2066c55254e7691efeab863f43bfcc084/clang/lib/Driver/ToolChains/Fuchsia.cpp#L31 let pre_link_args = TargetOptions::link_args( - LinkerFlavor::Ld, + LinkerFlavor::Gnu(Cc::No, Lld::No), &[ "--build-id", "--hash-style=gnu", @@ -25,7 +25,7 @@ pub fn opts() -> TargetOptions { TargetOptions { os: "fuchsia".into(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), dynamic_linking: true, families: cvs!["unix"], diff --git a/compiler/rustc_target/src/spec/hermit_base.rs b/compiler/rustc_target/src/spec/hermit_base.rs index 562ccef7eba01..dd9991381e7b9 100644 --- a/compiler/rustc_target/src/spec/hermit_base.rs +++ b/compiler/rustc_target/src/spec/hermit_base.rs @@ -1,14 +1,14 @@ -use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, TargetOptions, TlsModel}; +use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, TargetOptions, TlsModel}; pub fn opts() -> TargetOptions { let pre_link_args = TargetOptions::link_args( - LinkerFlavor::Ld, + LinkerFlavor::Gnu(Cc::No, Lld::No), &["--build-id", "--hash-style=gnu", "--Bstatic"], ); TargetOptions { os: "hermit".into(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), has_thread_local: true, pre_link_args, diff --git a/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs index 2a24e4459c553..3aad05eb2719b 100644 --- a/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/hexagon_unknown_linux_musl.rs @@ -1,4 +1,4 @@ -use crate::spec::Target; +use crate::spec::{Cc, LinkerFlavor, Target}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); @@ -9,7 +9,7 @@ pub fn target() -> Target { base.crt_static_default = false; base.has_rpath = true; - base.linker_is_gnu = false; + base.linker_flavor = LinkerFlavor::Unix(Cc::Yes); base.c_enum_min_bits = 8; diff --git a/compiler/rustc_target/src/spec/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/i686_apple_darwin.rs index 99b9d88e642ff..15607c12ea906 100644 --- a/compiler/rustc_target/src/spec/i686_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/i686_apple_darwin.rs @@ -1,11 +1,11 @@ -use crate::spec::{FramePointer, LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { // ld64 only understand i386 and not i686 let mut base = super::apple_base::opts("macos", "i386", ""); base.cpu = "yonah".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]); + base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m32"]); base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove()); base.stack_probes = StackProbeType::X86; base.frame_pointer = FramePointer::Always; diff --git a/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs index 6318654399c47..7a11138754fa8 100644 --- a/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/i686_pc_windows_gnu.rs @@ -1,4 +1,4 @@ -use crate::spec::{FramePointer, LinkerFlavor, Target}; +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target}; pub fn target() -> Target { let mut base = super::windows_gnu_base::opts(); @@ -9,8 +9,11 @@ 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::Ld, &["-m", "i386pe", "--large-address-aware"]); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-Wl,--large-address-aware"]); + 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"]); Target { llvm_target: "i686-pc-windows-gnu".into(), diff --git a/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs index f4ceaa1ca4bb8..db4c00dc697d7 100644 --- a/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/i686_pc_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{LinkerFlavor, Lld, Target}; pub fn target() -> Target { let mut base = super::windows_msvc_base::opts(); @@ -6,7 +6,7 @@ pub fn target() -> Target { base.max_atomic_width = Some(64); base.add_pre_link_args( - LinkerFlavor::Msvc, + LinkerFlavor::Msvc(Lld::No), &[ // Mark all dynamic libraries and executables as compatible with the larger 4GiB address // space available to x86 Windows binaries on x86_64. diff --git a/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs index 7d201245006f1..35ca78034f170 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_freebsd.rs @@ -1,10 +1,10 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::freebsd_base::opts(); base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-Wl,-znotext"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "-Wl,-znotext"]); base.stack_probes = StackProbeType::X86; Target { diff --git a/compiler/rustc_target/src/spec/i686_unknown_haiku.rs b/compiler/rustc_target/src/spec/i686_unknown_haiku.rs index 357cc547fa0c1..e6b72336c5cf5 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_haiku.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_haiku.rs @@ -1,10 +1,10 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::haiku_base::opts(); base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); base.stack_probes = StackProbeType::X86; Target { diff --git a/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs index bb7b56802983a..73e536a7e4d93 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_linux_gnu.rs @@ -1,11 +1,11 @@ -use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); base.supported_sanitizers = SanitizerSet::ADDRESS; - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); base.stack_probes = StackProbeType::X86; Target { diff --git a/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs index f604791967402..3825082ba25e4 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_linux_musl.rs @@ -1,10 +1,10 @@ -use crate::spec::{FramePointer, LinkerFlavor, StackProbeType, Target}; +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-Wl,-melf_i386"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "-Wl,-melf_i386"]); base.stack_probes = StackProbeType::X86; // The unwinder used by i686-unknown-linux-musl, the LLVM libunwind diff --git a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs index 0fd2d1231df88..b191996c7de0d 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_netbsd.rs @@ -1,10 +1,10 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::netbsd_base::opts(); base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); base.stack_probes = StackProbeType::X86; Target { diff --git a/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs index 2952c043daaf8..8babe55971280 100644 --- a/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/i686_unknown_openbsd.rs @@ -1,10 +1,10 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::openbsd_base::opts(); base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "-fuse-ld=lld"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32", "-fuse-ld=lld"]); base.stack_probes = StackProbeType::X86; Target { diff --git a/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs index d52810d2fb08b..a3e32569827fb 100644 --- a/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/i686_uwp_windows_gnu.rs @@ -1,4 +1,4 @@ -use crate::spec::{FramePointer, LinkerFlavor, Target}; +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target}; pub fn target() -> Target { let mut base = super::windows_uwp_gnu_base::opts(); @@ -8,8 +8,11 @@ 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::Ld, &["-m", "i386pe", "--large-address-aware"]); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-Wl,--large-address-aware"]); + 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"]); Target { llvm_target: "i686-pc-windows-gnu".into(), diff --git a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs index 4a0d98efd82eb..b5cfdfcebea90 100644 --- a/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/i686_wrs_vxworks.rs @@ -1,10 +1,10 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::vxworks_base::opts(); base.cpu = "pentium4".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]); base.stack_probes = StackProbeType::X86; Target { diff --git a/compiler/rustc_target/src/spec/illumos_base.rs b/compiler/rustc_target/src/spec/illumos_base.rs index 77e000474b86f..8ac3515844348 100644 --- a/compiler/rustc_target/src/spec/illumos_base.rs +++ b/compiler/rustc_target/src/spec/illumos_base.rs @@ -1,8 +1,8 @@ -use crate::spec::{cvs, FramePointer, LinkerFlavor, TargetOptions}; +use crate::spec::{cvs, Cc, FramePointer, LinkerFlavor, TargetOptions}; pub fn opts() -> TargetOptions { let late_link_args = TargetOptions::link_args( - LinkerFlavor::Gcc, + LinkerFlavor::Unix(Cc::Yes), &[ // The illumos libc contains a stack unwinding implementation, as // does libgcc_s. The latter implementation includes several @@ -30,7 +30,7 @@ pub fn opts() -> TargetOptions { has_rpath: true, families: cvs!["unix"], is_like_solaris: true, - linker_is_gnu: false, + linker_flavor: LinkerFlavor::Unix(Cc::Yes), limit_rdylib_exports: false, // Linker doesn't support this frame_pointer: FramePointer::Always, eh_frame_header: false, diff --git a/compiler/rustc_target/src/spec/l4re_base.rs b/compiler/rustc_target/src/spec/l4re_base.rs index b7bc1072bf328..3a4d83fad1751 100644 --- a/compiler/rustc_target/src/spec/l4re_base.rs +++ b/compiler/rustc_target/src/spec/l4re_base.rs @@ -1,13 +1,12 @@ -use crate::spec::{cvs, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions}; +use crate::spec::{cvs, Cc, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions}; pub fn opts() -> TargetOptions { TargetOptions { os: "l4re".into(), env: "uclibc".into(), - linker_flavor: LinkerFlavor::Ld, + linker_flavor: LinkerFlavor::Unix(Cc::No), panic_strategy: PanicStrategy::Abort, linker: Some("l4-bender".into()), - linker_is_gnu: false, families: cvs!["unix"], relocation_model: RelocModel::Static, ..Default::default() diff --git a/compiler/rustc_target/src/spec/mipsel_sony_psp.rs b/compiler/rustc_target/src/spec/mipsel_sony_psp.rs index cfc8ec21c2aef..75beb91b13a5e 100644 --- a/compiler/rustc_target/src/spec/mipsel_sony_psp.rs +++ b/compiler/rustc_target/src/spec/mipsel_sony_psp.rs @@ -1,11 +1,13 @@ -use crate::spec::{cvs, Target, TargetOptions}; -use crate::spec::{LinkerFlavor, LldFlavor, RelocModel}; +use crate::spec::{cvs, Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions}; // The PSP has custom linker requirements. const LINKER_SCRIPT: &str = include_str!("./mipsel_sony_psp_linker_script.ld"); pub fn target() -> Target { - let pre_link_args = TargetOptions::link_args(LinkerFlavor::Ld, &["--emit-relocs", "--nmagic"]); + let pre_link_args = TargetOptions::link_args( + LinkerFlavor::Gnu(Cc::No, Lld::No), + &["--emit-relocs", "--nmagic"], + ); Target { llvm_target: "mipsel-sony-psp".into(), @@ -16,7 +18,7 @@ pub fn target() -> Target { options: TargetOptions { os: "psp".into(), vendor: "sony".into(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), cpu: "mips2".into(), linker: Some("rust-lld".into()), relocation_model: RelocModel::Static, diff --git a/compiler/rustc_target/src/spec/mipsel_unknown_none.rs b/compiler/rustc_target/src/spec/mipsel_unknown_none.rs index fe2aa2de871ce..43b01e7a062dc 100644 --- a/compiler/rustc_target/src/spec/mipsel_unknown_none.rs +++ b/compiler/rustc_target/src/spec/mipsel_unknown_none.rs @@ -2,8 +2,7 @@ //! //! Can be used for MIPS M4K core (e.g. on PIC32MX devices) -use crate::spec::{LinkerFlavor, LldFlavor, RelocModel}; -use crate::spec::{PanicStrategy, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -13,7 +12,7 @@ pub fn target() -> Target { arch: "mips".into(), options: TargetOptions { - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), cpu: "mips32r2".into(), features: "+mips32r2,+soft-float,+noabicalls".into(), max_atomic_width: Some(32), diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index af85e2f4febcd..9396d769dc702 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -90,17 +90,73 @@ mod windows_msvc_base; mod windows_uwp_gnu_base; mod windows_uwp_msvc_base; +/// Linker is called through a C/C++ compiler. +#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub enum Cc { + Yes, + No, +} + +/// Linker is LLD. +#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] +pub enum Lld { + Yes, + No, +} + +/// All linkers have some kinds of command line interfaces and rustc needs to know which commands +/// to use with each of them. So we cluster all such interfaces into a (somewhat arbitrary) number +/// of classes that we call "linker flavors". +/// +/// Technically, it's not even necessary, we can nearly always infer the flavor from linker name +/// and target properties like `is_like_windows`/`is_like_osx`/etc. However, the PRs originally +/// introducing `-Clinker-flavor` (#40018 and friends) were aiming to reduce this kind of inference +/// and provide something certain and explicitly specified instead, and that design goal is still +/// relevant now. +/// +/// The second goal is to keep the number of flavors to the minimum if possible. +/// LLD somewhat forces our hand here because that linker is self-sufficent only if its executable +/// (`argv[0]`) is named in specific way, otherwise it doesn't work and requires a +/// `-flavor LLD_FLAVOR` argument to choose which logic to use. Our shipped `rust-lld` in +/// particular is not named in such specific way, so it needs the flavor option, so we make our +/// linker flavors sufficiently fine-grained to satisfy LLD without inferring its flavor from other +/// target properties, in accordance with the first design goal. +/// +/// The first component of the flavor is tightly coupled with the compilation target, +/// while the `Cc` and `Lld` flags can vary withing the same target. #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] pub enum LinkerFlavor { - Gcc, - Ld, - Lld(LldFlavor), - Msvc, + /// Unix-like linker with GNU extensions (both naked and compiler-wrapped forms). + /// Besides similar "default" Linux/BSD linkers this also includes Windows/GNU linker, + /// which is somewhat different because it doesn't produce ELFs. + Gnu(Cc, Lld), + /// Unix-like linker for Apple targets (both naked and compiler-wrapped forms). + /// Extracted from the "umbrella" `Unix` flavor due to its corresponding LLD flavor. + Darwin(Cc, Lld), + /// Unix-like linker for Wasm targets (both naked and compiler-wrapped forms). + /// Extracted from the "umbrella" `Unix` flavor due to its corresponding LLD flavor. + /// Non-LLD version does not exist, so the lld flag is currently hardcoded here. + WasmLld(Cc), + /// Basic Unix-like linker for "any other Unix" targets (Solaris/illumos, L4Re, MSP430, etc), + /// possibly with non-GNU extensions (both naked and compiler-wrapped forms). + /// LLD doesn't support any of these. + Unix(Cc), + /// MSVC-style linker for Windows and UEFI, LLD supports it. + Msvc(Lld), + /// Emscripten Compiler Frontend, a wrapper around `WasmLld(Cc::Yes)` that has a different + /// interface and produces some additional JavaScript output. EmCc, + // Below: other linker-like tools with unique interfaces for exotic targets. + /// Linker tool for BPF. Bpf, + /// Linker tool for Nvidia PTX. Ptx, } +/// Linker flavors available externally through command line (`-Clinker-flavor`) +/// or json target specifications. +/// FIXME: This set has accumulated historically, bring it more in line with the internal +/// linker flavors (`LinkerFlavor`). #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)] pub enum LinkerFlavorCli { Gcc, @@ -148,12 +204,32 @@ impl ToJson for LldFlavor { } impl LinkerFlavor { - pub fn from_cli(cli: LinkerFlavorCli) -> LinkerFlavor { + pub fn from_cli(cli: LinkerFlavorCli, target: &TargetOptions) -> LinkerFlavor { + Self::from_cli_impl(cli, target.linker_flavor.lld_flavor(), target.linker_flavor.is_gnu()) + } + + /// The passed CLI flavor is preferred over other args coming from the default target spec, + /// so this function can produce a flavor that is incompatible with the current target. + /// FIXME: Produce errors when `-Clinker-flavor` is set to something incompatible + /// with the current target. + fn from_cli_impl(cli: LinkerFlavorCli, lld_flavor: LldFlavor, is_gnu: bool) -> LinkerFlavor { match cli { - LinkerFlavorCli::Gcc => LinkerFlavor::Gcc, - LinkerFlavorCli::Ld => LinkerFlavor::Ld, - LinkerFlavorCli::Lld(lld_flavor) => LinkerFlavor::Lld(lld_flavor), - LinkerFlavorCli::Msvc => LinkerFlavor::Msvc, + LinkerFlavorCli::Gcc => match lld_flavor { + LldFlavor::Ld if is_gnu => LinkerFlavor::Gnu(Cc::Yes, Lld::No), + LldFlavor::Ld64 => LinkerFlavor::Darwin(Cc::Yes, Lld::No), + LldFlavor::Wasm => LinkerFlavor::WasmLld(Cc::Yes), + LldFlavor::Ld | LldFlavor::Link => LinkerFlavor::Unix(Cc::Yes), + }, + LinkerFlavorCli::Ld => match lld_flavor { + LldFlavor::Ld if is_gnu => LinkerFlavor::Gnu(Cc::No, Lld::No), + LldFlavor::Ld64 => LinkerFlavor::Darwin(Cc::No, Lld::No), + LldFlavor::Ld | LldFlavor::Wasm | LldFlavor::Link => LinkerFlavor::Unix(Cc::No), + }, + LinkerFlavorCli::Lld(LldFlavor::Ld) => LinkerFlavor::Gnu(Cc::No, Lld::Yes), + LinkerFlavorCli::Lld(LldFlavor::Ld64) => LinkerFlavor::Darwin(Cc::No, Lld::Yes), + LinkerFlavorCli::Lld(LldFlavor::Wasm) => LinkerFlavor::WasmLld(Cc::No), + LinkerFlavorCli::Lld(LldFlavor::Link) => LinkerFlavor::Msvc(Lld::Yes), + LinkerFlavorCli::Msvc => LinkerFlavor::Msvc(Lld::No), LinkerFlavorCli::Em => LinkerFlavor::EmCc, LinkerFlavorCli::BpfLinker => LinkerFlavor::Bpf, LinkerFlavorCli::PtxLinker => LinkerFlavor::Ptx, @@ -162,15 +238,40 @@ impl LinkerFlavor { fn to_cli(self) -> LinkerFlavorCli { match self { - LinkerFlavor::Gcc => LinkerFlavorCli::Gcc, - LinkerFlavor::Ld => LinkerFlavorCli::Ld, - LinkerFlavor::Lld(lld_flavor) => LinkerFlavorCli::Lld(lld_flavor), - LinkerFlavor::Msvc => LinkerFlavorCli::Msvc, + LinkerFlavor::Gnu(Cc::Yes, _) + | LinkerFlavor::Darwin(Cc::Yes, _) + | LinkerFlavor::WasmLld(Cc::Yes) + | LinkerFlavor::Unix(Cc::Yes) => LinkerFlavorCli::Gcc, + LinkerFlavor::Gnu(_, Lld::Yes) => LinkerFlavorCli::Lld(LldFlavor::Ld), + LinkerFlavor::Darwin(_, Lld::Yes) => LinkerFlavorCli::Lld(LldFlavor::Ld64), + LinkerFlavor::WasmLld(..) => LinkerFlavorCli::Lld(LldFlavor::Wasm), + LinkerFlavor::Gnu(..) | LinkerFlavor::Darwin(..) | LinkerFlavor::Unix(..) => { + LinkerFlavorCli::Ld + } + LinkerFlavor::Msvc(Lld::Yes) => LinkerFlavorCli::Lld(LldFlavor::Link), + LinkerFlavor::Msvc(..) => LinkerFlavorCli::Msvc, LinkerFlavor::EmCc => LinkerFlavorCli::Em, LinkerFlavor::Bpf => LinkerFlavorCli::BpfLinker, LinkerFlavor::Ptx => LinkerFlavorCli::PtxLinker, } } + + pub fn lld_flavor(self) -> LldFlavor { + match self { + LinkerFlavor::Gnu(..) + | LinkerFlavor::Unix(..) + | LinkerFlavor::EmCc + | LinkerFlavor::Bpf + | LinkerFlavor::Ptx => LldFlavor::Ld, + LinkerFlavor::Darwin(..) => LldFlavor::Ld64, + LinkerFlavor::WasmLld(..) => LldFlavor::Wasm, + LinkerFlavor::Msvc(..) => LldFlavor::Link, + } + } + + pub fn is_gnu(self) -> bool { + matches!(self, LinkerFlavor::Gnu(..)) + } } macro_rules! linker_flavor_cli_impls { @@ -1258,16 +1359,11 @@ pub struct TargetOptions { /// Linker to invoke pub linker: Option>, /// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed - /// on the command line. Defaults to `LinkerFlavor::Gcc`. + /// on the command line. Defaults to `LinkerFlavor::Gnu(Cc::Yes, Lld::No)`. pub linker_flavor: LinkerFlavor, linker_flavor_json: LinkerFlavorCli, - /// LLD flavor used if `lld` (or `rust-lld`) is specified as a linker - /// without clarifying its flavor in any way. - /// FIXME: Merge this into `LinkerFlavor`. - pub lld_flavor: LldFlavor, - /// Whether the linker support GNU-like arguments such as -O. Defaults to true. - /// FIXME: Merge this into `LinkerFlavor`. - pub linker_is_gnu: bool, + lld_flavor_json: LldFlavor, + linker_is_gnu_json: bool, /// Objects to link before and after all other object code. pub pre_link_objects: CrtObjects, @@ -1300,7 +1396,7 @@ pub struct TargetOptions { /// Optional link script applied to `dylib` and `executable` crate types. /// This is a string containing the script, not a path. Can only be applied - /// to linkers where `linker_is_gnu` is true. + /// to linkers where linker flavor matches `LinkerFlavor::Gnu(..)`. pub link_script: Option>, /// Environment variables to be set for the linker invocation. pub link_env: StaticCow<[(StaticCow, StaticCow)]>, @@ -1575,22 +1671,38 @@ pub struct TargetOptions { /// Add arguments for the given flavor and also for its "twin" flavors /// that have a compatible command line interface. -fn add_link_args(link_args: &mut LinkArgs, flavor: LinkerFlavor, args: &[&'static str]) { - let mut insert = |flavor| { - link_args.entry(flavor).or_default().extend(args.iter().copied().map(Cow::Borrowed)) - }; +fn add_link_args_iter( + link_args: &mut LinkArgs, + flavor: LinkerFlavor, + args: impl Iterator> + Clone, +) { + let mut insert = |flavor| link_args.entry(flavor).or_default().extend(args.clone()); insert(flavor); match flavor { - LinkerFlavor::Ld => insert(LinkerFlavor::Lld(LldFlavor::Ld)), - LinkerFlavor::Msvc => insert(LinkerFlavor::Lld(LldFlavor::Link)), - LinkerFlavor::Lld(LldFlavor::Ld64) | LinkerFlavor::Lld(LldFlavor::Wasm) => {} - LinkerFlavor::Lld(lld_flavor) => { - panic!("add_link_args: use non-LLD flavor for {:?}", lld_flavor) + LinkerFlavor::Gnu(cc, lld) => { + assert_eq!(lld, Lld::No); + insert(LinkerFlavor::Gnu(cc, Lld::Yes)); + } + LinkerFlavor::Darwin(cc, lld) => { + assert_eq!(lld, Lld::No); + insert(LinkerFlavor::Darwin(cc, Lld::Yes)); } - LinkerFlavor::Gcc | LinkerFlavor::EmCc | LinkerFlavor::Bpf | LinkerFlavor::Ptx => {} + LinkerFlavor::Msvc(lld) => { + assert_eq!(lld, Lld::No); + insert(LinkerFlavor::Msvc(Lld::Yes)); + } + LinkerFlavor::WasmLld(..) + | LinkerFlavor::Unix(..) + | LinkerFlavor::EmCc + | LinkerFlavor::Bpf + | LinkerFlavor::Ptx => {} } } +fn add_link_args(link_args: &mut LinkArgs, flavor: LinkerFlavor, args: &[&'static str]) { + add_link_args_iter(link_args, flavor, args.iter().copied().map(Cow::Borrowed)) +} + impl TargetOptions { fn link_args(flavor: LinkerFlavor, args: &[&'static str]) -> LinkArgs { let mut link_args = LinkArgs::new(); @@ -1607,7 +1719,11 @@ impl TargetOptions { } fn update_from_cli(&mut self) { - self.linker_flavor = LinkerFlavor::from_cli(self.linker_flavor_json); + self.linker_flavor = LinkerFlavor::from_cli_impl( + self.linker_flavor_json, + self.lld_flavor_json, + self.linker_is_gnu_json, + ); for (args, args_json) in [ (&mut self.pre_link_args, &self.pre_link_args_json), (&mut self.late_link_args, &self.late_link_args_json), @@ -1615,15 +1731,28 @@ impl TargetOptions { (&mut self.late_link_args_static, &self.late_link_args_static_json), (&mut self.post_link_args, &self.post_link_args_json), ] { - *args = args_json - .iter() - .map(|(flavor, args)| (LinkerFlavor::from_cli(*flavor), args.clone())) - .collect(); + args.clear(); + for (flavor, args_json) in args_json { + // Cannot use `from_cli` due to borrow checker. + let linker_flavor = LinkerFlavor::from_cli_impl( + *flavor, + self.lld_flavor_json, + self.linker_is_gnu_json, + ); + match linker_flavor { + LinkerFlavor::Gnu(_, Lld::Yes) + | LinkerFlavor::Darwin(_, Lld::Yes) + | LinkerFlavor::Msvc(Lld::Yes) => {} + _ => add_link_args_iter(args, linker_flavor, args_json.iter().cloned()), + } + } } } fn update_to_cli(&mut self) { self.linker_flavor_json = self.linker_flavor.to_cli(); + self.lld_flavor_json = self.linker_flavor.lld_flavor(); + self.linker_is_gnu_json = self.linker_flavor.is_gnu(); for (args, args_json) in [ (&self.pre_link_args, &mut self.pre_link_args_json), (&self.late_link_args, &mut self.late_link_args_json), @@ -1650,10 +1779,10 @@ impl Default for TargetOptions { abi: "".into(), vendor: "unknown".into(), linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.into()), - linker_flavor: LinkerFlavor::Gcc, + linker_flavor: LinkerFlavor::Gnu(Cc::Yes, Lld::No), linker_flavor_json: LinkerFlavorCli::Gcc, - lld_flavor: LldFlavor::Ld, - linker_is_gnu: true, + lld_flavor_json: LldFlavor::Ld, + linker_is_gnu_json: true, link_script: None, asm_args: cvs![], cpu: "generic".into(), @@ -1922,6 +2051,12 @@ impl Target { base.$key_name = s; } } ); + ($key_name:ident = $json_name:expr, bool) => ( { + let name = $json_name; + if let Some(s) = obj.remove(name).and_then(|b| b.as_bool()) { + base.$key_name = s; + } + } ); ($key_name:ident, u64) => ( { let name = (stringify!($key_name)).replace("_", "-"); if let Some(s) = obj.remove(&name).and_then(|j| Json::as_u64(&j)) { @@ -2093,9 +2228,9 @@ impl Target { .map(|s| s.to_string().into()); } } ); - ($key_name:ident, LldFlavor) => ( { - let name = (stringify!($key_name)).replace("_", "-"); - obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { + ($key_name:ident = $json_name:expr, LldFlavor) => ( { + let name = $json_name; + obj.remove(name).and_then(|o| o.as_str().and_then(|s| { if let Some(flavor) = LldFlavor::from_str(&s) { base.$key_name = flavor; } else { @@ -2289,8 +2424,8 @@ impl Target { key!(vendor); key!(linker, optional); key!(linker_flavor_json = "linker-flavor", LinkerFlavor)?; - key!(lld_flavor, LldFlavor)?; - key!(linker_is_gnu, bool); + key!(lld_flavor_json = "lld-flavor", LldFlavor)?; + key!(linker_is_gnu_json = "linker-is-gnu", bool); key!(pre_link_objects = "pre-link-objects", link_objects); key!(post_link_objects = "post-link-objects", link_objects); key!(pre_link_objects_self_contained = "pre-link-objects-fallback", link_objects); @@ -2539,8 +2674,8 @@ impl ToJson for Target { target_option_val!(vendor); target_option_val!(linker); target_option_val!(linker_flavor_json, "linker-flavor"); - target_option_val!(lld_flavor); - target_option_val!(linker_is_gnu); + target_option_val!(lld_flavor_json, "lld-flavor"); + target_option_val!(linker_is_gnu_json, "linker-is-gnu"); target_option_val!(pre_link_objects); target_option_val!(post_link_objects); target_option_val!(pre_link_objects_self_contained, "pre-link-objects-fallback"); diff --git a/compiler/rustc_target/src/spec/msp430_none_elf.rs b/compiler/rustc_target/src/spec/msp430_none_elf.rs index 6b09386ae3ee5..251fd2a0a7ab7 100644 --- a/compiler/rustc_target/src/spec/msp430_none_elf.rs +++ b/compiler/rustc_target/src/spec/msp430_none_elf.rs @@ -1,4 +1,4 @@ -use crate::spec::{cvs, PanicStrategy, RelocModel, Target, TargetOptions}; +use crate::spec::{cvs, Cc, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -16,7 +16,7 @@ pub fn target() -> Target { // dependency on this specific gcc. asm_args: cvs!["-mcpu=msp430"], linker: Some("msp430-elf-gcc".into()), - linker_is_gnu: false, + linker_flavor: LinkerFlavor::Unix(Cc::Yes), // There are no atomic CAS instructions available in the MSP430 // instruction set, and the LLVM backend doesn't currently support diff --git a/compiler/rustc_target/src/spec/msvc_base.rs b/compiler/rustc_target/src/spec/msvc_base.rs index b3cd38a6ec3de..1dad9133ea3d2 100644 --- a/compiler/rustc_target/src/spec/msvc_base.rs +++ b/compiler/rustc_target/src/spec/msvc_base.rs @@ -1,17 +1,15 @@ -use crate::spec::{DebuginfoKind, LinkerFlavor, LldFlavor, SplitDebuginfo, TargetOptions}; +use crate::spec::{DebuginfoKind, LinkerFlavor, Lld, SplitDebuginfo, TargetOptions}; use std::borrow::Cow; pub fn opts() -> TargetOptions { // Suppress the verbose logo and authorship debugging output, which would needlessly // clog any log files. - let pre_link_args = TargetOptions::link_args(LinkerFlavor::Msvc, &["/NOLOGO"]); + let pre_link_args = TargetOptions::link_args(LinkerFlavor::Msvc(Lld::No), &["/NOLOGO"]); TargetOptions { - linker_flavor: LinkerFlavor::Msvc, + linker_flavor: LinkerFlavor::Msvc(Lld::No), is_like_windows: true, is_like_msvc: true, - lld_flavor: LldFlavor::Link, - linker_is_gnu: false, pre_link_args, abi_return_struct_as_int: true, emit_debug_gdb_scripts: false, diff --git a/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs b/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs index 6ab3a8b7eb5a0..b0582b235b9a4 100644 --- a/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs +++ b/compiler/rustc_target/src/spec/nvptx64_nvidia_cuda.rs @@ -13,7 +13,6 @@ pub fn target() -> Target { linker_flavor: LinkerFlavor::Ptx, // The linker can be installed from `crates.io`. linker: Some("rust-ptx-linker".into()), - linker_is_gnu: false, // With `ptx-linker` approach, it can be later overridden via link flags. cpu: "sm_30".into(), diff --git a/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs index 9f4cc3d80f1c9..08b273207301c 100644 --- a/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_freebsd.rs @@ -1,10 +1,10 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::freebsd_base::opts(); base.cpu = "ppc64".into(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_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/powerpc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs index 21955a616c2de..ce64de861cd26 100644 --- a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_gnu.rs @@ -1,10 +1,10 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.cpu = "ppc64".into(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_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/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs index bbf86e4ff41ca..81286a668fe71 100644 --- a/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_linux_musl.rs @@ -1,10 +1,10 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); base.cpu = "ppc64".into(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_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/powerpc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/powerpc64_unknown_openbsd.rs index bfa61a21fb3e6..7232dce3e96cc 100644 --- a/compiler/rustc_target/src/spec/powerpc64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/powerpc64_unknown_openbsd.rs @@ -1,10 +1,10 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::openbsd_base::opts(); base.cpu = "ppc64".into(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_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/powerpc64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs index 4ebf342ad22e4..10da7872c7361 100644 --- a/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/powerpc64_wrs_vxworks.rs @@ -1,10 +1,10 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::vxworks_base::opts(); base.cpu = "ppc64".into(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_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/powerpc64le_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_freebsd.rs index a7ab907853143..8c941e1065153 100644 --- a/compiler/rustc_target/src/spec/powerpc64le_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_freebsd.rs @@ -1,9 +1,9 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::freebsd_base::opts(); base.cpu = "ppc64le".into(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_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/powerpc64le_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs index 69fd6be6dc0e0..fd896e086b541 100644 --- a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_gnu.rs @@ -1,9 +1,9 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.cpu = "ppc64le".into(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_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/powerpc64le_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs index ae3a8b545191a..3cffcf49772ed 100644 --- a/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/powerpc64le_unknown_linux_musl.rs @@ -1,9 +1,9 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); base.cpu = "ppc64le".into(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_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/powerpc_unknown_freebsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs index b5d4e5de05e29..342f321bd5bf7 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_freebsd.rs @@ -1,10 +1,13 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::freebsd_base::opts(); // Extra hint to linker that we are generating secure-PLT code. - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "--target=powerpc-unknown-freebsd13.0"]); + base.add_pre_link_args( + LinkerFlavor::Gnu(Cc::Yes, Lld::No), + &["-m32", "--target=powerpc-unknown-freebsd13.0"], + ); base.max_atomic_width = Some(32); base.stack_probes = StackProbeType::Inline; diff --git a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs index 0ceb66c327be5..c8c61dc46eefe 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnu.rs @@ -1,9 +1,9 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]); + base.add_pre_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/powerpc_unknown_linux_gnuspe.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs index 716090f39cac2..5c51ec91f715d 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_gnuspe.rs @@ -1,9 +1,9 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-mspe"]); + base.add_pre_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/powerpc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs index d8cd158584a3c..fc7d802cbf44b 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_linux_musl.rs @@ -1,9 +1,9 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]); + base.add_pre_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/powerpc_unknown_netbsd.rs b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs index 7053e4b9c26fe..912149c79e44c 100644 --- a/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/powerpc_unknown_netbsd.rs @@ -1,9 +1,9 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::netbsd_base::opts(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32"]); + base.add_pre_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/powerpc_wrs_vxworks.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs index e0c5db6eacfe6..a8c1c2a6132ea 100644 --- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks.rs @@ -1,9 +1,9 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::vxworks_base::opts(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m32", "--secure-plt"]); + base.add_pre_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/powerpc_wrs_vxworks_spe.rs b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs index c7f41b1da87f6..abb8d13daef40 100644 --- a/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs +++ b/compiler/rustc_target/src/spec/powerpc_wrs_vxworks_spe.rs @@ -1,9 +1,9 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::vxworks_base::opts(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-mspe", "--secure-plt"]); + base.add_pre_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/riscv32i_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv32i_unknown_none_elf.rs index 232139db6cad0..75a65a268494c 100644 --- a/compiler/rustc_target/src/spec/riscv32i_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv32i_unknown_none_elf.rs @@ -1,5 +1,4 @@ -use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -9,7 +8,7 @@ pub fn target() -> Target { arch: "riscv32".into(), options: TargetOptions { - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), max_atomic_width: Some(0), diff --git a/compiler/rustc_target/src/spec/riscv32im_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv32im_unknown_none_elf.rs index 3e5d2887f431c..f2242bbe08714 100644 --- a/compiler/rustc_target/src/spec/riscv32im_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv32im_unknown_none_elf.rs @@ -1,5 +1,4 @@ -use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -9,7 +8,7 @@ pub fn target() -> Target { arch: "riscv32".into(), options: TargetOptions { - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), max_atomic_width: Some(0), diff --git a/compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs index 99317b9f1185f..55c6e4d16e5a4 100644 --- a/compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv32imac_unknown_none_elf.rs @@ -1,5 +1,4 @@ -use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -9,7 +8,7 @@ pub fn target() -> Target { arch: "riscv32".into(), options: TargetOptions { - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), max_atomic_width: Some(32), diff --git a/compiler/rustc_target/src/spec/riscv32imac_unknown_xous_elf.rs b/compiler/rustc_target/src/spec/riscv32imac_unknown_xous_elf.rs index a5de645c9846f..a263e5d5cde28 100644 --- a/compiler/rustc_target/src/spec/riscv32imac_unknown_xous_elf.rs +++ b/compiler/rustc_target/src/spec/riscv32imac_unknown_xous_elf.rs @@ -1,5 +1,4 @@ -use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -10,7 +9,7 @@ pub fn target() -> Target { options: TargetOptions { os: "xous".into(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), max_atomic_width: Some(32), diff --git a/compiler/rustc_target/src/spec/riscv32imc_esp_espidf.rs b/compiler/rustc_target/src/spec/riscv32imc_esp_espidf.rs index 03baef65c0d5b..25638a092b5d3 100644 --- a/compiler/rustc_target/src/spec/riscv32imc_esp_espidf.rs +++ b/compiler/rustc_target/src/spec/riscv32imc_esp_espidf.rs @@ -1,5 +1,4 @@ -use crate::spec::{cvs, Target, TargetOptions}; -use crate::spec::{LinkerFlavor, PanicStrategy, RelocModel}; +use crate::spec::{cvs, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -13,7 +12,6 @@ pub fn target() -> Target { os: "espidf".into(), env: "newlib".into(), vendor: "espressif".into(), - linker_flavor: LinkerFlavor::Gcc, linker: Some("riscv32-esp-elf-gcc".into()), cpu: "generic-rv32".into(), diff --git a/compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs index bf510d204a721..01e773fae9734 100644 --- a/compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv32imc_unknown_none_elf.rs @@ -1,5 +1,4 @@ -use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -9,7 +8,7 @@ pub fn target() -> Target { arch: "riscv32".into(), options: TargetOptions { - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv32".into(), max_atomic_width: Some(0), diff --git a/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs index 03b3cfd1eb11c..67806d578c8e4 100644 --- a/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv64gc_unknown_none_elf.rs @@ -1,5 +1,5 @@ -use crate::spec::{CodeModel, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; -use crate::spec::{Target, TargetOptions}; +use crate::spec::{Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy}; +use crate::spec::{RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -9,7 +9,7 @@ pub fn target() -> Target { arch: "riscv64".into(), options: TargetOptions { - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), llvm_abiname: "lp64d".into(), cpu: "generic-rv64".into(), diff --git a/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs b/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs index 2a94c9dd23371..f371e09bed74d 100644 --- a/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/riscv64imac_unknown_none_elf.rs @@ -1,5 +1,5 @@ -use crate::spec::{CodeModel, Target, TargetOptions}; -use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; +use crate::spec::{Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy}; +use crate::spec::{RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -9,7 +9,7 @@ pub fn target() -> Target { arch: "riscv64".into(), options: TargetOptions { - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), cpu: "generic-rv64".into(), max_atomic_width: Some(64), diff --git a/compiler/rustc_target/src/spec/solaris_base.rs b/compiler/rustc_target/src/spec/solaris_base.rs index b7e8e8cf7f577..f97cdb4fb2842 100644 --- a/compiler/rustc_target/src/spec/solaris_base.rs +++ b/compiler/rustc_target/src/spec/solaris_base.rs @@ -1,4 +1,4 @@ -use crate::spec::{cvs, TargetOptions}; +use crate::spec::{cvs, Cc, LinkerFlavor, TargetOptions}; pub fn opts() -> TargetOptions { TargetOptions { @@ -7,7 +7,7 @@ pub fn opts() -> TargetOptions { has_rpath: true, families: cvs!["unix"], is_like_solaris: true, - linker_is_gnu: false, + linker_flavor: LinkerFlavor::Unix(Cc::Yes), limit_rdylib_exports: false, // Linker doesn't support this eh_frame_header: false, diff --git a/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs index 836ab0e37283a..38ab066b0879f 100644 --- a/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/sparc64_unknown_netbsd.rs @@ -1,10 +1,10 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::netbsd_base::opts(); base.cpu = "v9".into(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); Target { diff --git a/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs index 4a192df392fa3..06a5f782a6dfb 100644 --- a/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/sparc64_unknown_openbsd.rs @@ -1,11 +1,11 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, Target}; pub fn target() -> Target { let mut base = super::openbsd_base::opts(); base.endian = Endian::Big; base.cpu = "v9".into(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); Target { diff --git a/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs index ea4fafa4b0654..12968abda082e 100644 --- a/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/sparc_unknown_linux_gnu.rs @@ -1,12 +1,12 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, Target}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.endian = Endian::Big; base.cpu = "v9".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-mv8plus"]); + base.add_pre_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/sparcv9_sun_solaris.rs b/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs index aac09181a74d1..440194ef216bf 100644 --- a/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs +++ b/compiler/rustc_target/src/spec/sparcv9_sun_solaris.rs @@ -1,10 +1,10 @@ use crate::abi::Endian; -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{Cc, LinkerFlavor, Target}; pub fn target() -> Target { let mut base = super::solaris_base::opts(); base.endian = Endian::Big; - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_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/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs index 0af599916a999..172da0ed5df88 100644 --- a/compiler/rustc_target/src/spec/tests/tests_impl.rs +++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs @@ -19,11 +19,13 @@ impl Target { assert!(self.is_like_windows); } - // Check that default linker flavor and lld flavor are compatible - // with some other key properties. - assert_eq!(self.is_like_osx, matches!(self.lld_flavor, LldFlavor::Ld64)); - assert_eq!(self.is_like_msvc, matches!(self.lld_flavor, LldFlavor::Link)); - assert_eq!(self.is_like_wasm, matches!(self.lld_flavor, LldFlavor::Wasm)); + // Check that default linker flavor is compatible with some other key properties. + assert_eq!(self.is_like_osx, matches!(self.linker_flavor, LinkerFlavor::Darwin(..))); + assert_eq!(self.is_like_msvc, matches!(self.linker_flavor, LinkerFlavor::Msvc(..))); + assert_eq!( + self.is_like_wasm && self.os != "emscripten", + matches!(self.linker_flavor, LinkerFlavor::WasmLld(..)) + ); assert_eq!(self.os == "emscripten", matches!(self.linker_flavor, LinkerFlavor::EmCc)); assert_eq!(self.arch == "bpf", matches!(self.linker_flavor, LinkerFlavor::Bpf)); assert_eq!(self.arch == "nvptx64", matches!(self.linker_flavor, LinkerFlavor::Ptx)); @@ -38,44 +40,25 @@ impl Target { 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, self.lld_flavor) { - ( - LinkerFlavor::Ld | LinkerFlavor::Lld(LldFlavor::Ld) | LinkerFlavor::Gcc, - LldFlavor::Ld, - ) => { - assert_matches!( - flavor, - LinkerFlavor::Ld | LinkerFlavor::Lld(LldFlavor::Ld) | LinkerFlavor::Gcc - ) - } - (LinkerFlavor::Gcc, LldFlavor::Ld64) => { - assert_matches!( - flavor, - LinkerFlavor::Lld(LldFlavor::Ld64) | LinkerFlavor::Gcc - ) + match self.linker_flavor { + LinkerFlavor::Gnu(..) => { + assert_matches!(flavor, LinkerFlavor::Gnu(..)); } - (LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link), LldFlavor::Link) => { - assert_matches!( - flavor, - LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link) - ) + LinkerFlavor::Darwin(..) => { + assert_matches!(flavor, LinkerFlavor::Darwin(..)) } - (LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc, LldFlavor::Wasm) => { - assert_matches!( - flavor, - LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc - ) + LinkerFlavor::WasmLld(..) => { + assert_matches!(flavor, LinkerFlavor::WasmLld(..)) } - (LinkerFlavor::EmCc, LldFlavor::Wasm) => { - assert_matches!(flavor, LinkerFlavor::EmCc) + LinkerFlavor::Unix(..) => { + assert_matches!(flavor, LinkerFlavor::Unix(..)); } - (LinkerFlavor::Bpf, LldFlavor::Ld) => { - assert_matches!(flavor, LinkerFlavor::Bpf) + LinkerFlavor::Msvc(..) => { + assert_matches!(flavor, LinkerFlavor::Msvc(..)) } - (LinkerFlavor::Ptx, LldFlavor::Ld) => { - assert_matches!(flavor, LinkerFlavor::Ptx) + LinkerFlavor::EmCc | LinkerFlavor::Bpf | LinkerFlavor::Ptx => { + assert_eq!(flavor, self.linker_flavor) } - flavors => unreachable!("unexpected flavor combination: {:?}", flavors), } // Check that link args for cc and non-cc versions of flavors are consistent. @@ -88,25 +71,29 @@ impl Target { } } }; + match self.linker_flavor { - LinkerFlavor::Gcc => match self.lld_flavor { - LldFlavor::Ld => { - check_noncc(LinkerFlavor::Ld); - check_noncc(LinkerFlavor::Lld(LldFlavor::Ld)); - } - LldFlavor::Ld64 => check_noncc(LinkerFlavor::Lld(LldFlavor::Ld64)), - LldFlavor::Wasm => check_noncc(LinkerFlavor::Lld(LldFlavor::Wasm)), - LldFlavor::Link => {} - }, + LinkerFlavor::Gnu(Cc::Yes, lld) => check_noncc(LinkerFlavor::Gnu(Cc::No, lld)), + LinkerFlavor::WasmLld(Cc::Yes) => check_noncc(LinkerFlavor::WasmLld(Cc::No)), + LinkerFlavor::Unix(Cc::Yes) => check_noncc(LinkerFlavor::Unix(Cc::No)), _ => {} } } // Check that link args for lld and non-lld versions of flavors are consistent. - assert_eq!(args.get(&LinkerFlavor::Ld), args.get(&LinkerFlavor::Lld(LldFlavor::Ld))); + for cc in [Cc::No, Cc::Yes] { + assert_eq!( + args.get(&LinkerFlavor::Gnu(cc, Lld::No)), + args.get(&LinkerFlavor::Gnu(cc, Lld::Yes)), + ); + assert_eq!( + args.get(&LinkerFlavor::Darwin(cc, Lld::No)), + args.get(&LinkerFlavor::Darwin(cc, Lld::Yes)), + ); + } assert_eq!( - args.get(&LinkerFlavor::Msvc), - args.get(&LinkerFlavor::Lld(LldFlavor::Link)), + args.get(&LinkerFlavor::Msvc(Lld::No)), + args.get(&LinkerFlavor::Msvc(Lld::Yes)), ); } diff --git a/compiler/rustc_target/src/spec/thumb_base.rs b/compiler/rustc_target/src/spec/thumb_base.rs index 049142b89f1f1..000766c57ce79 100644 --- a/compiler/rustc_target/src/spec/thumb_base.rs +++ b/compiler/rustc_target/src/spec/thumb_base.rs @@ -27,13 +27,12 @@ // differentiate these targets from our other `arm(v7)-*-*-gnueabi(hf)` targets in the context of // build scripts / gcc flags. -use crate::spec::TargetOptions; -use crate::spec::{FramePointer, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, PanicStrategy, RelocModel, TargetOptions}; pub fn opts() -> TargetOptions { // See rust-lang/rfcs#1645 for a discussion about these defaults TargetOptions { - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), // In most cases, LLD is good enough linker: Some("rust-lld".into()), // Because these devices have very little resources having an unwinder is too onerous so we diff --git a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs index bdaaed8b5d0e8..5a3e4c88d3a9b 100644 --- a/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs +++ b/compiler/rustc_target/src/spec/thumbv4t_none_eabi.rs @@ -16,9 +16,8 @@ //! The default link script is very likely wrong, so you should use //! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script. -use crate::spec::{ - cvs, FramePointer, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions, -}; +use crate::spec::{cvs, Cc, FramePointer, LinkerFlavor, Lld}; +use crate::spec::{PanicStrategy, RelocModel, Target, TargetOptions}; pub fn target() -> Target { Target { @@ -37,7 +36,7 @@ pub fn target() -> Target { data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(), options: TargetOptions { abi: "eabi".into(), - linker_flavor: LinkerFlavor::Ld, + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::No), linker: Some("arm-none-eabi-ld".into()), // extra args passed to the external assembler (assuming `arm-none-eabi-as`): diff --git a/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs b/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs index 4d09d3a4d106f..f1be274f067c2 100644 --- a/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs +++ b/compiler/rustc_target/src/spec/thumbv7a_pc_windows_msvc.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, PanicStrategy, Target, TargetOptions}; +use crate::spec::{LinkerFlavor, Lld, PanicStrategy, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::windows_msvc_base::opts(); @@ -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, &["/OPT:NOLBR"]); + base.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &["/OPT:NOLBR"]); Target { llvm_target: "thumbv7a-pc-windows-msvc".into(), diff --git a/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs index 4cad9e1837010..8d80fcd5fe579 100644 --- a/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs +++ b/compiler/rustc_target/src/spec/thumbv7neon_linux_androideabi.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions}; // This target if is for the Android v7a ABI in thumb mode with // NEON unconditionally enabled and, therefore, with 32 FPU registers @@ -10,7 +10,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::android_base::opts(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-march=armv7-a"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-march=armv7-a"]); Target { llvm_target: "armv7-none-linux-android".into(), pointer_width: 32, diff --git a/compiler/rustc_target/src/spec/uefi_msvc_base.rs b/compiler/rustc_target/src/spec/uefi_msvc_base.rs index 99af7d85e1d02..8968d3c8fc100 100644 --- a/compiler/rustc_target/src/spec/uefi_msvc_base.rs +++ b/compiler/rustc_target/src/spec/uefi_msvc_base.rs @@ -9,14 +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::{LinkerFlavor, LldFlavor, PanicStrategy}; -use crate::spec::{StackProbeType, TargetOptions}; +use crate::spec::{LinkerFlavor, Lld, PanicStrategy, StackProbeType, TargetOptions}; pub fn opts() -> TargetOptions { let mut base = super::msvc_base::opts(); base.add_pre_link_args( - LinkerFlavor::Msvc, + LinkerFlavor::Msvc(Lld::No), &[ // Non-standard subsystems have no default entry-point in PE+ files. We have to define // one. "efi_main" seems to be a common choice amongst other implementations and the @@ -37,7 +36,7 @@ pub fn opts() -> TargetOptions { TargetOptions { os: "uefi".into(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Link), + linker_flavor: LinkerFlavor::Msvc(Lld::Yes), disable_redzone: true, exe_suffix: ".efi".into(), allows_weak_linkage: false, diff --git a/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs index 4e2927dd913c2..8dad941b534b6 100644 --- a/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs +++ b/compiler/rustc_target/src/spec/wasm32_unknown_unknown.rs @@ -10,14 +10,12 @@ //! This target is more or less managed by the Rust and WebAssembly Working //! Group nowadays at . -use super::wasm_base; -use super::{LinkerFlavor, LldFlavor, Target}; +use super::{wasm_base, Cc, LinkerFlavor, Target}; use crate::spec::abi::Abi; pub fn target() -> Target { let mut options = wasm_base::options(); options.os = "unknown".into(); - options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm); // This is a default for backwards-compatibility with the original // definition of this target oh-so-long-ago. Once the "wasm" ABI is @@ -30,7 +28,7 @@ pub fn target() -> Target { options.default_adjusted_cabi = Some(Abi::Wasm); options.add_pre_link_args( - LinkerFlavor::Lld(LldFlavor::Wasm), + LinkerFlavor::WasmLld(Cc::No), &[ // For now this target just never has an entry symbol no matter the output // type, so unconditionally pass this. @@ -44,7 +42,7 @@ pub fn target() -> Target { ], ); options.add_pre_link_args( - LinkerFlavor::Gcc, + LinkerFlavor::WasmLld(Cc::Yes), &[ // Make sure clang uses LLD as its linker and is configured appropriately // otherwise diff --git a/compiler/rustc_target/src/spec/wasm32_wasi.rs b/compiler/rustc_target/src/spec/wasm32_wasi.rs index 9c30487f4abe7..93a956403e50f 100644 --- a/compiler/rustc_target/src/spec/wasm32_wasi.rs +++ b/compiler/rustc_target/src/spec/wasm32_wasi.rs @@ -72,15 +72,13 @@ //! best we can with this target. Don't start relying on too much here unless //! you know what you're getting in to! -use super::wasm_base; -use super::{crt_objects, LinkerFlavor, LldFlavor, Target}; +use super::{crt_objects, wasm_base, Cc, LinkerFlavor, Target}; pub fn target() -> Target { let mut options = wasm_base::options(); options.os = "wasi".into(); - options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm); - options.add_pre_link_args(LinkerFlavor::Gcc, &["--target=wasm32-wasi"]); + options.add_pre_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/wasm64_unknown_unknown.rs b/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs index 5211f7707fbb2..3fda398d24c85 100644 --- a/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs +++ b/compiler/rustc_target/src/spec/wasm64_unknown_unknown.rs @@ -7,16 +7,14 @@ //! 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 super::wasm_base; -use super::{LinkerFlavor, LldFlavor, Target}; +use super::{wasm_base, Cc, LinkerFlavor, Target}; pub fn target() -> Target { let mut options = wasm_base::options(); options.os = "unknown".into(); - options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm); options.add_pre_link_args( - LinkerFlavor::Lld(LldFlavor::Wasm), + LinkerFlavor::WasmLld(Cc::No), &[ // For now this target just never has an entry symbol no matter the output // type, so unconditionally pass this. @@ -25,7 +23,7 @@ pub fn target() -> Target { ], ); options.add_pre_link_args( - LinkerFlavor::Gcc, + LinkerFlavor::WasmLld(Cc::Yes), &[ // Make sure clang uses LLD as its linker and is configured appropriately // otherwise diff --git a/compiler/rustc_target/src/spec/wasm_base.rs b/compiler/rustc_target/src/spec/wasm_base.rs index 28a07701eae74..528a84a8b37cb 100644 --- a/compiler/rustc_target/src/spec/wasm_base.rs +++ b/compiler/rustc_target/src/spec/wasm_base.rs @@ -1,5 +1,5 @@ use super::crt_objects::LinkSelfContainedDefault; -use super::{cvs, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel}; +use super::{cvs, Cc, LinkerFlavor, PanicStrategy, RelocModel, TargetOptions, TlsModel}; pub fn options() -> TargetOptions { macro_rules! args { @@ -49,8 +49,8 @@ pub fn options() -> TargetOptions { }; } - let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::Lld(LldFlavor::Wasm), args!("")); - super::add_link_args(&mut pre_link_args, LinkerFlavor::Gcc, args!("-Wl,")); + let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::WasmLld(Cc::No), args!("")); + super::add_link_args(&mut pre_link_args, LinkerFlavor::WasmLld(Cc::Yes), args!("-Wl,")); TargetOptions { is_like_wasm: true, @@ -91,8 +91,7 @@ pub fn options() -> TargetOptions { // we use the LLD shipped with the Rust toolchain by default linker: Some("rust-lld".into()), - lld_flavor: LldFlavor::Wasm, - linker_is_gnu: false, + linker_flavor: LinkerFlavor::WasmLld(Cc::No), pre_link_args, diff --git a/compiler/rustc_target/src/spec/windows_gnu_base.rs b/compiler/rustc_target/src/spec/windows_gnu_base.rs index 81d44a963f1f3..a32ca469b2f58 100644 --- a/compiler/rustc_target/src/spec/windows_gnu_base.rs +++ b/compiler/rustc_target/src/spec/windows_gnu_base.rs @@ -1,10 +1,10 @@ use crate::spec::crt_objects::{self, LinkSelfContainedDefault}; -use crate::spec::{cvs, DebuginfoKind, LinkerFlavor, SplitDebuginfo, TargetOptions}; +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::Ld, + LinkerFlavor::Gnu(Cc::No, Lld::No), &[ // Enable ASLR "--dynamicbase", @@ -14,7 +14,7 @@ pub fn opts() -> TargetOptions { ); super::add_link_args( &mut pre_link_args, - LinkerFlavor::Gcc, + 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. @@ -42,23 +42,33 @@ pub fn opts() -> TargetOptions { "-luser32", "-lkernel32", ]; - let mut late_link_args = TargetOptions::link_args(LinkerFlavor::Ld, mingw_libs); - super::add_link_args(&mut late_link_args, LinkerFlavor::Gcc, mingw_libs); + let mut late_link_args = + TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs); + super::add_link_args(&mut late_link_args, 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::Ld, dynamic_unwind_libs); - super::add_link_args(&mut late_link_args_dynamic, LinkerFlavor::Gcc, dynamic_unwind_libs); + TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), dynamic_unwind_libs); + super::add_link_args( + &mut late_link_args_dynamic, + 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::Ld, static_unwind_libs); - super::add_link_args(&mut late_link_args_static, LinkerFlavor::Gcc, static_unwind_libs); + let mut late_link_args_static = + TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), static_unwind_libs); + super::add_link_args( + &mut late_link_args_static, + LinkerFlavor::Gnu(Cc::Yes, Lld::No), + static_unwind_libs, + ); TargetOptions { os: "windows".into(), diff --git a/compiler/rustc_target/src/spec/windows_gnullvm_base.rs b/compiler/rustc_target/src/spec/windows_gnullvm_base.rs index f30be25497d8a..58210c75a3da2 100644 --- a/compiler/rustc_target/src/spec/windows_gnullvm_base.rs +++ b/compiler/rustc_target/src/spec/windows_gnullvm_base.rs @@ -1,15 +1,17 @@ -use crate::spec::{cvs, LinkerFlavor, TargetOptions}; +use crate::spec::{cvs, Cc, LinkerFlavor, Lld, TargetOptions}; pub fn opts() -> TargetOptions { // We cannot use `-nodefaultlibs` because compiler-rt has to be passed // as a path since it's not added to linker search path by the default. // There were attempts to make it behave like libgcc (so one can just use -l) // but LLVM maintainers rejected it: https://reviews.llvm.org/D51440 - let pre_link_args = - TargetOptions::link_args(LinkerFlavor::Gcc, &["-nolibc", "--unwindlib=none"]); + let pre_link_args = TargetOptions::link_args( + LinkerFlavor::Gnu(Cc::Yes, Lld::No), + &["-nolibc", "--unwindlib=none"], + ); // Order of `late_link_args*` does not matter with LLD. let late_link_args = TargetOptions::link_args( - LinkerFlavor::Gcc, + LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-lmingw32", "-lmingwex", "-lmsvcrt", "-lkernel32", "-luser32"], ); diff --git a/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs b/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs index fa69b919cecd7..f30c33d997e33 100644 --- a/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs +++ b/compiler/rustc_target/src/spec/windows_uwp_gnu_base.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkArgs, LinkerFlavor, TargetOptions}; +use crate::spec::{Cc, LinkArgs, LinkerFlavor, Lld, TargetOptions}; pub fn opts() -> TargetOptions { let base = super::windows_gnu_base::opts(); @@ -15,8 +15,9 @@ pub fn opts() -> TargetOptions { "-lmingwex", "-lmingw32", ]; - let mut late_link_args = TargetOptions::link_args(LinkerFlavor::Ld, mingw_libs); - super::add_link_args(&mut late_link_args, LinkerFlavor::Gcc, mingw_libs); + let mut late_link_args = + TargetOptions::link_args(LinkerFlavor::Gnu(Cc::No, Lld::No), mingw_libs); + super::add_link_args(&mut late_link_args, 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(); diff --git a/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs b/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs index f2573fc2d2115..8c942c59dd035 100644 --- a/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs +++ b/compiler/rustc_target/src/spec/windows_uwp_msvc_base.rs @@ -1,11 +1,11 @@ -use crate::spec::{LinkerFlavor, TargetOptions}; +use crate::spec::{LinkerFlavor, Lld, TargetOptions}; pub fn opts() -> TargetOptions { let mut opts = super::windows_msvc_base::opts(); opts.abi = "uwp".into(); opts.vendor = "uwp".into(); - opts.add_pre_link_args(LinkerFlavor::Msvc, &["/APPCONTAINER", "mincore.lib"]); + opts.add_pre_link_args(LinkerFlavor::Msvc(Lld::No), &["/APPCONTAINER", "mincore.lib"]); opts } diff --git a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs index ad96923320ce8..087be1b957b14 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs @@ -1,5 +1,5 @@ -use crate::spec::TargetOptions; -use crate::spec::{FramePointer, LinkerFlavor, SanitizerSet, StackProbeType, Target}; +use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet}; +use crate::spec::{StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let arch = "x86_64"; @@ -7,7 +7,7 @@ pub fn target() -> Target { base.cpu = "core2".into(); base.max_atomic_width = Some(128); // core2 support cmpxchg16b base.frame_pointer = FramePointer::Always; - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]); base.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove()); base.stack_probes = StackProbeType::X86; base.supported_sanitizers = diff --git a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs index 61591dacf45b3..13259205ac0f8 100644 --- a/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs +++ b/compiler/rustc_target/src/spec/x86_64_apple_ios_macabi.rs @@ -1,11 +1,11 @@ use super::apple_sdk_base::{opts, Arch}; -use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let llvm_target = "x86_64-apple-ios13.0-macabi"; let mut base = opts("ios", Arch::X86_64_macabi); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-target", llvm_target]); + base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-target", llvm_target]); Target { llvm_target: llvm_target.into(), diff --git a/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs index 9d597ea2e62d6..cba6fda19dc3e 100644 --- a/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs +++ b/compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs @@ -1,12 +1,10 @@ use std::borrow::Cow; -use crate::spec::cvs; - -use super::{LinkerFlavor, LldFlavor, Target, TargetOptions}; +use super::{cvs, Cc, LinkerFlavor, Lld, Target, TargetOptions}; pub fn target() -> Target { let pre_link_args = TargetOptions::link_args( - LinkerFlavor::Ld, + LinkerFlavor::Gnu(Cc::No, Lld::No), &[ "-e", "elf_entry", @@ -61,7 +59,7 @@ pub fn target() -> Target { env: "sgx".into(), vendor: "fortanix".into(), abi: "fortanix".into(), - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), max_atomic_width: Some(64), cpu: "x86-64".into(), diff --git a/compiler/rustc_target/src/spec/x86_64_linux_android.rs b/compiler/rustc_target/src/spec/x86_64_linux_android.rs index 4db5ec7fd285b..9c9137848550f 100644 --- a/compiler/rustc_target/src/spec/x86_64_linux_android.rs +++ b/compiler/rustc_target/src/spec/x86_64_linux_android.rs @@ -1,4 +1,4 @@ -use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::android_base::opts(); @@ -6,7 +6,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::Gcc, &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::X86; Target { diff --git a/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs b/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs index 974359a138b9f..cb62a8173222e 100644 --- a/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs +++ b/compiler/rustc_target/src/spec/x86_64_pc_solaris.rs @@ -1,8 +1,8 @@ -use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target}; +use crate::spec::{Cc, LinkerFlavor, SanitizerSet, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::solaris_base::opts(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Unix(Cc::Yes), &["-m64"]); base.cpu = "x86-64".into(); base.vendor = "pc".into(); base.max_atomic_width = Some(64); diff --git a/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs b/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs index 59a8cffca480a..37feaa9dbbf84 100644 --- a/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/x86_64_pc_windows_gnu.rs @@ -1,11 +1,14 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, Target}; pub fn target() -> Target { let mut base = super::windows_gnu_base::opts(); base.cpu = "x86-64".into(); // Use high-entropy 64 bit address space for ASLR - base.add_pre_link_args(LinkerFlavor::Ld, &["-m", "i386pep", "--high-entropy-va"]); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64", "-Wl,--high-entropy-va"]); + 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.max_atomic_width = Some(64); base.linker = Some("x86_64-w64-mingw32-gcc".into()); diff --git a/compiler/rustc_target/src/spec/x86_64_pc_windows_gnullvm.rs b/compiler/rustc_target/src/spec/x86_64_pc_windows_gnullvm.rs index d3909b3895e52..039bc2bd2bb84 100644 --- a/compiler/rustc_target/src/spec/x86_64_pc_windows_gnullvm.rs +++ b/compiler/rustc_target/src/spec/x86_64_pc_windows_gnullvm.rs @@ -1,9 +1,9 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, Target}; pub fn target() -> Target { let mut base = super::windows_gnullvm_base::opts(); base.cpu = "x86-64".into(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.max_atomic_width = Some(64); base.linker = Some("x86_64-w64-mingw32-clang".into()); diff --git a/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs b/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs index a2fe371a2b8fa..0f31ea86b3f16 100644 --- a/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs +++ b/compiler/rustc_target/src/spec/x86_64_sun_solaris.rs @@ -1,8 +1,8 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target}; +use crate::spec::{Cc, LinkerFlavor, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::solaris_base::opts(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Unix(Cc::Yes), &["-m64"]); base.cpu = "x86-64".into(); base.vendor = "sun".into(); base.max_atomic_width = Some(64); diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs index 989e6432b6633..67ce3768db0c8 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_dragonfly.rs @@ -1,10 +1,10 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::dragonfly_base::opts(); base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::X86; Target { diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs index 24b5b4beebc80..98988ab359542 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_freebsd.rs @@ -1,10 +1,10 @@ -use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::freebsd_base::opts(); base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::X86; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::MEMORY | SanitizerSet::THREAD; diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs b/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs index e3f14aeeea91f..9a7a3b501cfdc 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_haiku.rs @@ -1,10 +1,10 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::haiku_base::opts(); base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::X86; // This option is required to build executables on Haiku x86_64 base.position_independent_executables = true; diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs b/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs index 9f19c3a2b2a91..04a12a7bfa642 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_illumos.rs @@ -1,8 +1,8 @@ -use crate::spec::{LinkerFlavor, SanitizerSet, Target}; +use crate::spec::{Cc, LinkerFlavor, SanitizerSet, Target}; pub fn target() -> Target { let mut base = super::illumos_base::opts(); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64", "-std=c99"]); + base.add_pre_link_args(LinkerFlavor::Unix(Cc::Yes), &["-m64", "-std=c99"]); base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI; diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs index 34e20544da694..a91ab365b668a 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnu.rs @@ -1,10 +1,10 @@ -use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::X86; base.static_position_independent_executables = true; base.supported_sanitizers = SanitizerSet::ADDRESS diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs index 23a1f5d80f216..626d5b480c632 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_gnux32.rs @@ -1,11 +1,11 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::linux_gnu_base::opts(); base.cpu = "x86-64".into(); base.abi = "x32".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-mx32"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mx32"]); base.stack_probes = StackProbeType::X86; 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/x86_64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs index 179f099545608..9087dc3df6007 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_linux_musl.rs @@ -1,10 +1,10 @@ -use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::linux_musl_base::opts(); base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::X86; base.static_position_independent_executables = true; base.supported_sanitizers = SanitizerSet::ADDRESS diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs index ac77dfb64157e..64ae425d8c0b7 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_netbsd.rs @@ -1,10 +1,10 @@ -use crate::spec::{LinkerFlavor, SanitizerSet, StackProbeType, Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, SanitizerSet, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { let mut base = super::netbsd_base::opts(); base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::X86; base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_none.rs b/compiler/rustc_target/src/spec/x86_64_unknown_none.rs index 871cdd02078a0..e4d33c2b8c62d 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_none.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_none.rs @@ -4,7 +4,7 @@ // `target-cpu` compiler flags to opt-in more hardware-specific // features. -use super::{CodeModel, LinkerFlavor, LldFlavor, PanicStrategy}; +use super::{Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy}; use super::{RelroLevel, StackProbeType, Target, TargetOptions}; pub fn target() -> Target { @@ -15,7 +15,7 @@ pub fn target() -> Target { position_independent_executables: true, static_position_independent_executables: true, relro_level: RelroLevel::Full, - linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), + linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), linker: Some("rust-lld".into()), features: "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float" diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_none_linuxkernel.rs b/compiler/rustc_target/src/spec/x86_64_unknown_none_linuxkernel.rs index 593345a5f1d8c..ebd9636ff5102 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_none_linuxkernel.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_none_linuxkernel.rs @@ -1,7 +1,7 @@ // This defines the amd64 target for the Linux Kernel. See the linux-kernel-base module for // generic Linux kernel options. -use crate::spec::{CodeModel, LinkerFlavor, Target}; +use crate::spec::{Cc, CodeModel, LinkerFlavor, Lld, Target}; pub fn target() -> Target { let mut base = super::linux_kernel_base::opts(); @@ -10,7 +10,7 @@ pub fn target() -> Target { base.features = "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float".into(); base.code_model = Some(CodeModel::Kernel); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); Target { // FIXME: Some dispute, the linux-on-clang folks think this should use diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs index b8084d513f7fa..66b8e20226f19 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_openbsd.rs @@ -1,10 +1,10 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::openbsd_base::opts(); base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::X86; Target { diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs index a2a143f856de6..b47f15cf57897 100644 --- a/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs +++ b/compiler/rustc_target/src/spec/x86_64_unknown_redox.rs @@ -1,10 +1,10 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::redox_base::opts(); base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::X86; Target { diff --git a/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs b/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs index 76d2013cf7fdc..c3eaa6939bb13 100644 --- a/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs +++ b/compiler/rustc_target/src/spec/x86_64_uwp_windows_gnu.rs @@ -1,11 +1,14 @@ -use crate::spec::{LinkerFlavor, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, Target}; pub fn target() -> Target { let mut base = super::windows_uwp_gnu_base::opts(); base.cpu = "x86-64".into(); // Use high-entropy 64 bit address space for ASLR - base.add_pre_link_args(LinkerFlavor::Ld, &["-m", "i386pep", "--high-entropy-va"]); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64", "-Wl,--high-entropy-va"]); + 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.max_atomic_width = Some(64); Target { diff --git a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs index 187027d388974..365ade6bcf9c0 100644 --- a/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs +++ b/compiler/rustc_target/src/spec/x86_64_wrs_vxworks.rs @@ -1,10 +1,10 @@ -use crate::spec::{LinkerFlavor, StackProbeType, Target}; +use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target}; pub fn target() -> Target { let mut base = super::vxworks_base::opts(); base.cpu = "x86-64".into(); base.max_atomic_width = Some(64); - base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64"]); + base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]); base.stack_probes = StackProbeType::X86; base.disable_redzone = true;