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::symbol::Symbol;
use rustc_span::DebuggerVisualizerFile; use rustc_span::DebuggerVisualizerFile;
use rustc_target::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault}; use rustc_target::spec::crt_objects::{CrtObjects, LinkSelfContainedDefault};
use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor, SplitDebuginfo}; use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy};
use rustc_target::spec::{PanicStrategy, RelocModel, RelroLevel, SanitizerSet, Target}; use rustc_target::spec::{RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, Target};
use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder}; use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
use super::command::Command; use super::command::Command;
@ -748,8 +748,7 @@ fn link_natively<'a>(
// then it should not default to linking executables as pie. Different // then it should not default to linking executables as pie. Different
// versions of gcc seem to use different quotes in the error message so // versions of gcc seem to use different quotes in the error message so
// don't check for them. // don't check for them.
if sess.target.linker_is_gnu if matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _))
&& flavor != LinkerFlavor::Ld
&& unknown_arg_regex.is_match(&out) && unknown_arg_regex.is_match(&out)
&& out.contains("-no-pie") && out.contains("-no-pie")
&& cmd.get_args().iter().any(|e| e.to_string_lossy() == "-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. // Detect '-static-pie' used with an older version of gcc or clang not supporting it.
// Fallback from '-static-pie' to '-static' in that case. // Fallback from '-static-pie' to '-static' in that case.
if sess.target.linker_is_gnu if matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _))
&& flavor != LinkerFlavor::Ld
&& unknown_arg_regex.is_match(&out) && unknown_arg_regex.is_match(&out)
&& (out.contains("-static-pie") || out.contains("--no-dynamic-linker")) && (out.contains("-static-pie") || out.contains("--no-dynamic-linker"))
&& cmd.get_args().iter().any(|e| e.to_string_lossy() == "-static-pie") && 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. // install the Visual Studio build tools.
if let Some(code) = prog.status.code() { if let Some(code) = prog.status.code() {
if sess.target.is_like_msvc if sess.target.is_like_msvc
&& flavor == LinkerFlavor::Msvc && flavor == LinkerFlavor::Msvc(Lld::No)
// Respect the command line override // Respect the command line override
&& sess.opts.cg.linker.is_none() && sess.opts.cg.linker.is_none()
// Match exactly "link.exe" // 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 // only the linker flavor is known; use the default linker for the selected flavor
(None, Some(flavor)) => Some(( (None, Some(flavor)) => Some((
PathBuf::from(match flavor { 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")) { if cfg!(any(target_os = "solaris", target_os = "illumos")) {
// On historical Solaris systems, "cc" may have // On historical Solaris systems, "cc" may have
// been Sun Studio, which is not flag-compatible // been Sun Studio, which is not flag-compatible
@ -1200,9 +1201,14 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
"cc" "cc"
} }
} }
LinkerFlavor::Ld => "ld", LinkerFlavor::Gnu(_, Lld::Yes)
LinkerFlavor::Lld(_) => "lld", | LinkerFlavor::Darwin(_, Lld::Yes)
LinkerFlavor::Msvc => "link.exe", | LinkerFlavor::WasmLld(..)
| LinkerFlavor::Msvc(Lld::Yes) => "lld",
LinkerFlavor::Gnu(..) | LinkerFlavor::Darwin(..) | LinkerFlavor::Unix(..) => {
"ld"
}
LinkerFlavor::Msvc(..) => "link.exe",
LinkerFlavor::EmCc => { LinkerFlavor::EmCc => {
if cfg!(windows) { if cfg!(windows) {
"emcc.bat" "emcc.bat"
@ -1227,15 +1233,20 @@ pub fn linker_and_flavor(sess: &Session) -> (PathBuf, LinkerFlavor) {
|| stem == "clang" || stem == "clang"
|| stem.ends_with("-clang") || stem.ends_with("-clang")
{ {
LinkerFlavor::Gcc LinkerFlavor::from_cli(LinkerFlavorCli::Gcc, &sess.target)
} else if stem == "wasm-ld" || stem.ends_with("-wasm-ld") { } else if stem == "wasm-ld" || stem.ends_with("-wasm-ld") {
LinkerFlavor::Lld(LldFlavor::Wasm) LinkerFlavor::WasmLld(Cc::No)
} else if stem == "ld" || stem == "ld.lld" || stem.ends_with("-ld") { } else if stem == "ld" || stem.ends_with("-ld") {
LinkerFlavor::Ld LinkerFlavor::from_cli(LinkerFlavorCli::Ld, &sess.target)
} else if stem == "link" || stem == "lld-link" { } else if stem == "ld.lld" {
LinkerFlavor::Msvc 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" { } 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 { } else {
// fall back to the value in the target spec // fall back to the value in the target spec
sess.target.linker_flavor 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 // linker and linker flavor specified via command line have precedence over what the target
// specification specifies // 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) { if let Some(ret) = infer_from(sess, sess.opts.cg.linker.clone(), linker_flavor) {
return ret; return ret;
} }
@ -1320,7 +1332,7 @@ fn print_native_static_libs(sess: &Session, all_native_libs: &[NativeLib]) {
let verbatim = lib.verbatim.unwrap_or(false); let verbatim = lib.verbatim.unwrap_or(false);
if sess.target.is_like_msvc { if sess.target.is_like_msvc {
Some(format!("{}{}", name, if verbatim { "" } else { ".lib" })) 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)) Some(format!("-l{}{}", if verbatim { ":" } else { "" }, name))
} else { } else {
Some(format!("-l{}", name)) Some(format!("-l{}", name))
@ -1607,7 +1619,7 @@ fn add_pre_link_objects(
let empty = Default::default(); let empty = Default::default();
let objects = if self_contained { let objects = if self_contained {
&opts.pre_link_objects_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 &opts.pre_link_objects
} else { } else {
&empty &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) { fn add_link_script(cmd: &mut dyn Linker, sess: &Session, tmpdir: &Path, crate_type: CrateType) {
match (crate_type, &sess.target.link_script) { match (crate_type, &sess.target.link_script) {
(CrateType::Cdylib | CrateType::Executable, Some(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"); 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(), out_filename: out_filename.to_path_buf(),
has_rpath: sess.target.has_rpath, has_rpath: sess.target.has_rpath,
is_like_osx: sess.target.is_like_osx, 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)); cmd.args(&rpath::get_rpath_flags(&mut rpath_config));
} }
@ -2104,7 +2116,7 @@ fn add_order_independent_options(
if sess.target.os == "fuchsia" if sess.target.os == "fuchsia"
&& crate_type == CrateType::Executable && crate_type == CrateType::Executable
&& flavor != LinkerFlavor::Gcc && !matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _))
{ {
let prefix = if sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::ADDRESS) { let prefix = if sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::ADDRESS) {
"asan/" "asan/"
@ -2717,12 +2729,12 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
let llvm_target = &sess.target.llvm_target; let llvm_target = &sess.target.llvm_target;
if sess.target.vendor != "apple" if sess.target.vendor != "apple"
|| !matches!(os.as_ref(), "ios" | "tvos" | "watchos" | "macos") || !matches!(os.as_ref(), "ios" | "tvos" | "watchos" | "macos")
|| (flavor != LinkerFlavor::Gcc && flavor != LinkerFlavor::Lld(LldFlavor::Ld64)) || !matches!(flavor, LinkerFlavor::Darwin(..))
{ {
return; return;
} }
if os == "macos" && flavor != LinkerFlavor::Lld(LldFlavor::Ld64) { if os == "macos" && !matches!(flavor, LinkerFlavor::Darwin(Cc::No, _)) {
return; return;
} }
@ -2756,10 +2768,10 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
}; };
match flavor { match flavor {
LinkerFlavor::Gcc => { LinkerFlavor::Darwin(Cc::Yes, _) => {
cmd.args(&["-isysroot", &sdk_root, "-Wl,-syslibroot", &sdk_root]); cmd.args(&["-isysroot", &sdk_root, "-Wl,-syslibroot", &sdk_root]);
} }
LinkerFlavor::Lld(LldFlavor::Ld64) => { LinkerFlavor::Darwin(Cc::No, _) => {
cmd.args(&["-syslibroot", &sdk_root]); cmd.args(&["-syslibroot", &sdk_root]);
} }
_ => unreachable!(), _ => 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) { 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 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 { match ld_impl {
LdImpl::Lld => { LdImpl::Lld => {
// Implement the "self-contained" part of -Zgcc-ld // 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 // Implement the "linker flavor" part of -Zgcc-ld
// by asking cc to use some kind of lld. // by asking cc to use some kind of lld.
cmd.arg("-fuse-ld=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. // Tell clang to use a non-default LLD flavor.
// Gcc doesn't understand the target option, but we currently assume // Gcc doesn't understand the target option, but we currently assume
// that gcc is not used for Apple and Wasm targets (#97402). // 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_middle::ty::TyCtxt;
use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip}; use rustc_session::config::{self, CrateType, DebugInfo, LinkerPluginLto, Lto, OptLevel, Strip};
use rustc_session::Session; use rustc_session::Session;
use rustc_target::spec::{LinkOutputKind, LinkerFlavor, LldFlavor}; use rustc_target::spec::{Cc, LinkOutputKind, LinkerFlavor, Lld};
use cc::windows_registry; use cc::windows_registry;
@ -56,8 +56,13 @@ pub fn get_linker<'a>(
let mut cmd = match linker.to_str() { let mut cmd = match linker.to_str() {
Some(linker) if cfg!(windows) && linker.ends_with(".bat") => Command::bat_script(linker), Some(linker) if cfg!(windows) && linker.ends_with(".bat") => Command::bat_script(linker),
_ => match flavor { _ => match flavor {
LinkerFlavor::Lld(f) => Command::lld(linker, f), LinkerFlavor::Gnu(Cc::No, Lld::Yes)
LinkerFlavor::Msvc if sess.opts.cg.linker.is_none() && sess.target.linker.is_none() => { | 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(msvc_tool.as_ref().map_or(linker, |t| t.path()))
} }
_ => Command::new(linker), _ => Command::new(linker),
@ -68,9 +73,7 @@ pub fn get_linker<'a>(
// To comply with the Windows App Certification Kit, // To comply with the Windows App Certification Kit,
// MSVC needs to link with the Store versions of the runtime libraries (vcruntime, msvcrt, etc). // MSVC needs to link with the Store versions of the runtime libraries (vcruntime, msvcrt, etc).
let t = &sess.target; let t = &sess.target;
if (flavor == LinkerFlavor::Msvc || flavor == LinkerFlavor::Lld(LldFlavor::Link)) if matches!(flavor, LinkerFlavor::Msvc(..)) && t.vendor == "uwp" {
&& t.vendor == "uwp"
{
if let Some(ref tool) = msvc_tool { if let Some(ref tool) = msvc_tool {
let original_path = tool.path(); let original_path = tool.path();
if let Some(ref root_lib_path) = original_path.ancestors().nth(4) { 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. // to the linker args construction.
assert!(cmd.get_args().is_empty() || sess.target.vendor == "uwp"); assert!(cmd.get_args().is_empty() || sess.target.vendor == "uwp");
match flavor { match flavor {
LinkerFlavor::Gcc => { LinkerFlavor::Unix(Cc::No) if sess.target.os == "l4re" => {
Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: false })
as Box<dyn Linker>
}
LinkerFlavor::Ld if sess.target.os == "l4re" => {
Box::new(L4Bender::new(cmd, sess)) as Box<dyn Linker> Box::new(L4Bender::new(cmd, sess)) as Box<dyn Linker>
} }
LinkerFlavor::Lld(LldFlavor::Ld) LinkerFlavor::WasmLld(Cc::No) => Box::new(WasmLd::new(cmd, sess)) as Box<dyn Linker>,
| LinkerFlavor::Lld(LldFlavor::Ld64) LinkerFlavor::Gnu(cc, _)
| LinkerFlavor::Ld => { | LinkerFlavor::Darwin(cc, _)
Box::new(GccLinker { cmd, sess, target_cpu, hinted_static: false, is_ld: true }) | LinkerFlavor::WasmLld(cc)
as Box<dyn Linker> | LinkerFlavor::Unix(cc) => Box::new(GccLinker {
} cmd,
LinkerFlavor::Lld(LldFlavor::Link) | LinkerFlavor::Msvc => { sess,
Box::new(MsvcLinker { cmd, sess }) as Box<dyn Linker> target_cpu,
} hinted_static: false,
LinkerFlavor::Lld(LldFlavor::Wasm) => Box::new(WasmLd::new(cmd, sess)) as Box<dyn Linker>, 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::EmCc => Box::new(EmLinker { cmd, sess }) as Box<dyn Linker>,
LinkerFlavor::Bpf => Box::new(BpfLinker { 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>, 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. hinted_static: bool, // Keeps track of the current hinting mode.
// Link as ld // Link as ld
is_ld: bool, is_ld: bool,
is_gnu: bool,
} }
impl<'a> GccLinker<'a> { 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) { fn set_output_kind(&mut self, output_kind: LinkOutputKind, out_filename: &Path) {
match output_kind { match output_kind {
LinkOutputKind::DynamicNoPicExe => { LinkOutputKind::DynamicNoPicExe => {
if !self.is_ld && self.sess.target.linker_is_gnu { if !self.is_ld && self.is_gnu {
self.cmd.arg("-no-pie"); self.cmd.arg("-no-pie");
} }
} }
@ -373,7 +376,7 @@ impl<'a> Linker for GccLinker<'a> {
LinkOutputKind::StaticNoPicExe => { LinkOutputKind::StaticNoPicExe => {
// `-static` works for both gcc wrapper and ld. // `-static` works for both gcc wrapper and ld.
self.cmd.arg("-static"); 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"); self.cmd.arg("-no-pie");
} }
} }
@ -432,31 +435,25 @@ impl<'a> Linker for GccLinker<'a> {
// has -needed-l{} / -needed_library {} // has -needed-l{} / -needed_library {}
// but we have no way to detect that here. // but we have no way to detect that here.
self.sess.warn("`as-needed` modifier not implemented yet for ld64"); 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"); self.linker_arg("--no-as-needed");
} else { } else {
self.sess.warn("`as-needed` modifier not supported for current linker"); self.sess.warn("`as-needed` modifier not supported for current linker");
} }
} }
self.hint_dynamic(); self.hint_dynamic();
self.cmd.arg(format!( self.cmd.arg(format!("-l{}{lib}", if verbatim && self.is_gnu { ":" } else { "" },));
"-l{}{lib}",
if verbatim && self.sess.target.linker_is_gnu { ":" } else { "" },
));
if !as_needed { if !as_needed {
if self.sess.target.is_like_osx { if self.sess.target.is_like_osx {
// See above FIXME comment // 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"); self.linker_arg("--as-needed");
} }
} }
} }
fn link_staticlib(&mut self, lib: &str, verbatim: bool) { fn link_staticlib(&mut self, lib: &str, verbatim: bool) {
self.hint_static(); self.hint_static();
self.cmd.arg(format!( self.cmd.arg(format!("-l{}{lib}", if verbatim && self.is_gnu { ":" } else { "" },));
"-l{}{lib}",
if verbatim && self.sess.target.linker_is_gnu { ":" } else { "" },
));
} }
fn link_rlib(&mut self, lib: &Path) { fn link_rlib(&mut self, lib: &Path) {
self.hint_static(); self.hint_static();
@ -511,10 +508,7 @@ impl<'a> Linker for GccLinker<'a> {
let target = &self.sess.target; let target = &self.sess.target;
if !target.is_like_osx { if !target.is_like_osx {
self.linker_arg("--whole-archive"); self.linker_arg("--whole-archive");
self.cmd.arg(format!( self.cmd.arg(format!("-l{}{lib}", if verbatim && self.is_gnu { ":" } else { "" },));
"-l{}{lib}",
if verbatim && self.sess.target.linker_is_gnu { ":" } else { "" },
));
self.linker_arg("--no-whole-archive"); self.linker_arg("--no-whole-archive");
} else { } else {
// -force_load is the macOS equivalent of --whole-archive, but it // -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, // 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% // --gc-sections drops the size of hello world from 1.8MB to 597K, a 67%
// reduction. // reduction.
} else if (self.sess.target.linker_is_gnu || self.sess.target.is_like_wasm) } else if (self.is_gnu || self.sess.target.is_like_wasm) && !keep_metadata {
&& !keep_metadata
{
self.linker_arg("--gc-sections"); self.linker_arg("--gc-sections");
} }
} }
fn no_gc_sections(&mut self) { 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"); self.linker_arg("--no-gc-sections");
} }
} }
fn optimize(&mut self) { 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; return;
} }
@ -587,7 +579,7 @@ impl<'a> Linker for GccLinker<'a> {
} }
fn pgo_gen(&mut self) { fn pgo_gen(&mut self) {
if !self.sess.target.linker_is_gnu { if !self.is_gnu {
return; return;
} }
@ -758,13 +750,13 @@ impl<'a> Linker for GccLinker<'a> {
fn add_no_exec(&mut self) { fn add_no_exec(&mut self) {
if self.sess.target.is_like_windows { if self.sess.target.is_like_windows {
self.linker_arg("--nxcompat"); self.linker_arg("--nxcompat");
} else if self.sess.target.linker_is_gnu { } else if self.is_gnu {
self.linker_arg("-znoexecstack"); self.linker_arg("-znoexecstack");
} }
} }
fn add_as_needed(&mut self) { 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"); self.linker_arg("--as-needed");
} else if self.sess.target.is_like_solaris { } else if self.sess.target.is_like_solaris {
// -z ignore is the Solaris equivalent to the GNU ld --as-needed option // -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 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 { pub fn target() -> Target {
let llvm_target = "arm64-apple-ios14.0-macabi"; let llvm_target = "arm64-apple-ios14.0-macabi";
let mut base = opts("ios", Arch::Arm64_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 { Target {
llvm_target: llvm_target.into(), 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"); 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(), data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(),
arch: "aarch64".into(), arch: "aarch64".into(),
options: TargetOptions { options: TargetOptions {
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
link_script: Some(LINKER_SCRIPT.into()), link_script: Some(LINKER_SCRIPT.into()),
os: "horizon".into(), os: "horizon".into(),

View file

@ -6,11 +6,11 @@
// //
// For example, `-C target-cpu=cortex-a53`. // 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 { pub fn target() -> Target {
let opts = TargetOptions { let opts = TargetOptions {
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
features: "+strict-align,+neon,+fp-armv8".into(), features: "+strict-align,+neon,+fp-armv8".into(),
relocation_model: RelocModel::Static, relocation_model: RelocModel::Static,

View file

@ -6,12 +6,12 @@
// //
// For example, `-C target-cpu=cortex-a53`. // 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 { pub fn target() -> Target {
let opts = TargetOptions { let opts = TargetOptions {
abi: "softfloat".into(), abi: "softfloat".into(),
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
features: "+strict-align,-neon,-fp-armv8".into(), features: "+strict-align,-neon,-fp-armv8".into(),
relocation_model: RelocModel::Static, relocation_model: RelocModel::Static,

View file

@ -2,13 +2,13 @@
// uefi-base module for generic UEFI options. // uefi-base module for generic UEFI options.
use super::uefi_msvc_base; use super::uefi_msvc_base;
use crate::spec::{LinkerFlavor, Target}; use crate::spec::{LinkerFlavor, Lld, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = uefi_msvc_base::opts(); let mut base = uefi_msvc_base::opts();
base.max_atomic_width = Some(128); 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 { Target {
llvm_target: "aarch64-unknown-windows".into(), llvm_target: "aarch64-unknown-windows".into(),

View file

@ -1,7 +1,7 @@
use std::{borrow::Cow, env}; use std::{borrow::Cow, env};
use crate::spec::{cvs, DebuginfoKind, FramePointer, SplitDebuginfo, StaticCow, TargetOptions}; use crate::spec::{cvs, Cc, DebuginfoKind, FramePointer, LinkArgs};
use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor}; use crate::spec::{LinkerFlavor, Lld, SplitDebuginfo, StaticCow, TargetOptions};
fn pre_link_args(os: &'static str, arch: &'static str, abi: &'static str) -> LinkArgs { fn pre_link_args(os: &'static str, arch: &'static str, abi: &'static str) -> LinkArgs {
let platform_name: StaticCow<str> = match abi { 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(); .into();
let mut args = TargetOptions::link_args( let mut args = TargetOptions::link_args(
LinkerFlavor::Lld(LldFlavor::Ld64), LinkerFlavor::Darwin(Cc::No, Lld::No),
&["-arch", arch, "-platform_version"], &["-arch", arch, "-platform_version"],
); );
// Manually add owned args unsupported by link arg building helpers. super::add_link_args_iter(
args.entry(LinkerFlavor::Lld(LldFlavor::Ld64)).or_default().extend([ &mut args,
platform_name, LinkerFlavor::Darwin(Cc::No, Lld::No),
platform_version.clone(), [platform_name, platform_version.clone(), platform_version].into_iter(),
platform_version, );
]);
if abi != "macabi" { 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 args
@ -55,11 +54,11 @@ pub fn opts(os: &'static str, arch: &'static str, abi: &'static str) -> TargetOp
TargetOptions { TargetOptions {
os: os.into(), os: os.into(),
vendor: "apple".into(), vendor: "apple".into(),
linker_flavor: LinkerFlavor::Darwin(Cc::Yes, Lld::No),
// macOS has -dead_strip, which doesn't rely on function_sections // macOS has -dead_strip, which doesn't rely on function_sections
function_sections: false, function_sections: false,
dynamic_linking: true, dynamic_linking: true,
pre_link_args: pre_link_args(os, arch, abi), pre_link_args: pre_link_args(os, arch, abi),
linker_is_gnu: false,
families: cvs!["unix"], families: cvs!["unix"],
is_like_osx: true, is_like_osx: true,
default_dwarf_version: 2, 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, abi_return_struct_as_int: true,
emit_debug_gdb_scripts: false, emit_debug_gdb_scripts: false,
eh_frame_header: false, eh_frame_header: false,
lld_flavor: LldFlavor::Ld64,
debuginfo_kind: DebuginfoKind::DwarfDsym, debuginfo_kind: DebuginfoKind::DwarfDsym,
// The historical default for macOS targets is to run `dsymutil` which // 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) // Targets the Big endian Cortex-R4/R5 processor (ARMv7-R)
use crate::abi::Endian; use crate::abi::Endian;
use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
Target { Target {
@ -13,7 +12,7 @@ pub fn target() -> Target {
options: TargetOptions { options: TargetOptions {
abi: "eabi".into(), abi: "eabi".into(),
endian: Endian::Big, endian: Endian::Big,
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
relocation_model: RelocModel::Static, relocation_model: RelocModel::Static,
panic_strategy: PanicStrategy::Abort, panic_strategy: PanicStrategy::Abort,

View file

@ -1,8 +1,7 @@
// Targets the Cortex-R4F/R5F processor (ARMv7-R) // Targets the Cortex-R4F/R5F processor (ARMv7-R)
use crate::abi::Endian; use crate::abi::Endian;
use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
Target { Target {
@ -13,7 +12,7 @@ pub fn target() -> Target {
options: TargetOptions { options: TargetOptions {
abi: "eabihf".into(), abi: "eabihf".into(),
endian: Endian::Big, endian: Endian::Big,
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
relocation_model: RelocModel::Static, relocation_model: RelocModel::Static,
panic_strategy: PanicStrategy::Abort, panic_strategy: PanicStrategy::Abort,

View file

@ -16,7 +16,7 @@
//! The default link script is very likely wrong, so you should use //! 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. //! `-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 { pub fn target() -> 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(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(),
options: TargetOptions { options: TargetOptions {
abi: "eabi".into(), abi: "eabi".into(),
linker_flavor: LinkerFlavor::Ld, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::No),
linker: Some("arm-none-eabi-ld".into()), linker: Some("arm-none-eabi-ld".into()),
asm_args: cvs!["-mthumb-interwork", "-march=armv4t", "-mlittle-endian",], asm_args: cvs!["-mthumb-interwork", "-march=armv4t", "-mlittle-endian",],
// Force-enable 32-bit atomics, which allows the use of atomic load/store only. // 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. /// 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 { pub fn target() -> Target {
let pre_link_args = TargetOptions::link_args( 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"], &["-specs=3dsx.specs", "-mtune=mpcore", "-mfloat-abi=hard", "-mtp=soft"],
); );
@ -21,7 +21,6 @@ pub fn target() -> Target {
env: "newlib".into(), env: "newlib".into(),
vendor: "nintendo".into(), vendor: "nintendo".into(),
abi: "eabihf".into(), abi: "eabihf".into(),
linker_flavor: LinkerFlavor::Gcc,
cpu: "mpcore".into(), cpu: "mpcore".into(),
families: cvs!["unix"], families: cvs!["unix"],
linker: Some("arm-none-eabi-gcc".into()), 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 // This target if is for the baseline of the Android v7a ABI
// in thumb mode. It's named armv7-* instead of thumbv7-* // 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 { pub fn target() -> Target {
let mut base = super::android_base::opts(); 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 { Target {
llvm_target: "armv7-none-linux-android".into(), llvm_target: "armv7-none-linux-android".into(),
pointer_width: 32, pointer_width: 32,

View file

@ -14,12 +14,12 @@
// - `relocation-model` set to `static`; also no PIE, no relro and no dynamic // - `relocation-model` set to `static`; also no PIE, no relro and no dynamic
// linking. rationale: matches `thumb` targets // 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 { pub fn target() -> Target {
let opts = TargetOptions { let opts = TargetOptions {
abi: "eabi".into(), abi: "eabi".into(),
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
features: "+v7,+thumb2,+soft-float,-neon,+strict-align".into(), features: "+v7,+thumb2,+soft-float,-neon,+strict-align".into(),
relocation_model: RelocModel::Static, 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 // changes (list in `armv7a_none_eabi.rs`) to bring it closer to the bare-metal
// `thumb` & `aarch64` targets. // `thumb` & `aarch64` targets.
use super::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel, Target, TargetOptions}; use super::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let opts = TargetOptions { let opts = TargetOptions {
abi: "eabihf".into(), abi: "eabihf".into(),
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
features: "+v7,+vfp3,-d32,+thumb2,-neon,+strict-align".into(), features: "+v7,+vfp3,-d32,+thumb2,-neon,+strict-align".into(),
relocation_model: RelocModel::Static, relocation_model: RelocModel::Static,

View file

@ -1,7 +1,6 @@
// Targets the Little-endian Cortex-R4/R5 processor (ARMv7-R) // Targets the Little-endian Cortex-R4/R5 processor (ARMv7-R)
use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
Target { Target {
@ -12,7 +11,7 @@ pub fn target() -> Target {
options: TargetOptions { options: TargetOptions {
abi: "eabi".into(), abi: "eabi".into(),
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
relocation_model: RelocModel::Static, relocation_model: RelocModel::Static,
panic_strategy: PanicStrategy::Abort, panic_strategy: PanicStrategy::Abort,

View file

@ -1,7 +1,6 @@
// Targets the Little-endian Cortex-R4F/R5F processor (ARMv7-R) // Targets the Little-endian Cortex-R4F/R5F processor (ARMv7-R)
use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
Target { Target {
@ -12,7 +11,7 @@ pub fn target() -> Target {
options: TargetOptions { options: TargetOptions {
abi: "eabihf".into(), abi: "eabihf".into(),
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
relocation_model: RelocModel::Static, relocation_model: RelocModel::Static,
panic_strategy: PanicStrategy::Abort, 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. /// 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()), linker: Some("avr-gcc".into()),
eh_frame_header: false, eh_frame_header: false,
pre_link_args: TargetOptions::link_args(LinkerFlavor::Gcc, &[mmcu]), pre_link_args: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &[mmcu]),
late_link_args: TargetOptions::link_args(LinkerFlavor::Gcc, &["-lgcc"]), late_link_args: TargetOptions::link_args(
LinkerFlavor::Gnu(Cc::Yes, Lld::No),
&["-lgcc"],
),
max_atomic_width: Some(0), max_atomic_width: Some(0),
atomic_cas: false, atomic_cas: false,
relocation_model: RelocModel::Static, 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 { pub fn opts() -> TargetOptions {
// This mirrors the linker options provided by clang. We presume lld for // 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 // https://github.com/llvm/llvm-project/blob/db9322b2066c55254e7691efeab863f43bfcc084/clang/lib/Driver/ToolChains/Fuchsia.cpp#L31
let pre_link_args = TargetOptions::link_args( let pre_link_args = TargetOptions::link_args(
LinkerFlavor::Ld, LinkerFlavor::Gnu(Cc::No, Lld::No),
&[ &[
"--build-id", "--build-id",
"--hash-style=gnu", "--hash-style=gnu",
@ -25,7 +25,7 @@ pub fn opts() -> TargetOptions {
TargetOptions { TargetOptions {
os: "fuchsia".into(), os: "fuchsia".into(),
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
dynamic_linking: true, dynamic_linking: true,
families: cvs!["unix"], 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 { pub fn opts() -> TargetOptions {
let pre_link_args = TargetOptions::link_args( let pre_link_args = TargetOptions::link_args(
LinkerFlavor::Ld, LinkerFlavor::Gnu(Cc::No, Lld::No),
&["--build-id", "--hash-style=gnu", "--Bstatic"], &["--build-id", "--hash-style=gnu", "--Bstatic"],
); );
TargetOptions { TargetOptions {
os: "hermit".into(), os: "hermit".into(),
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
has_thread_local: true, has_thread_local: true,
pre_link_args, pre_link_args,

View file

@ -1,4 +1,4 @@
use crate::spec::Target; use crate::spec::{Cc, LinkerFlavor, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::linux_musl_base::opts(); let mut base = super::linux_musl_base::opts();
@ -9,7 +9,7 @@ pub fn target() -> Target {
base.crt_static_default = false; base.crt_static_default = false;
base.has_rpath = true; base.has_rpath = true;
base.linker_is_gnu = false; base.linker_flavor = LinkerFlavor::Unix(Cc::Yes);
base.c_enum_min_bits = 8; 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 { pub fn target() -> Target {
// ld64 only understand i386 and not i686 // ld64 only understand i386 and not i686
let mut base = super::apple_base::opts("macos", "i386", ""); let mut base = super::apple_base::opts("macos", "i386", "");
base.cpu = "yonah".into(); base.cpu = "yonah".into();
base.max_atomic_width = Some(64); 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.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove());
base.stack_probes = StackProbeType::X86; base.stack_probes = StackProbeType::X86;
base.frame_pointer = FramePointer::Always; 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 { pub fn target() -> Target {
let mut base = super::windows_gnu_base::opts(); 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 // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
// space available to x86 Windows binaries on x86_64. // 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(
base.add_pre_link_args(LinkerFlavor::Gcc, &["-Wl,--large-address-aware"]); 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 { Target {
llvm_target: "i686-pc-windows-gnu".into(), 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 { pub fn target() -> Target {
let mut base = super::windows_msvc_base::opts(); let mut base = super::windows_msvc_base::opts();
@ -6,7 +6,7 @@ pub fn target() -> Target {
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.add_pre_link_args( base.add_pre_link_args(
LinkerFlavor::Msvc, LinkerFlavor::Msvc(Lld::No),
&[ &[
// Mark all dynamic libraries and executables as compatible with the larger 4GiB address // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
// space available to x86 Windows binaries on x86_64. // 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 { pub fn target() -> Target {
let mut base = super::freebsd_base::opts(); let mut base = super::freebsd_base::opts();
base.cpu = "pentium4".into(); base.cpu = "pentium4".into();
base.max_atomic_width = Some(64); 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; base.stack_probes = StackProbeType::X86;
Target { 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 { pub fn target() -> Target {
let mut base = super::haiku_base::opts(); let mut base = super::haiku_base::opts();
base.cpu = "pentium4".into(); base.cpu = "pentium4".into();
base.max_atomic_width = Some(64); 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; base.stack_probes = StackProbeType::X86;
Target { 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 { pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts(); let mut base = super::linux_gnu_base::opts();
base.cpu = "pentium4".into(); base.cpu = "pentium4".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.supported_sanitizers = SanitizerSet::ADDRESS; 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; base.stack_probes = StackProbeType::X86;
Target { 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 { pub fn target() -> Target {
let mut base = super::linux_musl_base::opts(); let mut base = super::linux_musl_base::opts();
base.cpu = "pentium4".into(); base.cpu = "pentium4".into();
base.max_atomic_width = Some(64); 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; base.stack_probes = StackProbeType::X86;
// The unwinder used by i686-unknown-linux-musl, the LLVM libunwind // 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 { pub fn target() -> Target {
let mut base = super::netbsd_base::opts(); let mut base = super::netbsd_base::opts();
base.cpu = "pentium4".into(); base.cpu = "pentium4".into();
base.max_atomic_width = Some(64); 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; base.stack_probes = StackProbeType::X86;
Target { 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 { pub fn target() -> Target {
let mut base = super::openbsd_base::opts(); let mut base = super::openbsd_base::opts();
base.cpu = "pentium4".into(); base.cpu = "pentium4".into();
base.max_atomic_width = Some(64); 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; base.stack_probes = StackProbeType::X86;
Target { 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 { pub fn target() -> Target {
let mut base = super::windows_uwp_gnu_base::opts(); 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 // Mark all dynamic libraries and executables as compatible with the larger 4GiB address
// space available to x86 Windows binaries on x86_64. // 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(
base.add_pre_link_args(LinkerFlavor::Gcc, &["-Wl,--large-address-aware"]); 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 { Target {
llvm_target: "i686-pc-windows-gnu".into(), 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 { pub fn target() -> Target {
let mut base = super::vxworks_base::opts(); let mut base = super::vxworks_base::opts();
base.cpu = "pentium4".into(); base.cpu = "pentium4".into();
base.max_atomic_width = Some(64); 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; base.stack_probes = StackProbeType::X86;
Target { 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 { pub fn opts() -> TargetOptions {
let late_link_args = TargetOptions::link_args( let late_link_args = TargetOptions::link_args(
LinkerFlavor::Gcc, LinkerFlavor::Unix(Cc::Yes),
&[ &[
// The illumos libc contains a stack unwinding implementation, as // The illumos libc contains a stack unwinding implementation, as
// does libgcc_s. The latter implementation includes several // does libgcc_s. The latter implementation includes several
@ -30,7 +30,7 @@ pub fn opts() -> TargetOptions {
has_rpath: true, has_rpath: true,
families: cvs!["unix"], families: cvs!["unix"],
is_like_solaris: true, is_like_solaris: true,
linker_is_gnu: false, linker_flavor: LinkerFlavor::Unix(Cc::Yes),
limit_rdylib_exports: false, // Linker doesn't support this limit_rdylib_exports: false, // Linker doesn't support this
frame_pointer: FramePointer::Always, frame_pointer: FramePointer::Always,
eh_frame_header: false, 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 { pub fn opts() -> TargetOptions {
TargetOptions { TargetOptions {
os: "l4re".into(), os: "l4re".into(),
env: "uclibc".into(), env: "uclibc".into(),
linker_flavor: LinkerFlavor::Ld, linker_flavor: LinkerFlavor::Unix(Cc::No),
panic_strategy: PanicStrategy::Abort, panic_strategy: PanicStrategy::Abort,
linker: Some("l4-bender".into()), linker: Some("l4-bender".into()),
linker_is_gnu: false,
families: cvs!["unix"], families: cvs!["unix"],
relocation_model: RelocModel::Static, relocation_model: RelocModel::Static,
..Default::default() ..Default::default()

View file

@ -1,11 +1,13 @@
use crate::spec::{cvs, Target, TargetOptions}; use crate::spec::{cvs, Cc, LinkerFlavor, Lld, RelocModel, Target, TargetOptions};
use crate::spec::{LinkerFlavor, LldFlavor, RelocModel};
// The PSP has custom linker requirements. // The PSP has custom linker requirements.
const LINKER_SCRIPT: &str = include_str!("./mipsel_sony_psp_linker_script.ld"); const LINKER_SCRIPT: &str = include_str!("./mipsel_sony_psp_linker_script.ld");
pub fn target() -> Target { 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 { Target {
llvm_target: "mipsel-sony-psp".into(), llvm_target: "mipsel-sony-psp".into(),
@ -16,7 +18,7 @@ pub fn target() -> Target {
options: TargetOptions { options: TargetOptions {
os: "psp".into(), os: "psp".into(),
vendor: "sony".into(), vendor: "sony".into(),
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
cpu: "mips2".into(), cpu: "mips2".into(),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
relocation_model: RelocModel::Static, relocation_model: RelocModel::Static,

View file

@ -2,8 +2,7 @@
//! //!
//! Can be used for MIPS M4K core (e.g. on PIC32MX devices) //! Can be used for MIPS M4K core (e.g. on PIC32MX devices)
use crate::spec::{LinkerFlavor, LldFlavor, RelocModel}; use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
use crate::spec::{PanicStrategy, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
Target { Target {
@ -13,7 +12,7 @@ pub fn target() -> Target {
arch: "mips".into(), arch: "mips".into(),
options: TargetOptions { options: TargetOptions {
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
cpu: "mips32r2".into(), cpu: "mips32r2".into(),
features: "+mips32r2,+soft-float,+noabicalls".into(), features: "+mips32r2,+soft-float,+noabicalls".into(),
max_atomic_width: Some(32), max_atomic_width: Some(32),

View file

@ -90,17 +90,73 @@ mod windows_msvc_base;
mod windows_uwp_gnu_base; mod windows_uwp_gnu_base;
mod windows_uwp_msvc_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)] #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum LinkerFlavor { pub enum LinkerFlavor {
Gcc, /// Unix-like linker with GNU extensions (both naked and compiler-wrapped forms).
Ld, /// Besides similar "default" Linux/BSD linkers this also includes Windows/GNU linker,
Lld(LldFlavor), /// which is somewhat different because it doesn't produce ELFs.
Msvc, 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, EmCc,
// Below: other linker-like tools with unique interfaces for exotic targets.
/// Linker tool for BPF.
Bpf, Bpf,
/// Linker tool for Nvidia PTX.
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)] #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum LinkerFlavorCli { pub enum LinkerFlavorCli {
Gcc, Gcc,
@ -148,12 +204,32 @@ impl ToJson for LldFlavor {
} }
impl LinkerFlavor { 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 { match cli {
LinkerFlavorCli::Gcc => LinkerFlavor::Gcc, LinkerFlavorCli::Gcc => match lld_flavor {
LinkerFlavorCli::Ld => LinkerFlavor::Ld, LldFlavor::Ld if is_gnu => LinkerFlavor::Gnu(Cc::Yes, Lld::No),
LinkerFlavorCli::Lld(lld_flavor) => LinkerFlavor::Lld(lld_flavor), LldFlavor::Ld64 => LinkerFlavor::Darwin(Cc::Yes, Lld::No),
LinkerFlavorCli::Msvc => LinkerFlavor::Msvc, 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::Em => LinkerFlavor::EmCc,
LinkerFlavorCli::BpfLinker => LinkerFlavor::Bpf, LinkerFlavorCli::BpfLinker => LinkerFlavor::Bpf,
LinkerFlavorCli::PtxLinker => LinkerFlavor::Ptx, LinkerFlavorCli::PtxLinker => LinkerFlavor::Ptx,
@ -162,15 +238,40 @@ impl LinkerFlavor {
fn to_cli(self) -> LinkerFlavorCli { fn to_cli(self) -> LinkerFlavorCli {
match self { match self {
LinkerFlavor::Gcc => LinkerFlavorCli::Gcc, LinkerFlavor::Gnu(Cc::Yes, _)
LinkerFlavor::Ld => LinkerFlavorCli::Ld, | LinkerFlavor::Darwin(Cc::Yes, _)
LinkerFlavor::Lld(lld_flavor) => LinkerFlavorCli::Lld(lld_flavor), | LinkerFlavor::WasmLld(Cc::Yes)
LinkerFlavor::Msvc => LinkerFlavorCli::Msvc, | 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::EmCc => LinkerFlavorCli::Em,
LinkerFlavor::Bpf => LinkerFlavorCli::BpfLinker, LinkerFlavor::Bpf => LinkerFlavorCli::BpfLinker,
LinkerFlavor::Ptx => LinkerFlavorCli::PtxLinker, 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 { macro_rules! linker_flavor_cli_impls {
@ -1258,16 +1359,11 @@ pub struct TargetOptions {
/// Linker to invoke /// Linker to invoke
pub linker: Option<StaticCow<str>>, pub linker: Option<StaticCow<str>>,
/// Default linker flavor used if `-C linker-flavor` or `-C linker` are not passed /// 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, pub linker_flavor: LinkerFlavor,
linker_flavor_json: LinkerFlavorCli, linker_flavor_json: LinkerFlavorCli,
/// LLD flavor used if `lld` (or `rust-lld`) is specified as a linker lld_flavor_json: LldFlavor,
/// without clarifying its flavor in any way. linker_is_gnu_json: bool,
/// 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,
/// Objects to link before and after all other object code. /// Objects to link before and after all other object code.
pub pre_link_objects: CrtObjects, pub pre_link_objects: CrtObjects,
@ -1300,7 +1396,7 @@ pub struct TargetOptions {
/// Optional link script applied to `dylib` and `executable` crate types. /// Optional link script applied to `dylib` and `executable` crate types.
/// This is a string containing the script, not a path. Can only be applied /// 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>>, pub link_script: Option<StaticCow<str>>,
/// Environment variables to be set for the linker invocation. /// Environment variables to be set for the linker invocation.
pub link_env: StaticCow<[(StaticCow<str>, StaticCow<str>)]>, pub link_env: StaticCow<[(StaticCow<str>, StaticCow<str>)]>,
@ -1575,22 +1671,38 @@ pub struct TargetOptions {
/// Add arguments for the given flavor and also for its "twin" flavors /// Add arguments for the given flavor and also for its "twin" flavors
/// that have a compatible command line interface. /// that have a compatible command line interface.
fn add_link_args(link_args: &mut LinkArgs, flavor: LinkerFlavor, args: &[&'static str]) { fn add_link_args_iter(
let mut insert = |flavor| { link_args: &mut LinkArgs,
link_args.entry(flavor).or_default().extend(args.iter().copied().map(Cow::Borrowed)) flavor: LinkerFlavor,
}; args: impl Iterator<Item = StaticCow<str>> + Clone,
) {
let mut insert = |flavor| link_args.entry(flavor).or_default().extend(args.clone());
insert(flavor); insert(flavor);
match flavor { match flavor {
LinkerFlavor::Ld => insert(LinkerFlavor::Lld(LldFlavor::Ld)), LinkerFlavor::Gnu(cc, lld) => {
LinkerFlavor::Msvc => insert(LinkerFlavor::Lld(LldFlavor::Link)), assert_eq!(lld, Lld::No);
LinkerFlavor::Lld(LldFlavor::Ld64) | LinkerFlavor::Lld(LldFlavor::Wasm) => {} insert(LinkerFlavor::Gnu(cc, Lld::Yes));
LinkerFlavor::Lld(lld_flavor) => {
panic!("add_link_args: use non-LLD flavor for {:?}", lld_flavor)
} }
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 { impl TargetOptions {
fn link_args(flavor: LinkerFlavor, args: &[&'static str]) -> LinkArgs { fn link_args(flavor: LinkerFlavor, args: &[&'static str]) -> LinkArgs {
let mut link_args = LinkArgs::new(); let mut link_args = LinkArgs::new();
@ -1607,7 +1719,11 @@ impl TargetOptions {
} }
fn update_from_cli(&mut self) { 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 [ for (args, args_json) in [
(&mut self.pre_link_args, &self.pre_link_args_json), (&mut self.pre_link_args, &self.pre_link_args_json),
(&mut self.late_link_args, &self.late_link_args_json), (&mut self.late_link_args, &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.late_link_args_static, &self.late_link_args_static_json),
(&mut self.post_link_args, &self.post_link_args_json), (&mut self.post_link_args, &self.post_link_args_json),
] { ] {
*args = args_json args.clear();
.iter() for (flavor, args_json) in args_json {
.map(|(flavor, args)| (LinkerFlavor::from_cli(*flavor), args.clone())) // Cannot use `from_cli` due to borrow checker.
.collect(); 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) { fn update_to_cli(&mut self) {
self.linker_flavor_json = self.linker_flavor.to_cli(); 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 [ for (args, args_json) in [
(&self.pre_link_args, &mut self.pre_link_args_json), (&self.pre_link_args, &mut self.pre_link_args_json),
(&self.late_link_args, &mut self.late_link_args_json), (&self.late_link_args, &mut self.late_link_args_json),
@ -1650,10 +1779,10 @@ impl Default for TargetOptions {
abi: "".into(), abi: "".into(),
vendor: "unknown".into(), vendor: "unknown".into(),
linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.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, linker_flavor_json: LinkerFlavorCli::Gcc,
lld_flavor: LldFlavor::Ld, lld_flavor_json: LldFlavor::Ld,
linker_is_gnu: true, linker_is_gnu_json: true,
link_script: None, link_script: None,
asm_args: cvs![], asm_args: cvs![],
cpu: "generic".into(), cpu: "generic".into(),
@ -1922,6 +2051,12 @@ impl Target {
base.$key_name = s; 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) => ( { ($key_name:ident, u64) => ( {
let name = (stringify!($key_name)).replace("_", "-"); let name = (stringify!($key_name)).replace("_", "-");
if let Some(s) = obj.remove(&name).and_then(|j| Json::as_u64(&j)) { 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()); .map(|s| s.to_string().into());
} }
} ); } );
($key_name:ident, LldFlavor) => ( { ($key_name:ident = $json_name:expr, LldFlavor) => ( {
let name = (stringify!($key_name)).replace("_", "-"); let name = $json_name;
obj.remove(&name).and_then(|o| o.as_str().and_then(|s| { obj.remove(name).and_then(|o| o.as_str().and_then(|s| {
if let Some(flavor) = LldFlavor::from_str(&s) { if let Some(flavor) = LldFlavor::from_str(&s) {
base.$key_name = flavor; base.$key_name = flavor;
} else { } else {
@ -2289,8 +2424,8 @@ impl Target {
key!(vendor); key!(vendor);
key!(linker, optional); key!(linker, optional);
key!(linker_flavor_json = "linker-flavor", LinkerFlavor)?; key!(linker_flavor_json = "linker-flavor", LinkerFlavor)?;
key!(lld_flavor, LldFlavor)?; key!(lld_flavor_json = "lld-flavor", LldFlavor)?;
key!(linker_is_gnu, bool); key!(linker_is_gnu_json = "linker-is-gnu", bool);
key!(pre_link_objects = "pre-link-objects", link_objects); key!(pre_link_objects = "pre-link-objects", link_objects);
key!(post_link_objects = "post-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); 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!(vendor);
target_option_val!(linker); target_option_val!(linker);
target_option_val!(linker_flavor_json, "linker-flavor"); target_option_val!(linker_flavor_json, "linker-flavor");
target_option_val!(lld_flavor); target_option_val!(lld_flavor_json, "lld-flavor");
target_option_val!(linker_is_gnu); target_option_val!(linker_is_gnu_json, "linker-is-gnu");
target_option_val!(pre_link_objects); target_option_val!(pre_link_objects);
target_option_val!(post_link_objects); target_option_val!(post_link_objects);
target_option_val!(pre_link_objects_self_contained, "pre-link-objects-fallback"); 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 { pub fn target() -> Target {
Target { Target {
@ -16,7 +16,7 @@ pub fn target() -> Target {
// dependency on this specific gcc. // dependency on this specific gcc.
asm_args: cvs!["-mcpu=msp430"], asm_args: cvs!["-mcpu=msp430"],
linker: Some("msp430-elf-gcc".into()), 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 // There are no atomic CAS instructions available in the MSP430
// instruction set, and the LLVM backend doesn't currently support // 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; use std::borrow::Cow;
pub fn opts() -> TargetOptions { pub fn opts() -> TargetOptions {
// Suppress the verbose logo and authorship debugging output, which would needlessly // Suppress the verbose logo and authorship debugging output, which would needlessly
// clog any log files. // 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 { TargetOptions {
linker_flavor: LinkerFlavor::Msvc, linker_flavor: LinkerFlavor::Msvc(Lld::No),
is_like_windows: true, is_like_windows: true,
is_like_msvc: true, is_like_msvc: true,
lld_flavor: LldFlavor::Link,
linker_is_gnu: false,
pre_link_args, pre_link_args,
abi_return_struct_as_int: true, abi_return_struct_as_int: true,
emit_debug_gdb_scripts: false, emit_debug_gdb_scripts: false,

View file

@ -13,7 +13,6 @@ pub fn target() -> Target {
linker_flavor: LinkerFlavor::Ptx, linker_flavor: LinkerFlavor::Ptx,
// The linker can be installed from `crates.io`. // The linker can be installed from `crates.io`.
linker: Some("rust-ptx-linker".into()), linker: Some("rust-ptx-linker".into()),
linker_is_gnu: false,
// With `ptx-linker` approach, it can be later overridden via link flags. // With `ptx-linker` approach, it can be later overridden via link flags.
cpu: "sm_30".into(), cpu: "sm_30".into(),

View file

@ -1,10 +1,10 @@
use crate::abi::Endian; use crate::abi::Endian;
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::freebsd_base::opts(); let mut base = super::freebsd_base::opts();
base.cpu = "ppc64".into(); 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.max_atomic_width = Some(64);
base.stack_probes = StackProbeType::Inline; base.stack_probes = StackProbeType::Inline;

View file

@ -1,10 +1,10 @@
use crate::abi::Endian; use crate::abi::Endian;
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts(); let mut base = super::linux_gnu_base::opts();
base.cpu = "ppc64".into(); 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.max_atomic_width = Some(64);
base.stack_probes = StackProbeType::Inline; base.stack_probes = StackProbeType::Inline;

View file

@ -1,10 +1,10 @@
use crate::abi::Endian; use crate::abi::Endian;
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::linux_musl_base::opts(); let mut base = super::linux_musl_base::opts();
base.cpu = "ppc64".into(); 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.max_atomic_width = Some(64);
base.stack_probes = StackProbeType::Inline; base.stack_probes = StackProbeType::Inline;

View file

@ -1,10 +1,10 @@
use crate::abi::Endian; use crate::abi::Endian;
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::openbsd_base::opts(); let mut base = super::openbsd_base::opts();
base.cpu = "ppc64".into(); 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.max_atomic_width = Some(64);
base.stack_probes = StackProbeType::Inline; base.stack_probes = StackProbeType::Inline;

View file

@ -1,10 +1,10 @@
use crate::abi::Endian; use crate::abi::Endian;
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::vxworks_base::opts(); let mut base = super::vxworks_base::opts();
base.cpu = "ppc64".into(); 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.max_atomic_width = Some(64);
base.stack_probes = StackProbeType::Inline; 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 { pub fn target() -> Target {
let mut base = super::freebsd_base::opts(); let mut base = super::freebsd_base::opts();
base.cpu = "ppc64le".into(); 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.max_atomic_width = Some(64);
base.stack_probes = StackProbeType::Inline; 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 { pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts(); let mut base = super::linux_gnu_base::opts();
base.cpu = "ppc64le".into(); 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.max_atomic_width = Some(64);
base.stack_probes = StackProbeType::Inline; 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 { pub fn target() -> Target {
let mut base = super::linux_musl_base::opts(); let mut base = super::linux_musl_base::opts();
base.cpu = "ppc64le".into(); 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.max_atomic_width = Some(64);
base.stack_probes = StackProbeType::Inline; base.stack_probes = StackProbeType::Inline;

View file

@ -1,10 +1,13 @@
use crate::abi::Endian; use crate::abi::Endian;
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::freebsd_base::opts(); let mut base = super::freebsd_base::opts();
// Extra hint to linker that we are generating secure-PLT code. // 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.max_atomic_width = Some(32);
base.stack_probes = StackProbeType::Inline; base.stack_probes = StackProbeType::Inline;

View file

@ -1,9 +1,9 @@
use crate::abi::Endian; use crate::abi::Endian;
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts(); 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.max_atomic_width = Some(32);
base.stack_probes = StackProbeType::Inline; base.stack_probes = StackProbeType::Inline;

View file

@ -1,9 +1,9 @@
use crate::abi::Endian; use crate::abi::Endian;
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts(); 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.max_atomic_width = Some(32);
base.stack_probes = StackProbeType::Inline; base.stack_probes = StackProbeType::Inline;

View file

@ -1,9 +1,9 @@
use crate::abi::Endian; use crate::abi::Endian;
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::linux_musl_base::opts(); 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.max_atomic_width = Some(32);
base.stack_probes = StackProbeType::Inline; base.stack_probes = StackProbeType::Inline;

View file

@ -1,9 +1,9 @@
use crate::abi::Endian; use crate::abi::Endian;
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::netbsd_base::opts(); 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.max_atomic_width = Some(32);
base.stack_probes = StackProbeType::Inline; base.stack_probes = StackProbeType::Inline;

View file

@ -1,9 +1,9 @@
use crate::abi::Endian; use crate::abi::Endian;
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::vxworks_base::opts(); 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.max_atomic_width = Some(32);
base.stack_probes = StackProbeType::Inline; base.stack_probes = StackProbeType::Inline;

View file

@ -1,9 +1,9 @@
use crate::abi::Endian; use crate::abi::Endian;
use crate::spec::{LinkerFlavor, StackProbeType, Target, TargetOptions}; use crate::spec::{Cc, LinkerFlavor, Lld, StackProbeType, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::vxworks_base::opts(); 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.max_atomic_width = Some(32);
base.stack_probes = StackProbeType::Inline; base.stack_probes = StackProbeType::Inline;

View file

@ -1,5 +1,4 @@
use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
Target { Target {
@ -9,7 +8,7 @@ pub fn target() -> Target {
arch: "riscv32".into(), arch: "riscv32".into(),
options: TargetOptions { options: TargetOptions {
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
cpu: "generic-rv32".into(), cpu: "generic-rv32".into(),
max_atomic_width: Some(0), max_atomic_width: Some(0),

View file

@ -1,5 +1,4 @@
use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
Target { Target {
@ -9,7 +8,7 @@ pub fn target() -> Target {
arch: "riscv32".into(), arch: "riscv32".into(),
options: TargetOptions { options: TargetOptions {
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
cpu: "generic-rv32".into(), cpu: "generic-rv32".into(),
max_atomic_width: Some(0), max_atomic_width: Some(0),

View file

@ -1,5 +1,4 @@
use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
Target { Target {
@ -9,7 +8,7 @@ pub fn target() -> Target {
arch: "riscv32".into(), arch: "riscv32".into(),
options: TargetOptions { options: TargetOptions {
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
cpu: "generic-rv32".into(), cpu: "generic-rv32".into(),
max_atomic_width: Some(32), max_atomic_width: Some(32),

View file

@ -1,5 +1,4 @@
use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
Target { Target {
@ -10,7 +9,7 @@ pub fn target() -> Target {
options: TargetOptions { options: TargetOptions {
os: "xous".into(), os: "xous".into(),
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
cpu: "generic-rv32".into(), cpu: "generic-rv32".into(),
max_atomic_width: Some(32), max_atomic_width: Some(32),

View file

@ -1,5 +1,4 @@
use crate::spec::{cvs, Target, TargetOptions}; use crate::spec::{cvs, PanicStrategy, RelocModel, Target, TargetOptions};
use crate::spec::{LinkerFlavor, PanicStrategy, RelocModel};
pub fn target() -> Target { pub fn target() -> Target {
Target { Target {
@ -13,7 +12,6 @@ pub fn target() -> Target {
os: "espidf".into(), os: "espidf".into(),
env: "newlib".into(), env: "newlib".into(),
vendor: "espressif".into(), vendor: "espressif".into(),
linker_flavor: LinkerFlavor::Gcc,
linker: Some("riscv32-esp-elf-gcc".into()), linker: Some("riscv32-esp-elf-gcc".into()),
cpu: "generic-rv32".into(), cpu: "generic-rv32".into(),

View file

@ -1,5 +1,4 @@
use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
use crate::spec::{Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
Target { Target {
@ -9,7 +8,7 @@ pub fn target() -> Target {
arch: "riscv32".into(), arch: "riscv32".into(),
options: TargetOptions { options: TargetOptions {
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
cpu: "generic-rv32".into(), cpu: "generic-rv32".into(),
max_atomic_width: Some(0), max_atomic_width: Some(0),

View file

@ -1,5 +1,5 @@
use crate::spec::{CodeModel, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; use crate::spec::{Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy};
use crate::spec::{Target, TargetOptions}; use crate::spec::{RelocModel, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
Target { Target {
@ -9,7 +9,7 @@ pub fn target() -> Target {
arch: "riscv64".into(), arch: "riscv64".into(),
options: TargetOptions { options: TargetOptions {
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
llvm_abiname: "lp64d".into(), llvm_abiname: "lp64d".into(),
cpu: "generic-rv64".into(), cpu: "generic-rv64".into(),

View file

@ -1,5 +1,5 @@
use crate::spec::{CodeModel, Target, TargetOptions}; use crate::spec::{Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy};
use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy, RelocModel}; use crate::spec::{RelocModel, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
Target { Target {
@ -9,7 +9,7 @@ pub fn target() -> Target {
arch: "riscv64".into(), arch: "riscv64".into(),
options: TargetOptions { options: TargetOptions {
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
cpu: "generic-rv64".into(), cpu: "generic-rv64".into(),
max_atomic_width: Some(64), 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 { pub fn opts() -> TargetOptions {
TargetOptions { TargetOptions {
@ -7,7 +7,7 @@ pub fn opts() -> TargetOptions {
has_rpath: true, has_rpath: true,
families: cvs!["unix"], families: cvs!["unix"],
is_like_solaris: true, is_like_solaris: true,
linker_is_gnu: false, linker_flavor: LinkerFlavor::Unix(Cc::Yes),
limit_rdylib_exports: false, // Linker doesn't support this limit_rdylib_exports: false, // Linker doesn't support this
eh_frame_header: false, eh_frame_header: false,

View file

@ -1,10 +1,10 @@
use crate::abi::Endian; use crate::abi::Endian;
use crate::spec::{LinkerFlavor, Target, TargetOptions}; use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::netbsd_base::opts(); let mut base = super::netbsd_base::opts();
base.cpu = "v9".into(); 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); base.max_atomic_width = Some(64);
Target { Target {

View file

@ -1,11 +1,11 @@
use crate::abi::Endian; use crate::abi::Endian;
use crate::spec::{LinkerFlavor, Target}; use crate::spec::{Cc, LinkerFlavor, Lld, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::openbsd_base::opts(); let mut base = super::openbsd_base::opts();
base.endian = Endian::Big; base.endian = Endian::Big;
base.cpu = "v9".into(); 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); base.max_atomic_width = Some(64);
Target { Target {

View file

@ -1,12 +1,12 @@
use crate::abi::Endian; use crate::abi::Endian;
use crate::spec::{LinkerFlavor, Target}; use crate::spec::{Cc, LinkerFlavor, Lld, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts(); let mut base = super::linux_gnu_base::opts();
base.endian = Endian::Big; base.endian = Endian::Big;
base.cpu = "v9".into(); base.cpu = "v9".into();
base.max_atomic_width = Some(64); 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 { Target {
llvm_target: "sparc-unknown-linux-gnu".into(), llvm_target: "sparc-unknown-linux-gnu".into(),

View file

@ -1,10 +1,10 @@
use crate::abi::Endian; use crate::abi::Endian;
use crate::spec::{LinkerFlavor, Target}; use crate::spec::{Cc, LinkerFlavor, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::solaris_base::opts(); let mut base = super::solaris_base::opts();
base.endian = Endian::Big; 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" // llvm calls this "v9"
base.cpu = "v9".into(); base.cpu = "v9".into();
base.vendor = "sun".into(); base.vendor = "sun".into();

View file

@ -19,11 +19,13 @@ impl Target {
assert!(self.is_like_windows); assert!(self.is_like_windows);
} }
// Check that default linker flavor and lld flavor are compatible // Check that default linker flavor is compatible with some other key properties.
// with some other key properties. assert_eq!(self.is_like_osx, matches!(self.linker_flavor, LinkerFlavor::Darwin(..)));
assert_eq!(self.is_like_osx, matches!(self.lld_flavor, LldFlavor::Ld64)); assert_eq!(self.is_like_msvc, matches!(self.linker_flavor, LinkerFlavor::Msvc(..)));
assert_eq!(self.is_like_msvc, matches!(self.lld_flavor, LldFlavor::Link)); assert_eq!(
assert_eq!(self.is_like_wasm, matches!(self.lld_flavor, LldFlavor::Wasm)); 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.os == "emscripten", matches!(self.linker_flavor, LinkerFlavor::EmCc));
assert_eq!(self.arch == "bpf", matches!(self.linker_flavor, LinkerFlavor::Bpf)); assert_eq!(self.arch == "bpf", matches!(self.linker_flavor, LinkerFlavor::Bpf));
assert_eq!(self.arch == "nvptx64", matches!(self.linker_flavor, LinkerFlavor::Ptx)); assert_eq!(self.arch == "nvptx64", matches!(self.linker_flavor, LinkerFlavor::Ptx));
@ -38,44 +40,25 @@ impl Target {
for (&flavor, flavor_args) in args { for (&flavor, flavor_args) in args {
assert!(!flavor_args.is_empty()); assert!(!flavor_args.is_empty());
// Check that flavors mentioned in link args are compatible with the default flavor. // Check that flavors mentioned in link args are compatible with the default flavor.
match (self.linker_flavor, self.lld_flavor) { match self.linker_flavor {
( LinkerFlavor::Gnu(..) => {
LinkerFlavor::Ld | LinkerFlavor::Lld(LldFlavor::Ld) | LinkerFlavor::Gcc, assert_matches!(flavor, LinkerFlavor::Gnu(..));
LldFlavor::Ld,
) => {
assert_matches!(
flavor,
LinkerFlavor::Ld | LinkerFlavor::Lld(LldFlavor::Ld) | LinkerFlavor::Gcc
)
} }
(LinkerFlavor::Gcc, LldFlavor::Ld64) => { LinkerFlavor::Darwin(..) => {
assert_matches!( assert_matches!(flavor, LinkerFlavor::Darwin(..))
flavor,
LinkerFlavor::Lld(LldFlavor::Ld64) | LinkerFlavor::Gcc
)
} }
(LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link), LldFlavor::Link) => { LinkerFlavor::WasmLld(..) => {
assert_matches!( assert_matches!(flavor, LinkerFlavor::WasmLld(..))
flavor,
LinkerFlavor::Msvc | LinkerFlavor::Lld(LldFlavor::Link)
)
} }
(LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc, LldFlavor::Wasm) => { LinkerFlavor::Unix(..) => {
assert_matches!( assert_matches!(flavor, LinkerFlavor::Unix(..));
flavor,
LinkerFlavor::Lld(LldFlavor::Wasm) | LinkerFlavor::Gcc
)
} }
(LinkerFlavor::EmCc, LldFlavor::Wasm) => { LinkerFlavor::Msvc(..) => {
assert_matches!(flavor, LinkerFlavor::EmCc) assert_matches!(flavor, LinkerFlavor::Msvc(..))
} }
(LinkerFlavor::Bpf, LldFlavor::Ld) => { LinkerFlavor::EmCc | LinkerFlavor::Bpf | LinkerFlavor::Ptx => {
assert_matches!(flavor, LinkerFlavor::Bpf) 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. // Check that link args for cc and non-cc versions of flavors are consistent.
@ -88,25 +71,29 @@ impl Target {
} }
} }
}; };
match self.linker_flavor { match self.linker_flavor {
LinkerFlavor::Gcc => match self.lld_flavor { LinkerFlavor::Gnu(Cc::Yes, lld) => check_noncc(LinkerFlavor::Gnu(Cc::No, lld)),
LldFlavor::Ld => { LinkerFlavor::WasmLld(Cc::Yes) => check_noncc(LinkerFlavor::WasmLld(Cc::No)),
check_noncc(LinkerFlavor::Ld); LinkerFlavor::Unix(Cc::Yes) => check_noncc(LinkerFlavor::Unix(Cc::No)),
check_noncc(LinkerFlavor::Lld(LldFlavor::Ld));
}
LldFlavor::Ld64 => check_noncc(LinkerFlavor::Lld(LldFlavor::Ld64)),
LldFlavor::Wasm => check_noncc(LinkerFlavor::Lld(LldFlavor::Wasm)),
LldFlavor::Link => {}
},
_ => {} _ => {}
} }
} }
// Check that link args for lld and non-lld versions of flavors are consistent. // Check that link args for lld and non-lld versions of flavors are consistent.
assert_eq!(args.get(&LinkerFlavor::Ld), args.get(&LinkerFlavor::Lld(LldFlavor::Ld))); for cc in [Cc::No, Cc::Yes] {
assert_eq!(
args.get(&LinkerFlavor::Gnu(cc, Lld::No)),
args.get(&LinkerFlavor::Gnu(cc, Lld::Yes)),
);
assert_eq!(
args.get(&LinkerFlavor::Darwin(cc, Lld::No)),
args.get(&LinkerFlavor::Darwin(cc, Lld::Yes)),
);
}
assert_eq!( assert_eq!(
args.get(&LinkerFlavor::Msvc), args.get(&LinkerFlavor::Msvc(Lld::No)),
args.get(&LinkerFlavor::Lld(LldFlavor::Link)), 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 // differentiate these targets from our other `arm(v7)-*-*-gnueabi(hf)` targets in the context of
// build scripts / gcc flags. // build scripts / gcc flags.
use crate::spec::TargetOptions; use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, PanicStrategy, RelocModel, TargetOptions};
use crate::spec::{FramePointer, LinkerFlavor, LldFlavor, PanicStrategy, RelocModel};
pub fn opts() -> TargetOptions { pub fn opts() -> TargetOptions {
// See rust-lang/rfcs#1645 for a discussion about these defaults // See rust-lang/rfcs#1645 for a discussion about these defaults
TargetOptions { TargetOptions {
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
// In most cases, LLD is good enough // In most cases, LLD is good enough
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
// Because these devices have very little resources having an unwinder is too onerous so we // 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 //! 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. //! `-Clink-arg=-Tmy_script.ld` to override that with a correct linker script.
use crate::spec::{ use crate::spec::{cvs, Cc, FramePointer, LinkerFlavor, Lld};
cvs, FramePointer, LinkerFlavor, PanicStrategy, RelocModel, Target, TargetOptions, use crate::spec::{PanicStrategy, RelocModel, Target, TargetOptions};
};
pub fn target() -> Target { pub fn target() -> 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(), data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(),
options: TargetOptions { options: TargetOptions {
abi: "eabi".into(), abi: "eabi".into(),
linker_flavor: LinkerFlavor::Ld, linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::No),
linker: Some("arm-none-eabi-ld".into()), linker: Some("arm-none-eabi-ld".into()),
// extra args passed to the external assembler (assuming `arm-none-eabi-as`): // 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 { pub fn target() -> Target {
let mut base = super::windows_msvc_base::opts(); 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 // should be smart enough to insert branch islands only
// where necessary, but this is not the observed behavior. // where necessary, but this is not the observed behavior.
// Disabling the LBR optimization works around the issue. // 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 { Target {
llvm_target: "thumbv7a-pc-windows-msvc".into(), 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 // This target if is for the Android v7a ABI in thumb mode with
// NEON unconditionally enabled and, therefore, with 32 FPU registers // NEON unconditionally enabled and, therefore, with 32 FPU registers
@ -10,7 +10,7 @@ use crate::spec::{LinkerFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::android_base::opts(); 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 { Target {
llvm_target: "armv7-none-linux-android".into(), llvm_target: "armv7-none-linux-android".into(),
pointer_width: 32, pointer_width: 32,

View file

@ -9,14 +9,13 @@
// the timer-interrupt. Device-drivers are required to use polling-based models. Furthermore, all // 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. // code runs in the same environment, no process separation is supported.
use crate::spec::{LinkerFlavor, LldFlavor, PanicStrategy}; use crate::spec::{LinkerFlavor, Lld, PanicStrategy, StackProbeType, TargetOptions};
use crate::spec::{StackProbeType, TargetOptions};
pub fn opts() -> TargetOptions { pub fn opts() -> TargetOptions {
let mut base = super::msvc_base::opts(); let mut base = super::msvc_base::opts();
base.add_pre_link_args( 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 // 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 // one. "efi_main" seems to be a common choice amongst other implementations and the
@ -37,7 +36,7 @@ pub fn opts() -> TargetOptions {
TargetOptions { TargetOptions {
os: "uefi".into(), os: "uefi".into(),
linker_flavor: LinkerFlavor::Lld(LldFlavor::Link), linker_flavor: LinkerFlavor::Msvc(Lld::Yes),
disable_redzone: true, disable_redzone: true,
exe_suffix: ".efi".into(), exe_suffix: ".efi".into(),
allows_weak_linkage: false, allows_weak_linkage: false,

View file

@ -10,14 +10,12 @@
//! This target is more or less managed by the Rust and WebAssembly Working //! This target is more or less managed by the Rust and WebAssembly Working
//! Group nowadays at <https://github.com/rustwasm>. //! Group nowadays at <https://github.com/rustwasm>.
use super::wasm_base; use super::{wasm_base, Cc, LinkerFlavor, Target};
use super::{LinkerFlavor, LldFlavor, Target};
use crate::spec::abi::Abi; use crate::spec::abi::Abi;
pub fn target() -> Target { pub fn target() -> Target {
let mut options = wasm_base::options(); let mut options = wasm_base::options();
options.os = "unknown".into(); options.os = "unknown".into();
options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm);
// This is a default for backwards-compatibility with the original // This is a default for backwards-compatibility with the original
// definition of this target oh-so-long-ago. Once the "wasm" ABI is // 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.default_adjusted_cabi = Some(Abi::Wasm);
options.add_pre_link_args( 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 // For now this target just never has an entry symbol no matter the output
// type, so unconditionally pass this. // type, so unconditionally pass this.
@ -44,7 +42,7 @@ pub fn target() -> Target {
], ],
); );
options.add_pre_link_args( options.add_pre_link_args(
LinkerFlavor::Gcc, LinkerFlavor::WasmLld(Cc::Yes),
&[ &[
// Make sure clang uses LLD as its linker and is configured appropriately // Make sure clang uses LLD as its linker and is configured appropriately
// otherwise // otherwise

View file

@ -72,15 +72,13 @@
//! best we can with this target. Don't start relying on too much here unless //! best we can with this target. Don't start relying on too much here unless
//! you know what you're getting in to! //! you know what you're getting in to!
use super::wasm_base; use super::{crt_objects, wasm_base, Cc, LinkerFlavor, Target};
use super::{crt_objects, LinkerFlavor, LldFlavor, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut options = wasm_base::options(); let mut options = wasm_base::options();
options.os = "wasi".into(); options.os = "wasi".into();
options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm); options.add_pre_link_args(LinkerFlavor::WasmLld(Cc::Yes), &["--target=wasm32-wasi"]);
options.add_pre_link_args(LinkerFlavor::Gcc, &["--target=wasm32-wasi"]);
options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained(); options.pre_link_objects_self_contained = crt_objects::pre_wasi_self_contained();
options.post_link_objects_self_contained = crt_objects::post_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 //! the standard library is available, most of it returns an error immediately
//! (e.g. trying to create a TCP stream or something like that). //! (e.g. trying to create a TCP stream or something like that).
use super::wasm_base; use super::{wasm_base, Cc, LinkerFlavor, Target};
use super::{LinkerFlavor, LldFlavor, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut options = wasm_base::options(); let mut options = wasm_base::options();
options.os = "unknown".into(); options.os = "unknown".into();
options.linker_flavor = LinkerFlavor::Lld(LldFlavor::Wasm);
options.add_pre_link_args( 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 // For now this target just never has an entry symbol no matter the output
// type, so unconditionally pass this. // type, so unconditionally pass this.
@ -25,7 +23,7 @@ pub fn target() -> Target {
], ],
); );
options.add_pre_link_args( options.add_pre_link_args(
LinkerFlavor::Gcc, LinkerFlavor::WasmLld(Cc::Yes),
&[ &[
// Make sure clang uses LLD as its linker and is configured appropriately // Make sure clang uses LLD as its linker and is configured appropriately
// otherwise // otherwise

View file

@ -1,5 +1,5 @@
use super::crt_objects::LinkSelfContainedDefault; 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 { pub fn options() -> TargetOptions {
macro_rules! args { macro_rules! args {
@ -49,8 +49,8 @@ pub fn options() -> TargetOptions {
}; };
} }
let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::Lld(LldFlavor::Wasm), args!("")); let mut pre_link_args = TargetOptions::link_args(LinkerFlavor::WasmLld(Cc::No), args!(""));
super::add_link_args(&mut pre_link_args, LinkerFlavor::Gcc, args!("-Wl,")); super::add_link_args(&mut pre_link_args, LinkerFlavor::WasmLld(Cc::Yes), args!("-Wl,"));
TargetOptions { TargetOptions {
is_like_wasm: true, is_like_wasm: true,
@ -91,8 +91,7 @@ pub fn options() -> TargetOptions {
// we use the LLD shipped with the Rust toolchain by default // we use the LLD shipped with the Rust toolchain by default
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
lld_flavor: LldFlavor::Wasm, linker_flavor: LinkerFlavor::WasmLld(Cc::No),
linker_is_gnu: false,
pre_link_args, pre_link_args,

View file

@ -1,10 +1,10 @@
use crate::spec::crt_objects::{self, LinkSelfContainedDefault}; 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; use std::borrow::Cow;
pub fn opts() -> TargetOptions { pub fn opts() -> TargetOptions {
let mut pre_link_args = TargetOptions::link_args( let mut pre_link_args = TargetOptions::link_args(
LinkerFlavor::Ld, LinkerFlavor::Gnu(Cc::No, Lld::No),
&[ &[
// Enable ASLR // Enable ASLR
"--dynamicbase", "--dynamicbase",
@ -14,7 +14,7 @@ pub fn opts() -> TargetOptions {
); );
super::add_link_args( super::add_link_args(
&mut pre_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 // Tell GCC to avoid linker plugins, because we are not bundling
// them with Windows installer, and Rust does its own LTO anyways. // them with Windows installer, and Rust does its own LTO anyways.
@ -42,23 +42,33 @@ pub fn opts() -> TargetOptions {
"-luser32", "-luser32",
"-lkernel32", "-lkernel32",
]; ];
let mut late_link_args = TargetOptions::link_args(LinkerFlavor::Ld, mingw_libs); let mut late_link_args =
super::add_link_args(&mut late_link_args, LinkerFlavor::Gcc, mingw_libs); 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 // 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 // the shared libgcc_s-dw2-1.dll. This is required to support
// unwinding across DLL boundaries. // unwinding across DLL boundaries.
let dynamic_unwind_libs = &["-lgcc_s"]; let dynamic_unwind_libs = &["-lgcc_s"];
let mut late_link_args_dynamic = let mut late_link_args_dynamic =
TargetOptions::link_args(LinkerFlavor::Ld, 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::Gcc, 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 // If all of our crates are statically linked then we can get away
// with statically linking the libgcc unwinding code. This allows // with statically linking the libgcc unwinding code. This allows
// binaries to be redistributed without the libgcc_s-dw2-1.dll // binaries to be redistributed without the libgcc_s-dw2-1.dll
// dependency, but unfortunately break unwinding across DLL // dependency, but unfortunately break unwinding across DLL
// boundaries when unwinding across FFI boundaries. // boundaries when unwinding across FFI boundaries.
let static_unwind_libs = &["-lgcc_eh", "-l:libpthread.a"]; let static_unwind_libs = &["-lgcc_eh", "-l:libpthread.a"];
let mut late_link_args_static = TargetOptions::link_args(LinkerFlavor::Ld, static_unwind_libs); let mut late_link_args_static =
super::add_link_args(&mut late_link_args_static, LinkerFlavor::Gcc, static_unwind_libs); 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 { TargetOptions {
os: "windows".into(), 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 { pub fn opts() -> TargetOptions {
// We cannot use `-nodefaultlibs` because compiler-rt has to be passed // 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. // 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>) // 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 // but LLVM maintainers rejected it: https://reviews.llvm.org/D51440
let pre_link_args = let pre_link_args = TargetOptions::link_args(
TargetOptions::link_args(LinkerFlavor::Gcc, &["-nolibc", "--unwindlib=none"]); LinkerFlavor::Gnu(Cc::Yes, Lld::No),
&["-nolibc", "--unwindlib=none"],
);
// Order of `late_link_args*` does not matter with LLD. // Order of `late_link_args*` does not matter with LLD.
let late_link_args = TargetOptions::link_args( let late_link_args = TargetOptions::link_args(
LinkerFlavor::Gcc, LinkerFlavor::Gnu(Cc::Yes, Lld::No),
&["-lmingw32", "-lmingwex", "-lmsvcrt", "-lkernel32", "-luser32"], &["-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 { pub fn opts() -> TargetOptions {
let base = super::windows_gnu_base::opts(); let base = super::windows_gnu_base::opts();
@ -15,8 +15,9 @@ pub fn opts() -> TargetOptions {
"-lmingwex", "-lmingwex",
"-lmingw32", "-lmingw32",
]; ];
let mut late_link_args = TargetOptions::link_args(LinkerFlavor::Ld, mingw_libs); let mut late_link_args =
super::add_link_args(&mut late_link_args, LinkerFlavor::Gcc, mingw_libs); 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. // Reset the flags back to empty until the FIXME above is addressed.
let late_link_args_dynamic = LinkArgs::new(); let late_link_args_dynamic = LinkArgs::new();
let late_link_args_static = 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 { pub fn opts() -> TargetOptions {
let mut opts = super::windows_msvc_base::opts(); let mut opts = super::windows_msvc_base::opts();
opts.abi = "uwp".into(); opts.abi = "uwp".into();
opts.vendor = "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 opts
} }

View file

@ -1,5 +1,5 @@
use crate::spec::TargetOptions; use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet};
use crate::spec::{FramePointer, LinkerFlavor, SanitizerSet, StackProbeType, Target}; use crate::spec::{StackProbeType, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let arch = "x86_64"; let arch = "x86_64";
@ -7,7 +7,7 @@ pub fn target() -> Target {
base.cpu = "core2".into(); base.cpu = "core2".into();
base.max_atomic_width = Some(128); // core2 support cmpxchg16b base.max_atomic_width = Some(128); // core2 support cmpxchg16b
base.frame_pointer = FramePointer::Always; 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.link_env_remove.to_mut().extend(super::apple_base::macos_link_env_remove());
base.stack_probes = StackProbeType::X86; base.stack_probes = StackProbeType::X86;
base.supported_sanitizers = base.supported_sanitizers =

View file

@ -1,11 +1,11 @@
use super::apple_sdk_base::{opts, Arch}; 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 { pub fn target() -> Target {
let llvm_target = "x86_64-apple-ios13.0-macabi"; let llvm_target = "x86_64-apple-ios13.0-macabi";
let mut base = opts("ios", Arch::X86_64_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 { Target {
llvm_target: llvm_target.into(), llvm_target: llvm_target.into(),

View file

@ -1,12 +1,10 @@
use std::borrow::Cow; use std::borrow::Cow;
use crate::spec::cvs; use super::{cvs, Cc, LinkerFlavor, Lld, Target, TargetOptions};
use super::{LinkerFlavor, LldFlavor, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
let pre_link_args = TargetOptions::link_args( let pre_link_args = TargetOptions::link_args(
LinkerFlavor::Ld, LinkerFlavor::Gnu(Cc::No, Lld::No),
&[ &[
"-e", "-e",
"elf_entry", "elf_entry",
@ -61,7 +59,7 @@ pub fn target() -> Target {
env: "sgx".into(), env: "sgx".into(),
vendor: "fortanix".into(), vendor: "fortanix".into(),
abi: "fortanix".into(), abi: "fortanix".into(),
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
max_atomic_width: Some(64), max_atomic_width: Some(64),
cpu: "x86-64".into(), 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 { pub fn target() -> Target {
let mut base = super::android_base::opts(); 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 // https://developer.android.com/ndk/guides/abis.html#86-64
base.features = "+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt".into(); base.features = "+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+popcnt".into();
base.max_atomic_width = Some(64); 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.stack_probes = StackProbeType::X86;
Target { 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 { pub fn target() -> Target {
let mut base = super::solaris_base::opts(); 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.cpu = "x86-64".into();
base.vendor = "pc".into(); base.vendor = "pc".into();
base.max_atomic_width = Some(64); 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 { pub fn target() -> Target {
let mut base = super::windows_gnu_base::opts(); let mut base = super::windows_gnu_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
// Use high-entropy 64 bit address space for ASLR // 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(
base.add_pre_link_args(LinkerFlavor::Gcc, &["-m64", "-Wl,--high-entropy-va"]); 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.max_atomic_width = Some(64);
base.linker = Some("x86_64-w64-mingw32-gcc".into()); 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 { pub fn target() -> Target {
let mut base = super::windows_gnullvm_base::opts(); let mut base = super::windows_gnullvm_base::opts();
base.cpu = "x86-64".into(); 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.max_atomic_width = Some(64);
base.linker = Some("x86_64-w64-mingw32-clang".into()); 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 { pub fn target() -> Target {
let mut base = super::solaris_base::opts(); 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.cpu = "x86-64".into();
base.vendor = "sun".into(); base.vendor = "sun".into();
base.max_atomic_width = Some(64); 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 { pub fn target() -> Target {
let mut base = super::dragonfly_base::opts(); let mut base = super::dragonfly_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.max_atomic_width = Some(64); 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.stack_probes = StackProbeType::X86;
Target { 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 { pub fn target() -> Target {
let mut base = super::freebsd_base::opts(); let mut base = super::freebsd_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.max_atomic_width = Some(64); 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.stack_probes = StackProbeType::X86;
base.supported_sanitizers = base.supported_sanitizers =
SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::MEMORY | SanitizerSet::THREAD; 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 { pub fn target() -> Target {
let mut base = super::haiku_base::opts(); let mut base = super::haiku_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.max_atomic_width = Some(64); 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.stack_probes = StackProbeType::X86;
// This option is required to build executables on Haiku x86_64 // This option is required to build executables on Haiku x86_64
base.position_independent_executables = true; 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 { pub fn target() -> Target {
let mut base = super::illumos_base::opts(); 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.cpu = "x86-64".into();
base.max_atomic_width = Some(64); base.max_atomic_width = Some(64);
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI; 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 { pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts(); let mut base = super::linux_gnu_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.max_atomic_width = Some(64); 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.stack_probes = StackProbeType::X86;
base.static_position_independent_executables = true; base.static_position_independent_executables = true;
base.supported_sanitizers = SanitizerSet::ADDRESS 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 { pub fn target() -> Target {
let mut base = super::linux_gnu_base::opts(); let mut base = super::linux_gnu_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.abi = "x32".into(); base.abi = "x32".into();
base.max_atomic_width = Some(64); 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.stack_probes = StackProbeType::X86;
base.has_thread_local = false; base.has_thread_local = false;
// BUG(GabrielMajeri): disabling the PLT on x86_64 Linux with x32 ABI // 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 { pub fn target() -> Target {
let mut base = super::linux_musl_base::opts(); let mut base = super::linux_musl_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.max_atomic_width = Some(64); 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.stack_probes = StackProbeType::X86;
base.static_position_independent_executables = true; base.static_position_independent_executables = true;
base.supported_sanitizers = SanitizerSet::ADDRESS 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 { pub fn target() -> Target {
let mut base = super::netbsd_base::opts(); let mut base = super::netbsd_base::opts();
base.cpu = "x86-64".into(); base.cpu = "x86-64".into();
base.max_atomic_width = Some(64); 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.stack_probes = StackProbeType::X86;
base.supported_sanitizers = SanitizerSet::ADDRESS base.supported_sanitizers = SanitizerSet::ADDRESS
| SanitizerSet::CFI | SanitizerSet::CFI

View file

@ -4,7 +4,7 @@
// `target-cpu` compiler flags to opt-in more hardware-specific // `target-cpu` compiler flags to opt-in more hardware-specific
// features. // features.
use super::{CodeModel, LinkerFlavor, LldFlavor, PanicStrategy}; use super::{Cc, CodeModel, LinkerFlavor, Lld, PanicStrategy};
use super::{RelroLevel, StackProbeType, Target, TargetOptions}; use super::{RelroLevel, StackProbeType, Target, TargetOptions};
pub fn target() -> Target { pub fn target() -> Target {
@ -15,7 +15,7 @@ pub fn target() -> Target {
position_independent_executables: true, position_independent_executables: true,
static_position_independent_executables: true, static_position_independent_executables: true,
relro_level: RelroLevel::Full, relro_level: RelroLevel::Full,
linker_flavor: LinkerFlavor::Lld(LldFlavor::Ld), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
linker: Some("rust-lld".into()), linker: Some("rust-lld".into()),
features: features:
"-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float" "-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 // This defines the amd64 target for the Linux Kernel. See the linux-kernel-base module for
// generic Linux kernel options. // generic Linux kernel options.
use crate::spec::{CodeModel, LinkerFlavor, Target}; use crate::spec::{Cc, CodeModel, LinkerFlavor, Lld, Target};
pub fn target() -> Target { pub fn target() -> Target {
let mut base = super::linux_kernel_base::opts(); let mut base = super::linux_kernel_base::opts();
@ -10,7 +10,7 @@ pub fn target() -> Target {
base.features = base.features =
"-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float".into(); "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float".into();
base.code_model = Some(CodeModel::Kernel); 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 { Target {
// FIXME: Some dispute, the linux-on-clang folks think this should use // 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