1
Fork 0

rustc_target: Refactor internal linker flavors

In accordance with the design from https://github.com/rust-lang/rust/pull/96827#issuecomment-1208441595
This commit is contained in:
Vadim Petrochenkov 2022-08-06 21:08:46 +03:00
parent 4bd30785eb
commit 572b6a9c60
104 changed files with 569 additions and 438 deletions

View file

@ -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<String, String> {
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).

View file

@ -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<dyn Linker>
}
LinkerFlavor::Ld if sess.target.os == "l4re" => {
LinkerFlavor::Unix(Cc::No) if sess.target.os == "l4re" => {
Box::new(L4Bender::new(cmd, sess)) as Box<dyn Linker>
}
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<dyn Linker>
}
LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => {
Box::new(MsvcLinker { cmd, sess }) as Box<dyn Linker>
}
LinkerFlavor::Lld(LldFlavor::Wasm) => Box::new(WasmLd::new(cmd, sess)) as Box<dyn Linker>,
LinkerFlavor::WasmLld(Cc::No) => Box::new(WasmLd::new(cmd, sess)) as Box<dyn Linker>,
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<dyn Linker>,
LinkerFlavor::Msvc(..) => Box::new(MsvcLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::EmCc => Box::new(EmLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::Bpf => Box::new(BpfLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::Ptx => Box::new(PtxLinker { cmd, sess }) as Box<dyn Linker>,
@ -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

View file

@ -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(),

View file

@ -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(),

View file

@ -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,

View file

@ -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,

View file

@ -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(),

View file

@ -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<str> = 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

View file

@ -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,

View file

@ -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,

View file

@ -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.

View file

@ -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()),

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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"],

View file

@ -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,

View file

@ -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;

View file

@ -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;

View file

@ -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(),

View file

@ -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.

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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

View file

@ -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 {

View file

@ -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 {

View file

@ -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(),

View file

@ -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 {

View file

@ -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,

View file

@ -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()

View file

@ -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,

View file

@ -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),

View file

@ -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<StaticCow<str>>,
/// 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<StaticCow<str>>,
/// Environment variables to be set for the linker invocation.
pub link_env: StaticCow<[(StaticCow<str>, StaticCow<str>)]>,
@ -1575,20 +1671,36 @@ 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<Item = StaticCow<str>> + 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::Gcc | LinkerFlavor::EmCc | LinkerFlavor::Bpf | LinkerFlavor::Ptx => {}
LinkerFlavor::Darwin(cc, lld) => {
assert_eq!(lld, Lld::No);
insert(LinkerFlavor::Darwin(cc, Lld::Yes));
}
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 {
@ -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");

View file

@ -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

View file

@ -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,

View file

@ -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(),

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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),

View file

@ -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(),

View file

@ -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),

View file

@ -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(),

View file

@ -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),

View file

@ -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,

View file

@ -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 {

View file

@ -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 {

View file

@ -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(),

View file

@ -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();

View file

@ -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
)
match self.linker_flavor {
LinkerFlavor::Gnu(..) => {
assert_matches!(flavor, LinkerFlavor::Gnu(..));
}
(LinkerFlavor::Gcc, LldFlavor::Ld64) => {
assert_matches!(
flavor,
LinkerFlavor::Lld(LldFlavor::Ld64) | LinkerFlavor::Gcc
)
LinkerFlavor::Darwin(..) => {
assert_matches!(flavor, LinkerFlavor::Darwin(..))
}
(LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link), LldFlavor::Link) => {
assert_matches!(
flavor,
LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link)
)
LinkerFlavor::WasmLld(..) => {
assert_matches!(flavor, LinkerFlavor::WasmLld(..))
}
(LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc, LldFlavor::Wasm) => {
assert_matches!(
flavor,
LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc
)
LinkerFlavor::Unix(..) => {
assert_matches!(flavor, LinkerFlavor::Unix(..));
}
(LinkerFlavor::EmCc, LldFlavor::Wasm) => {
assert_matches!(flavor, LinkerFlavor::EmCc)
LinkerFlavor::Msvc(..) => {
assert_matches!(flavor, LinkerFlavor::Msvc(..))
}
(LinkerFlavor::Bpf, LldFlavor::Ld) => {
assert_matches!(flavor, LinkerFlavor::Bpf)
LinkerFlavor::EmCc | LinkerFlavor::Bpf | LinkerFlavor::Ptx => {
assert_eq!(flavor, self.linker_flavor)
}
(LinkerFlavor::Ptx, LldFlavor::Ld) => {
assert_matches!(flavor, LinkerFlavor::Ptx)
}
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::Msvc),
args.get(&LinkerFlavor::Lld(LldFlavor::Link)),
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(Lld::No)),
args.get(&LinkerFlavor::Msvc(Lld::Yes)),
);
}

View file

@ -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

View file

@ -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`):

View file

@ -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(),

View file

@ -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,

View file

@ -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,

View file

@ -10,14 +10,12 @@
//! This target is more or less managed by the Rust and WebAssembly Working
//! Group nowadays at <https://github.com/rustwasm>.
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

View file

@ -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();

View file

@ -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

View file

@ -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,

View file

@ -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(),

View file

@ -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<name>)
// 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"],
);

View file

@ -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();

View file

@ -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
}

View file

@ -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 =

View file

@ -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(),

View file

@ -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(),

View file

@ -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 {

View file

@ -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);

View file

@ -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());

View file

@ -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());

View file

@ -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);

View file

@ -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 {

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -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

Some files were not shown because too many files have changed in this diff Show more