diff options
| author | Jorge Aparicio <japaricious@gmail.com> | 2017-02-21 14:47:15 -0500 |
|---|---|---|
| committer | Jorge Aparicio <japaricious@gmail.com> | 2017-04-07 10:52:42 -0500 |
| commit | 9d11b089ad136432dff6c49c6eb3c48c7f6e5273 (patch) | |
| tree | 089d832161196cfcaa2cc681dcad636e37fb8407 /src/librustc_back/target | |
| parent | c438c1fb39337b7712afc58df4f1f9c5112e5cc1 (diff) | |
| download | rust-9d11b089ad136432dff6c49c6eb3c48c7f6e5273.tar.gz rust-9d11b089ad136432dff6c49c6eb3c48c7f6e5273.zip | |
-Z linker-flavor
This patch adds a `-Z linker-flavor` flag to rustc which can be used to invoke
the linker using a different interface.
For example, by default rustc assumes that all the Linux targets will be linked
using GCC. This makes it impossible to use LLD as a linker using just `-C
linker=ld.lld` because that will invoke LLD with invalid command line
arguments. (e.g. rustc will pass -Wl,--gc-sections to LLD but LLD doesn't
understand that; --gc-sections would be the right argument)
With this patch one can pass `-Z linker-flavor=ld` to rustc to invoke the linker
using a LD-like interface. This way, `rustc -C linker=ld.lld -Z
linker-flavor=ld` will invoke LLD with the right arguments.
`-Z linker-flavor` accepts 4 different arguments: `em` (emcc), `ld`,
`gcc`, `msvc` (link.exe). `em`, `gnu` and `msvc` cover all the existing linker
interfaces. `ld` is a new flavor for interfacing GNU's ld and LLD.
This patch also changes target specifications. `linker-flavor` is now a
mandatory field that specifies the *default* linker flavor that the target will
use. This change also makes the linker interface *explicit*; before, it used to
be derived from other fields like linker-is-gnu, is-like-msvc,
is-like-emscripten, etc.
Another change to target specifications is that the fields `pre-link-args`,
`post-link-args` and `late-link-args` now expect a map from flavor to linker
arguments.
``` diff
- "pre-link-args": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "pre-link-args": {
+ "gcc": ["-Wl,--as-needed", "-Wl,-z,-noexecstack"],
+ "ld": ["--as-needed", "-z,-noexecstack"],
+ },
```
[breaking-change] for users of custom targets specifications
Diffstat (limited to 'src/librustc_back/target')
80 files changed, 433 insertions, 187 deletions
diff --git a/src/librustc_back/target/aarch64_apple_ios.rs b/src/librustc_back/target/aarch64_apple_ios.rs index 5ef79359140..802a8c77db0 100644 --- a/src/librustc_back/target/aarch64_apple_ios.rs +++ b/src/librustc_back/target/aarch64_apple_ios.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; use super::apple_ios_base::{opts, Arch}; @@ -22,6 +23,7 @@ pub fn target() -> TargetResult { target_os: "ios".to_string(), target_env: "".to_string(), target_vendor: "apple".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { features: "+neon,+fp-armv8,+cyclone".to_string(), eliminate_frame_pointer: false, diff --git a/src/librustc_back/target/aarch64_linux_android.rs b/src/librustc_back/target/aarch64_linux_android.rs index 54eead94986..7d8610b4a36 100644 --- a/src/librustc_back/target/aarch64_linux_android.rs +++ b/src/librustc_back/target/aarch64_linux_android.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; // See https://developer.android.com/ndk/guides/abis.html#arm64-v8a @@ -28,6 +29,7 @@ pub fn target() -> TargetResult { target_os: "android".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { abi_blacklist: super::arm_base::abi_blacklist(), .. base diff --git a/src/librustc_back/target/aarch64_unknown_freebsd.rs b/src/librustc_back/target/aarch64_unknown_freebsd.rs index 3c5d6308ee6..c5cfff0be03 100644 --- a/src/librustc_back/target/aarch64_unknown_freebsd.rs +++ b/src/librustc_back/target/aarch64_unknown_freebsd.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -26,6 +27,7 @@ pub fn target() -> TargetResult { target_os: "freebsd".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { abi_blacklist: super::arm_base::abi_blacklist(), .. base diff --git a/src/librustc_back/target/aarch64_unknown_fuchsia.rs b/src/librustc_back/target/aarch64_unknown_fuchsia.rs index 6ba1732e67f..5d680504a02 100644 --- a/src/librustc_back/target/aarch64_unknown_fuchsia.rs +++ b/src/librustc_back/target/aarch64_unknown_fuchsia.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -23,6 +24,7 @@ pub fn target() -> TargetResult { target_os: "fuchsia".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { abi_blacklist: super::arm_base::abi_blacklist(), .. base diff --git a/src/librustc_back/target/aarch64_unknown_linux_gnu.rs b/src/librustc_back/target/aarch64_unknown_linux_gnu.rs index 5f6335d405f..043bd881c72 100644 --- a/src/librustc_back/target/aarch64_unknown_linux_gnu.rs +++ b/src/librustc_back/target/aarch64_unknown_linux_gnu.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -26,6 +27,7 @@ pub fn target() -> TargetResult { arch: "aarch64".to_string(), target_os: "linux".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { abi_blacklist: super::arm_base::abi_blacklist(), .. base diff --git a/src/librustc_back/target/android_base.rs b/src/librustc_back/target/android_base.rs index 9791520e933..49baa1b96ce 100644 --- a/src/librustc_back/target/android_base.rs +++ b/src/librustc_back/target/android_base.rs @@ -8,13 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::TargetOptions; pub fn opts() -> TargetOptions { let mut base = super::linux_base::opts(); // Many of the symbols defined in compiler-rt are also defined in libgcc. // Android's linker doesn't like that by default. - base.pre_link_args.push("-Wl,--allow-multiple-definition".to_string()); + base.pre_link_args + .get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,--allow-multiple-definition".to_string()); base.is_like_android = true; base.position_independent_executables = true; base.has_elf_tls = false; diff --git a/src/librustc_back/target/apple_base.rs b/src/librustc_back/target/apple_base.rs index 3a551a2b124..159f93a74c6 100644 --- a/src/librustc_back/target/apple_base.rs +++ b/src/librustc_back/target/apple_base.rs @@ -10,7 +10,7 @@ use std::env; -use target::TargetOptions; +use target::{LinkArgs, TargetOptions}; pub fn opts() -> TargetOptions { // ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6 @@ -43,7 +43,7 @@ pub fn opts() -> TargetOptions { dll_prefix: "lib".to_string(), dll_suffix: ".dylib".to_string(), archive_format: "bsd".to_string(), - pre_link_args: Vec::new(), + pre_link_args: LinkArgs::new(), exe_allocation_crate: super::maybe_jemalloc(), has_elf_tls: version >= (10, 7), .. Default::default() diff --git a/src/librustc_back/target/apple_ios_base.rs b/src/librustc_back/target/apple_ios_base.rs index 17492b8bdcb..2e7d30d969e 100644 --- a/src/librustc_back/target/apple_ios_base.rs +++ b/src/librustc_back/target/apple_ios_base.rs @@ -8,9 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use std::io; use std::process::Command; -use target::TargetOptions; +use target::{LinkArgs, TargetOptions}; use self::Arch::*; @@ -60,7 +61,7 @@ pub fn get_sdk_root(sdk_name: &str) -> Result<String, String> { } } -fn build_pre_link_args(arch: Arch) -> Result<Vec<String>, String> { +fn build_pre_link_args(arch: Arch) -> Result<LinkArgs, String> { let sdk_name = match arch { Armv7 | Armv7s | Arm64 => "iphoneos", I386 | X86_64 => "iphonesimulator" @@ -70,8 +71,14 @@ fn build_pre_link_args(arch: Arch) -> Result<Vec<String>, String> { let sdk_root = get_sdk_root(sdk_name)?; - Ok(vec!["-arch".to_string(), arch_name.to_string(), - "-Wl,-syslibroot".to_string(), sdk_root]) + let mut args = LinkArgs::new(); + args.insert(LinkerFlavor::Gcc, + vec!["-arch".to_string(), + arch_name.to_string(), + "-Wl,-syslibroot".to_string(), + sdk_root]); + + Ok(args) } fn target_cpu(arch: Arch) -> String { diff --git a/src/librustc_back/target/arm_linux_androideabi.rs b/src/librustc_back/target/arm_linux_androideabi.rs index c7d2df4344c..bccd5a41ab1 100644 --- a/src/librustc_back/target/arm_linux_androideabi.rs +++ b/src/librustc_back/target/arm_linux_androideabi.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -24,6 +25,7 @@ pub fn target() -> TargetResult { target_os: "android".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { abi_blacklist: super::arm_base::abi_blacklist(), .. base diff --git a/src/librustc_back/target/arm_unknown_linux_gnueabi.rs b/src/librustc_back/target/arm_unknown_linux_gnueabi.rs index 77d35edfbd0..165d34fe6c7 100644 --- a/src/librustc_back/target/arm_unknown_linux_gnueabi.rs +++ b/src/librustc_back/target/arm_unknown_linux_gnueabi.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -22,6 +23,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "gnu".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { features: "+v6".to_string(), diff --git a/src/librustc_back/target/arm_unknown_linux_gnueabihf.rs b/src/librustc_back/target/arm_unknown_linux_gnueabihf.rs index b183412be19..731021d979b 100644 --- a/src/librustc_back/target/arm_unknown_linux_gnueabihf.rs +++ b/src/librustc_back/target/arm_unknown_linux_gnueabihf.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -22,6 +23,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "gnu".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { features: "+v6,+vfp2".to_string(), diff --git a/src/librustc_back/target/arm_unknown_linux_musleabi.rs b/src/librustc_back/target/arm_unknown_linux_musleabi.rs index 261d4353c7a..f81bcd78b03 100644 --- a/src/librustc_back/target/arm_unknown_linux_musleabi.rs +++ b/src/librustc_back/target/arm_unknown_linux_musleabi.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -29,6 +30,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "musl".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { abi_blacklist: super::arm_base::abi_blacklist(), .. base diff --git a/src/librustc_back/target/arm_unknown_linux_musleabihf.rs b/src/librustc_back/target/arm_unknown_linux_musleabihf.rs index 1443dcf5bad..6c47678ede6 100644 --- a/src/librustc_back/target/arm_unknown_linux_musleabihf.rs +++ b/src/librustc_back/target/arm_unknown_linux_musleabihf.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -29,6 +30,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "musl".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { abi_blacklist: super::arm_base::abi_blacklist(), .. base diff --git a/src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs b/src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs index 37216e20762..200c6ab74cc 100644 --- a/src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs +++ b/src/librustc_back/target/armv5te_unknown_linux_gnueabi.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -21,6 +22,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "gnu".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { features: "+soft-float".to_string(), @@ -31,4 +33,3 @@ pub fn target() -> TargetResult { } }) } - diff --git a/src/librustc_back/target/armv7_apple_ios.rs b/src/librustc_back/target/armv7_apple_ios.rs index 9e9c4439306..4d874582832 100644 --- a/src/librustc_back/target/armv7_apple_ios.rs +++ b/src/librustc_back/target/armv7_apple_ios.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; use super::apple_ios_base::{opts, Arch}; @@ -22,6 +23,7 @@ pub fn target() -> TargetResult { target_os: "ios".to_string(), target_env: "".to_string(), target_vendor: "apple".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { features: "+v7,+vfp3,+neon".to_string(), max_atomic_width: Some(64), diff --git a/src/librustc_back/target/armv7_linux_androideabi.rs b/src/librustc_back/target/armv7_linux_androideabi.rs index 36f409b7948..0c90e834006 100644 --- a/src/librustc_back/target/armv7_linux_androideabi.rs +++ b/src/librustc_back/target/armv7_linux_androideabi.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; // See https://developer.android.com/ndk/guides/abis.html#v7a @@ -27,6 +28,7 @@ pub fn target() -> TargetResult { target_os: "android".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { abi_blacklist: super::arm_base::abi_blacklist(), .. base diff --git a/src/librustc_back/target/armv7_unknown_linux_gnueabihf.rs b/src/librustc_back/target/armv7_unknown_linux_gnueabihf.rs index 96ccedd5bea..d3a6a68449c 100644 --- a/src/librustc_back/target/armv7_unknown_linux_gnueabihf.rs +++ b/src/librustc_back/target/armv7_unknown_linux_gnueabihf.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -21,6 +22,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "gnu".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { // Info about features at https://wiki.debian.org/ArmHardFloatPort @@ -32,4 +34,3 @@ pub fn target() -> TargetResult { } }) } - diff --git a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs index 8f66e6a4f58..5086cd44f7a 100644 --- a/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs +++ b/src/librustc_back/target/armv7_unknown_linux_musleabihf.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -30,6 +31,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "musl".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { abi_blacklist: super::arm_base::abi_blacklist(), .. base diff --git a/src/librustc_back/target/armv7s_apple_ios.rs b/src/librustc_back/target/armv7s_apple_ios.rs index 6edde6e73ef..96c89a7ed3b 100644 --- a/src/librustc_back/target/armv7s_apple_ios.rs +++ b/src/librustc_back/target/armv7s_apple_ios.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; use super::apple_ios_base::{opts, Arch}; @@ -22,6 +23,7 @@ pub fn target() -> TargetResult { target_os: "ios".to_string(), target_env: "".to_string(), target_vendor: "apple".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { features: "+v7,+vfp4,+neon".to_string(), max_atomic_width: Some(64), diff --git a/src/librustc_back/target/asmjs_unknown_emscripten.rs b/src/librustc_back/target/asmjs_unknown_emscripten.rs index 4d38b0d1705..b884d4e5410 100644 --- a/src/librustc_back/target/asmjs_unknown_emscripten.rs +++ b/src/librustc_back/target/asmjs_unknown_emscripten.rs @@ -8,10 +8,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use super::{Target, TargetOptions}; +use LinkerFlavor; +use super::{LinkArgs, Target, TargetOptions}; use super::emscripten_base::{cmd}; pub fn target() -> Result<Target, String> { + let mut args = LinkArgs::new(); + args.insert(LinkerFlavor::Em, + vec!["-s".to_string(), + "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string()]); + let opts = TargetOptions { linker: cmd("emcc"), ar: cmd("emar"), @@ -24,7 +30,7 @@ pub fn target() -> Result<Target, String> { obj_is_bitcode: true, is_like_emscripten: true, max_atomic_width: Some(32), - post_link_args: vec!["-s".to_string(), "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string()], + post_link_args: args, target_family: Some("unix".to_string()), .. Default::default() }; @@ -37,6 +43,7 @@ pub fn target() -> Result<Target, String> { target_vendor: "unknown".to_string(), data_layout: "e-p:32:32-i64:64-v128:32:128-n32-S128".to_string(), arch: "asmjs".to_string(), + linker_flavor: LinkerFlavor::Em, options: opts, }) } diff --git a/src/librustc_back/target/dragonfly_base.rs b/src/librustc_back/target/dragonfly_base.rs index dca33e45af7..e44cd393289 100644 --- a/src/librustc_back/target/dragonfly_base.rs +++ b/src/librustc_back/target/dragonfly_base.rs @@ -8,26 +8,30 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use target::TargetOptions; +use LinkerFlavor; +use target::{LinkArgs, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { + let mut args = LinkArgs::new(); + args.insert(LinkerFlavor::Gcc, vec![ + // GNU-style linkers will use this to omit linking to libraries + // which don't actually fulfill any relocations, but only for + // libraries which follow this flag. Thus, use it before + // specifying libraries to link to. + "-Wl,--as-needed".to_string(), + + // Always enable NX protection when it is available + "-Wl,-z,noexecstack".to_string(), + ]); + TargetOptions { dynamic_linking: true, executables: true, target_family: Some("unix".to_string()), linker_is_gnu: true, has_rpath: true, - pre_link_args: vec![ - // GNU-style linkers will use this to omit linking to libraries - // which don't actually fulfill any relocations, but only for - // libraries which follow this flag. Thus, use it before - // specifying libraries to link to. - "-Wl,--as-needed".to_string(), - - // Always enable NX protection when it is available - "-Wl,-z,noexecstack".to_string(), - ], + pre_link_args: args, position_independent_executables: true, exe_allocation_crate: super::maybe_jemalloc(), .. Default::default() diff --git a/src/librustc_back/target/freebsd_base.rs b/src/librustc_back/target/freebsd_base.rs index dca33e45af7..e44cd393289 100644 --- a/src/librustc_back/target/freebsd_base.rs +++ b/src/librustc_back/target/freebsd_base.rs @@ -8,26 +8,30 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use target::TargetOptions; +use LinkerFlavor; +use target::{LinkArgs, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { + let mut args = LinkArgs::new(); + args.insert(LinkerFlavor::Gcc, vec![ + // GNU-style linkers will use this to omit linking to libraries + // which don't actually fulfill any relocations, but only for + // libraries which follow this flag. Thus, use it before + // specifying libraries to link to. + "-Wl,--as-needed".to_string(), + + // Always enable NX protection when it is available + "-Wl,-z,noexecstack".to_string(), + ]); + TargetOptions { dynamic_linking: true, executables: true, target_family: Some("unix".to_string()), linker_is_gnu: true, has_rpath: true, - pre_link_args: vec![ - // GNU-style linkers will use this to omit linking to libraries - // which don't actually fulfill any relocations, but only for - // libraries which follow this flag. Thus, use it before - // specifying libraries to link to. - "-Wl,--as-needed".to_string(), - - // Always enable NX protection when it is available - "-Wl,-z,noexecstack".to_string(), - ], + pre_link_args: args, position_independent_executables: true, exe_allocation_crate: super::maybe_jemalloc(), .. Default::default() diff --git a/src/librustc_back/target/fuchsia_base.rs b/src/librustc_back/target/fuchsia_base.rs index 8c517224201..c6207cdc4d9 100644 --- a/src/librustc_back/target/fuchsia_base.rs +++ b/src/librustc_back/target/fuchsia_base.rs @@ -8,30 +8,34 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use target::TargetOptions; +use LinkerFlavor; +use target::{LinkArgs, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { + let mut args = LinkArgs::new(); + args.insert(LinkerFlavor::Gcc, vec![ + // We want to be able to strip as much executable code as possible + // from the linker command line, and this flag indicates to the + // linker that it can avoid linking in dynamic libraries that don't + // actually satisfy any symbols up to that point (as with many other + // resolutions the linker does). This option only applies to all + // following libraries so we're sure to pass it as one of the first + // arguments. + // FIXME: figure out whether these linker args are desirable + //"-Wl,--as-needed".to_string(), + + // Always enable NX protection when it is available + //"-Wl,-z,noexecstack".to_string(), + ]); + TargetOptions { dynamic_linking: true, executables: true, target_family: Some("unix".to_string()), linker_is_gnu: true, has_rpath: true, - pre_link_args: vec![ - // We want to be able to strip as much executable code as possible - // from the linker command line, and this flag indicates to the - // linker that it can avoid linking in dynamic libraries that don't - // actually satisfy any symbols up to that point (as with many other - // resolutions the linker does). This option only applies to all - // following libraries so we're sure to pass it as one of the first - // arguments. - // FIXME: figure out whether these linker args are desirable - //"-Wl,--as-needed".to_string(), - - // Always enable NX protection when it is available - //"-Wl,-z,noexecstack".to_string(), - ], + pre_link_args: args, position_independent_executables: true, exe_allocation_crate: "alloc_system".to_string(), has_elf_tls: true, diff --git a/src/librustc_back/target/i386_apple_ios.rs b/src/librustc_back/target/i386_apple_ios.rs index 319ada4f8e1..a6383179f3a 100644 --- a/src/librustc_back/target/i386_apple_ios.rs +++ b/src/librustc_back/target/i386_apple_ios.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; use super::apple_ios_base::{opts, Arch}; @@ -22,6 +23,7 @@ pub fn target() -> TargetResult { target_os: "ios".to_string(), target_env: "".to_string(), target_vendor: "apple".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { max_atomic_width: Some(64), .. base diff --git a/src/librustc_back/target/i686_apple_darwin.rs b/src/librustc_back/target/i686_apple_darwin.rs index d3b09d9a0f1..6b14972e9f7 100644 --- a/src/librustc_back/target/i686_apple_darwin.rs +++ b/src/librustc_back/target/i686_apple_darwin.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::apple_base::opts(); base.cpu = "yonah".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.push("-m32".to_string()); + base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]); Ok(Target { llvm_target: "i686-apple-darwin".to_string(), @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "macos".to_string(), target_env: "".to_string(), target_vendor: "apple".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/i686_linux_android.rs b/src/librustc_back/target/i686_linux_android.rs index f8a8f5a3500..a5390cbfb72 100644 --- a/src/librustc_back/target/i686_linux_android.rs +++ b/src/librustc_back/target/i686_linux_android.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; // See https://developer.android.com/ndk/guides/abis.html#x86 @@ -31,6 +32,7 @@ pub fn target() -> TargetResult { target_os: "android".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/i686_pc_windows_gnu.rs b/src/librustc_back/target/i686_pc_windows_gnu.rs index 29477261392..4a736a93be7 100644 --- a/src/librustc_back/target/i686_pc_windows_gnu.rs +++ b/src/librustc_back/target/i686_pc_windows_gnu.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { @@ -18,7 +19,8 @@ pub fn target() -> TargetResult { // Mark all dynamic libraries and executables as compatible with the larger 4GiB address // space available to x86 Windows binaries on x86_64. - base.pre_link_args.push("-Wl,--large-address-aware".to_string()); + base.pre_link_args + .get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,--large-address-aware".to_string()); Ok(Target { llvm_target: "i686-pc-windows-gnu".to_string(), @@ -29,6 +31,7 @@ pub fn target() -> TargetResult { target_os: "windows".to_string(), target_env: "gnu".to_string(), target_vendor: "pc".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/i686_pc_windows_msvc.rs b/src/librustc_back/target/i686_pc_windows_msvc.rs index 2290d2057f1..17fe306804f 100644 --- a/src/librustc_back/target/i686_pc_windows_msvc.rs +++ b/src/librustc_back/target/i686_pc_windows_msvc.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { @@ -17,12 +18,13 @@ pub fn target() -> TargetResult { // Mark all dynamic libraries and executables as compatible with the larger 4GiB address // space available to x86 Windows binaries on x86_64. - base.pre_link_args.push("/LARGEADDRESSAWARE".to_string()); + base.pre_link_args + .get_mut(&LinkerFlavor::Msvc).unwrap().push("/LARGEADDRESSAWARE".to_string()); // Ensure the linker will only produce an image if it can also produce a table of // the image's safe exception handlers. // https://msdn.microsoft.com/en-us/library/9a89h429.aspx - base.pre_link_args.push("/SAFESEH".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Msvc).unwrap().push("/SAFESEH".to_string()); Ok(Target { llvm_target: "i686-pc-windows-msvc".to_string(), @@ -33,6 +35,7 @@ pub fn target() -> TargetResult { target_os: "windows".to_string(), target_env: "msvc".to_string(), target_vendor: "pc".to_string(), + linker_flavor: LinkerFlavor::Msvc, options: base, }) } diff --git a/src/librustc_back/target/i686_unknown_dragonfly.rs b/src/librustc_back/target/i686_unknown_dragonfly.rs index d8f8431e66e..052bc23c119 100644 --- a/src/librustc_back/target/i686_unknown_dragonfly.rs +++ b/src/librustc_back/target/i686_unknown_dragonfly.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::dragonfly_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.push("-m32".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); Ok(Target { llvm_target: "i686-unknown-dragonfly".to_string(), @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "dragonfly".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/i686_unknown_freebsd.rs b/src/librustc_back/target/i686_unknown_freebsd.rs index ddbc74f25c9..d77a9cca268 100644 --- a/src/librustc_back/target/i686_unknown_freebsd.rs +++ b/src/librustc_back/target/i686_unknown_freebsd.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::freebsd_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.push("-m32".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); Ok(Target { llvm_target: "i686-unknown-freebsd".to_string(), @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "freebsd".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/i686_unknown_haiku.rs b/src/librustc_back/target/i686_unknown_haiku.rs index 9078206c9e0..b0e67bd90dd 100644 --- a/src/librustc_back/target/i686_unknown_haiku.rs +++ b/src/librustc_back/target/i686_unknown_haiku.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::haiku_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.push("-m32".to_string()); + base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m32".to_string()]); Ok(Target { llvm_target: "i686-unknown-haiku".to_string(), @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "haiku".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/i686_unknown_linux_gnu.rs b/src/librustc_back/target/i686_unknown_linux_gnu.rs index bf9c28b0c10..3c5c1067626 100644 --- a/src/librustc_back/target/i686_unknown_linux_gnu.rs +++ b/src/librustc_back/target/i686_unknown_linux_gnu.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.push("-m32".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); Ok(Target { llvm_target: "i686-unknown-linux-gnu".to_string(), @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "gnu".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/i686_unknown_linux_musl.rs b/src/librustc_back/target/i686_unknown_linux_musl.rs index ced59448f7f..3ed8c94d0bf 100644 --- a/src/librustc_back/target/i686_unknown_linux_musl.rs +++ b/src/librustc_back/target/i686_unknown_linux_musl.rs @@ -8,14 +8,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.push("-m32".to_string()); - base.pre_link_args.push("-Wl,-melf_i386".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,-melf_i386".to_string()); // The unwinder used by i686-unknown-linux-musl, the LLVM libunwind // implementation, apparently relies on frame pointers existing... somehow. @@ -40,6 +41,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "musl".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/i686_unknown_netbsd.rs b/src/librustc_back/target/i686_unknown_netbsd.rs index e7e2ee3f905..fc92e5aee6a 100644 --- a/src/librustc_back/target/i686_unknown_netbsd.rs +++ b/src/librustc_back/target/i686_unknown_netbsd.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.push("-m32".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); Ok(Target { llvm_target: "i686-unknown-netbsdelf".to_string(), @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "netbsd".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/i686_unknown_openbsd.rs b/src/librustc_back/target/i686_unknown_openbsd.rs index 81efd37386a..7ef68bd6d9c 100644 --- a/src/librustc_back/target/i686_unknown_openbsd.rs +++ b/src/librustc_back/target/i686_unknown_openbsd.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::openbsd_base::opts(); base.cpu = "pentium4".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.push("-m32".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); Ok(Target { llvm_target: "i686-unknown-openbsd".to_string(), @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "openbsd".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/le32_unknown_nacl.rs b/src/librustc_back/target/le32_unknown_nacl.rs index 891e7dda14a..f4265e0eb14 100644 --- a/src/librustc_back/target/le32_unknown_nacl.rs +++ b/src/librustc_back/target/le32_unknown_nacl.rs @@ -8,17 +8,25 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use super::{Target, TargetOptions, TargetResult}; +use LinkerFlavor; +use super::{LinkArgs, Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { + let mut pre_link_args = LinkArgs::new(); + pre_link_args.insert(LinkerFlavor::Gcc, + vec!["--pnacl-exceptions=sjlj".to_string(), + "--target=le32-unknown-nacl".to_string(), + "-Wl,--start-group".to_string()]); + let mut post_link_args = LinkArgs::new(); + post_link_args.insert(LinkerFlavor::Gcc, + vec!["-Wl,--end-group".to_string()]); + let opts = TargetOptions { linker: "pnacl-clang".to_string(), ar: "pnacl-ar".to_string(), - pre_link_args: vec!["--pnacl-exceptions=sjlj".to_string(), - "--target=le32-unknown-nacl".to_string(), - "-Wl,--start-group".to_string()], - post_link_args: vec!["-Wl,--end-group".to_string()], + pre_link_args: pre_link_args, + post_link_args: post_link_args, dynamic_linking: false, executables: true, exe_suffix: ".pexe".to_string(), @@ -36,6 +44,7 @@ pub fn target() -> TargetResult { target_vendor: "unknown".to_string(), data_layout: "e-i64:64:64-p:32:32:32-v128:32:32".to_string(), arch: "le32".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: opts, }) } diff --git a/src/librustc_back/target/linux_base.rs b/src/librustc_back/target/linux_base.rs index 4b2ae9c8e69..722d2fa16ef 100644 --- a/src/librustc_back/target/linux_base.rs +++ b/src/librustc_back/target/linux_base.rs @@ -8,29 +8,33 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use target::TargetOptions; +use LinkerFlavor; +use target::{LinkArgs, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { + let mut args = LinkArgs::new(); + args.insert(LinkerFlavor::Gcc, vec![ + // We want to be able to strip as much executable code as possible + // from the linker command line, and this flag indicates to the + // linker that it can avoid linking in dynamic libraries that don't + // actually satisfy any symbols up to that point (as with many other + // resolutions the linker does). This option only applies to all + // following libraries so we're sure to pass it as one of the first + // arguments. + "-Wl,--as-needed".to_string(), + + // Always enable NX protection when it is available + "-Wl,-z,noexecstack".to_string(), + ]); + TargetOptions { dynamic_linking: true, executables: true, target_family: Some("unix".to_string()), linker_is_gnu: true, has_rpath: true, - pre_link_args: vec![ - // We want to be able to strip as much executable code as possible - // from the linker command line, and this flag indicates to the - // linker that it can avoid linking in dynamic libraries that don't - // actually satisfy any symbols up to that point (as with many other - // resolutions the linker does). This option only applies to all - // following libraries so we're sure to pass it as one of the first - // arguments. - "-Wl,--as-needed".to_string(), - - // Always enable NX protection when it is available - "-Wl,-z,noexecstack".to_string(), - ], + pre_link_args: args, position_independent_executables: true, exe_allocation_crate: super::maybe_jemalloc(), has_elf_tls: true, diff --git a/src/librustc_back/target/linux_musl_base.rs b/src/librustc_back/target/linux_musl_base.rs index 18cca425a32..236f2c1ef0a 100644 --- a/src/librustc_back/target/linux_musl_base.rs +++ b/src/librustc_back/target/linux_musl_base.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::TargetOptions; pub fn opts() -> TargetOptions { @@ -15,13 +16,13 @@ pub fn opts() -> TargetOptions { // Make sure that the linker/gcc really don't pull in anything, including // default objects, libs, etc. - base.pre_link_args.push("-nostdlib".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-nostdlib".to_string()); // At least when this was tested, the linker would not add the // `GNU_EH_FRAME` program header to executables generated, which is required // when unwinding to locate the unwinding information. I'm not sure why this // argument is *not* necessary for normal builds, but it can't hurt! - base.pre_link_args.push("-Wl,--eh-frame-hdr".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,--eh-frame-hdr".to_string()); // There's a whole bunch of circular dependencies when dealing with MUSL // unfortunately. To put this in perspective libc is statically linked to @@ -45,8 +46,8 @@ pub fn opts() -> TargetOptions { // link everything as a group, not stripping anything out until everything // is processed. The linker will still perform a pass to strip out object // files but it won't do so until all objects/archives have been processed. - base.pre_link_args.push("-Wl,-(".to_string()); - base.post_link_args.push("-Wl,-)".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-Wl,-(".to_string()); + base.post_link_args.insert(LinkerFlavor::Gcc, vec!["-Wl,-)".to_string()]); // When generating a statically linked executable there's generally some // small setup needed which is listed in these files. These are provided by diff --git a/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs b/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs index c284840ecb4..038a70ed6b1 100644 --- a/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs +++ b/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -20,6 +21,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "gnu".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { // NOTE(mips64r2) matches C toolchain cpu: "mips64r2".to_string(), diff --git a/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs b/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs index 17895836fe8..aed4c4fbb08 100644 --- a/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs +++ b/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -20,6 +21,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "gnu".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { // NOTE(mips64r2) matches C toolchain cpu: "mips64r2".to_string(), diff --git a/src/librustc_back/target/mips_unknown_linux_gnu.rs b/src/librustc_back/target/mips_unknown_linux_gnu.rs index a6d8fae2536..9ef61f9cadd 100644 --- a/src/librustc_back/target/mips_unknown_linux_gnu.rs +++ b/src/librustc_back/target/mips_unknown_linux_gnu.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -20,6 +21,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "gnu".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { cpu: "mips32r2".to_string(), features: "+mips32r2".to_string(), diff --git a/src/librustc_back/target/mips_unknown_linux_musl.rs b/src/librustc_back/target/mips_unknown_linux_musl.rs index e4a6d2a55d9..f54790bab97 100644 --- a/src/librustc_back/target/mips_unknown_linux_musl.rs +++ b/src/librustc_back/target/mips_unknown_linux_musl.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -20,6 +21,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "musl".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { cpu: "mips32r2".to_string(), features: "+mips32r2,+soft-float".to_string(), diff --git a/src/librustc_back/target/mips_unknown_linux_uclibc.rs b/src/librustc_back/target/mips_unknown_linux_uclibc.rs index ccc64ea393b..59c07efe0fd 100644 --- a/src/librustc_back/target/mips_unknown_linux_uclibc.rs +++ b/src/librustc_back/target/mips_unknown_linux_uclibc.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -20,6 +21,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "uclibc".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { cpu: "mips32r2".to_string(), features: "+mips32r2,+soft-float".to_string(), diff --git a/src/librustc_back/target/mipsel_unknown_linux_gnu.rs b/src/librustc_back/target/mipsel_unknown_linux_gnu.rs index 9b8b1d5713f..ec19cc1a536 100644 --- a/src/librustc_back/target/mipsel_unknown_linux_gnu.rs +++ b/src/librustc_back/target/mipsel_unknown_linux_gnu.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -20,6 +21,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "gnu".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { cpu: "mips32".to_string(), diff --git a/src/librustc_back/target/mipsel_unknown_linux_musl.rs b/src/librustc_back/target/mipsel_unknown_linux_musl.rs index 5693bddd048..00085d18e6d 100644 --- a/src/librustc_back/target/mipsel_unknown_linux_musl.rs +++ b/src/librustc_back/target/mipsel_unknown_linux_musl.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -20,6 +21,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "musl".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { cpu: "mips32".to_string(), features: "+mips32,+soft-float".to_string(), diff --git a/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs b/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs index 3acade5a474..b3ca2edec1e 100644 --- a/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs +++ b/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -20,6 +21,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "uclibc".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { cpu: "mips32".to_string(), diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs index 559418d2c4f..ca6894a7b70 100644 --- a/src/librustc_back/target/mod.rs +++ b/src/librustc_back/target/mod.rs @@ -50,7 +50,7 @@ use std::default::Default; use std::io::prelude::*; use syntax::abi::{Abi, lookup as lookup_abi}; -use PanicStrategy; +use {LinkerFlavor, PanicStrategy}; mod android_base; mod apple_base; @@ -72,6 +72,7 @@ mod thumb_base; mod fuchsia_base; mod redox_base; +pub type LinkArgs = BTreeMap<LinkerFlavor, Vec<String>>; pub type TargetResult = Result<Target, String>; macro_rules! supported_targets { @@ -241,6 +242,8 @@ pub struct Target { pub arch: String, /// [Data layout](http://llvm.org/docs/LangRef.html#data-layout) to pass to LLVM. pub data_layout: String, + /// Linker flavor + pub linker_flavor: LinkerFlavor, /// Optional settings with defaults. pub options: TargetOptions, } @@ -261,7 +264,7 @@ pub struct TargetOptions { /// Linker arguments that are unconditionally passed *before* any /// user-defined libraries. - pub pre_link_args: Vec<String>, + pub pre_link_args: LinkArgs, /// Objects to link before all others, always found within the /// sysroot folder. pub pre_link_objects_exe: Vec<String>, // ... when linking an executable @@ -269,13 +272,13 @@ pub struct TargetOptions { /// Linker arguments that are unconditionally passed after any /// user-defined but before post_link_objects. Standard platform /// libraries that should be always be linked to, usually go here. - pub late_link_args: Vec<String>, + pub late_link_args: LinkArgs, /// Objects to link after all others, always found within the /// sysroot folder. pub post_link_objects: Vec<String>, /// Linker arguments that are unconditionally passed *after* any /// user-defined libraries. - pub post_link_args: Vec<String>, + pub post_link_args: LinkArgs, /// Extra arguments to pass to the external assembler (when used) pub asm_args: Vec<String>, @@ -412,8 +415,8 @@ impl Default for TargetOptions { is_builtin: false, linker: option_env!("CFG_DEFAULT_LINKER").unwrap_or("cc").to_string(), ar: option_env!("CFG_DEFAULT_AR").unwrap_or("ar").to_string(), - pre_link_args: Vec::new(), - post_link_args: Vec::new(), + pre_link_args: LinkArgs::new(), + post_link_args: LinkArgs::new(), asm_args: Vec::new(), cpu: "generic".to_string(), features: "".to_string(), @@ -445,7 +448,7 @@ impl Default for TargetOptions { pre_link_objects_exe: Vec::new(), pre_link_objects_dll: Vec::new(), post_link_objects: Vec::new(), - late_link_args: Vec::new(), + late_link_args: LinkArgs::new(), archive_format: "gnu".to_string(), custom_unwind_resume: false, lib_allocation_crate: "alloc_system".to_string(), @@ -529,6 +532,10 @@ impl Target { target_os: get_req_field("os")?, target_env: get_opt_field("env", ""), target_vendor: get_opt_field("vendor", "unknown"), + linker_flavor: LinkerFlavor::from_str(&*get_req_field("linker-flavor")?) + .ok_or_else(|| { + format!("linker flavor must be {}", LinkerFlavor::one_of()) + })?, options: Default::default(), }; @@ -579,17 +586,49 @@ impl Target { .map(|s| s.to_string() ); } } ); + ($key_name:ident, LinkerFlavor) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + obj.find(&name[..]).and_then(|o| o.as_string().map(|s| { + LinkerFlavor::from_str(&s).ok_or_else(|| { + Err(format!("'{}' is not a valid value for linker-flavor. \ + Use 'em', 'gcc', 'ld' or 'msvc.", s)) + }) + })).unwrap_or(Ok(())) + } ); + ($key_name:ident, link_args) => ( { + let name = (stringify!($key_name)).replace("_", "-"); + if let Some(obj) = obj.find(&name[..]).and_then(|o| o.as_object()) { + let mut args = LinkArgs::new(); + for (k, v) in obj { + let k = LinkerFlavor::from_str(&k).ok_or_else(|| { + format!("{}: '{}' is not a valid value for linker-flavor. \ + Use 'em', 'gcc', 'ld' or 'msvc'", name, k) + })?; + + let v = v.as_array().map(|a| { + a + .iter() + .filter_map(|o| o.as_string()) + .map(|s| s.to_owned()) + .collect::<Vec<_>>() + }).unwrap_or(vec![]); + + args.insert(k, v); + } + base.options.$key_name = args; + } + } ); } key!(is_builtin, bool); key!(linker); key!(ar); - key!(pre_link_args, list); + key!(pre_link_args, link_args); key!(pre_link_objects_exe, list); key!(pre_link_objects_dll, list); - key!(late_link_args, list); + key!(late_link_args, link_args); key!(post_link_objects, list); - key!(post_link_args, list); + key!(post_link_args, link_args); key!(asm_args, list); key!(cpu); key!(features); @@ -734,6 +773,16 @@ impl ToJson for Target { d.insert(name.to_string(), self.options.$attr.to_json()); } } ); + (link_args - $attr:ident) => ( { + let name = (stringify!($attr)).replace("_", "-"); + if default.$attr != self.options.$attr { + let obj = self.options.$attr + .iter() + .map(|(k, v)| (k.desc().to_owned(), v.clone())) + .collect::<BTreeMap<_, _>>(); + d.insert(name.to_string(), obj.to_json()); + } + } ); } target_val!(llvm_target); @@ -743,18 +792,18 @@ impl ToJson for Target { target_val!(target_os, "os"); target_val!(target_env, "env"); target_val!(target_vendor, "vendor"); - target_val!(arch); target_val!(data_layout); + target_val!(linker_flavor); target_option_val!(is_builtin); target_option_val!(linker); target_option_val!(ar); - target_option_val!(pre_link_args); + target_option_val!(link_args - pre_link_args); target_option_val!(pre_link_objects_exe); target_option_val!(pre_link_objects_dll); - target_option_val!(late_link_args); + target_option_val!(link_args - late_link_args); target_option_val!(post_link_objects); - target_option_val!(post_link_args); + target_option_val!(link_args - post_link_args); target_option_val!(asm_args); target_option_val!(cpu); target_option_val!(features); diff --git a/src/librustc_back/target/netbsd_base.rs b/src/librustc_back/target/netbsd_base.rs index 57179a68afd..63245fcae76 100644 --- a/src/librustc_back/target/netbsd_base.rs +++ b/src/librustc_back/target/netbsd_base.rs @@ -8,26 +8,30 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use target::TargetOptions; +use LinkerFlavor; +use target::{LinkArgs, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { + let mut args = LinkArgs::new(); + args.insert(LinkerFlavor::Gcc, vec![ + // GNU-style linkers will use this to omit linking to libraries + // which don't actually fulfill any relocations, but only for + // libraries which follow this flag. Thus, use it before + // specifying libraries to link to. + "-Wl,--as-needed".to_string(), + + // Always enable NX protection when it is available + "-Wl,-z,noexecstack".to_string(), + ]); + TargetOptions { dynamic_linking: true, executables: true, target_family: Some("unix".to_string()), linker_is_gnu: true, has_rpath: true, - pre_link_args: vec![ - // GNU-style linkers will use this to omit linking to libraries - // which don't actually fulfill any relocations, but only for - // libraries which follow this flag. Thus, use it before - // specifying libraries to link to. - "-Wl,--as-needed".to_string(), - - // Always enable NX protection when it is available - "-Wl,-z,noexecstack".to_string(), - ], + pre_link_args: args, position_independent_executables: true, .. Default::default() } diff --git a/src/librustc_back/target/openbsd_base.rs b/src/librustc_back/target/openbsd_base.rs index 12b8e8bdc88..2df9b8e03ff 100644 --- a/src/librustc_back/target/openbsd_base.rs +++ b/src/librustc_back/target/openbsd_base.rs @@ -8,10 +8,23 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use target::TargetOptions; +use LinkerFlavor; +use target::{LinkArgs, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { + let mut args = LinkArgs::new(); + args.insert(LinkerFlavor::Gcc, vec![ + // GNU-style linkers will use this to omit linking to libraries + // which don't actually fulfill any relocations, but only for + // libraries which follow this flag. Thus, use it before + // specifying libraries to link to. + "-Wl,--as-needed".to_string(), + + // Always enable NX protection when it is available + "-Wl,-z,noexecstack".to_string(), + ]); + TargetOptions { dynamic_linking: true, executables: true, @@ -19,16 +32,7 @@ pub fn opts() -> TargetOptions { linker_is_gnu: true, has_rpath: true, is_like_openbsd: true, - pre_link_args: vec![ - // GNU-style linkers will use this to omit linking to libraries - // which don't actually fulfill any relocations, but only for - // libraries which follow this flag. Thus, use it before - // specifying libraries to link to. - "-Wl,--as-needed".to_string(), - - // Always enable NX protection when it is available - "-Wl,-z,noexecstack".to_string(), - ], + pre_link_args: args, position_independent_executables: true, exe_allocation_crate: "alloc_system".to_string(), .. Default::default() diff --git a/src/librustc_back/target/powerpc64_unknown_linux_gnu.rs b/src/librustc_back/target/powerpc64_unknown_linux_gnu.rs index 909c5488dcb..55a5bfd1e67 100644 --- a/src/librustc_back/target/powerpc64_unknown_linux_gnu.rs +++ b/src/librustc_back/target/powerpc64_unknown_linux_gnu.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); base.cpu = "ppc64".to_string(); - base.pre_link_args.push("-m64".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); base.max_atomic_width = Some(64); // see #36994 @@ -28,6 +29,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "gnu".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs b/src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs index a692346ca0f..c22bc3b041a 100644 --- a/src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs +++ b/src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); base.cpu = "ppc64le".to_string(); - base.pre_link_args.push("-m64".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); base.max_atomic_width = Some(64); // see #36994 @@ -28,6 +29,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "gnu".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/powerpc_unknown_linux_gnu.rs b/src/librustc_back/target/powerpc_unknown_linux_gnu.rs index 284772c4331..677d198b1a3 100644 --- a/src/librustc_back/target/powerpc_unknown_linux_gnu.rs +++ b/src/librustc_back/target/powerpc_unknown_linux_gnu.rs @@ -8,11 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); - base.pre_link_args.push("-m32".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string()); base.max_atomic_width = Some(32); // see #36994 @@ -27,6 +28,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "gnu".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/redox_base.rs b/src/librustc_back/target/redox_base.rs index c5e1e107753..f26a86d4bdc 100644 --- a/src/librustc_back/target/redox_base.rs +++ b/src/librustc_back/target/redox_base.rs @@ -8,25 +8,28 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use PanicStrategy; -use target::TargetOptions; +use {LinkerFlavor, PanicStrategy}; +use target::{LinkArgs, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { - TargetOptions { - pre_link_args: vec![ - // We want to be able to strip as much executable code as possible - // from the linker command line, and this flag indicates to the - // linker that it can avoid linking in dynamic libraries that don't - // actually satisfy any symbols up to that point (as with many other - // resolutions the linker does). This option only applies to all - // following libraries so we're sure to pass it as one of the first - // arguments. - "-Wl,--as-needed".to_string(), + let mut args = LinkArgs::new(); + args.insert(LinkerFlavor::Gcc, vec![ + // We want to be able to strip as much executable code as possible + // from the linker command line, and this flag indicates to the + // linker that it can avoid linking in dynamic libraries that don't + // actually satisfy any symbols up to that point (as with many other + // resolutions the linker does). This option only applies to all + // following libraries so we're sure to pass it as one of the first + // arguments. + "-Wl,--as-needed".to_string(), + + // Always enable NX protection when it is available + "-Wl,-z,noexecstack".to_string() + ]); - // Always enable NX protection when it is available - "-Wl,-z,noexecstack".to_string() - ], + TargetOptions { + pre_link_args: args, executables: true, relocation_model: "static".to_string(), disable_redzone: true, diff --git a/src/librustc_back/target/s390x_unknown_linux_gnu.rs b/src/librustc_back/target/s390x_unknown_linux_gnu.rs index 671fb4f4319..cc8eb7c4e84 100644 --- a/src/librustc_back/target/s390x_unknown_linux_gnu.rs +++ b/src/librustc_back/target/s390x_unknown_linux_gnu.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { @@ -31,6 +32,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "gnu".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/sparc64_unknown_linux_gnu.rs b/src/librustc_back/target/sparc64_unknown_linux_gnu.rs index f627cc18f0b..1bd51ac6258 100644 --- a/src/librustc_back/target/sparc64_unknown_linux_gnu.rs +++ b/src/librustc_back/target/sparc64_unknown_linux_gnu.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "gnu".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/sparc64_unknown_netbsd.rs b/src/librustc_back/target/sparc64_unknown_netbsd.rs index f30cebbc2d5..bc65a17ce6e 100644 --- a/src/librustc_back/target/sparc64_unknown_netbsd.rs +++ b/src/librustc_back/target/sparc64_unknown_netbsd.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); base.cpu = "v9".to_string(); - base.pre_link_args.push("-m64".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); base.max_atomic_width = Some(64); Ok(Target { @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "netbsd".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/sparcv9_sun_solaris.rs b/src/librustc_back/target/sparcv9_sun_solaris.rs index c88e5a402f2..122b38968a9 100644 --- a/src/librustc_back/target/sparcv9_sun_solaris.rs +++ b/src/librustc_back/target/sparcv9_sun_solaris.rs @@ -8,11 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::solaris_base::opts(); - base.pre_link_args.push("-m64".to_string()); + base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]); // llvm calls this "v9" base.cpu = "v9".to_string(); base.max_atomic_width = Some(64); @@ -30,6 +31,7 @@ pub fn target() -> TargetResult { target_os: "solaris".to_string(), target_env: "".to_string(), target_vendor: "sun".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/thumbv6m_none_eabi.rs b/src/librustc_back/target/thumbv6m_none_eabi.rs index 6c22f985384..08bf145e551 100644 --- a/src/librustc_back/target/thumbv6m_none_eabi.rs +++ b/src/librustc_back/target/thumbv6m_none_eabi.rs @@ -10,6 +10,7 @@ // Targets the Cortex-M0, Cortex-M0+ and Cortex-M1 processors (ARMv6-M architecture) +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -22,6 +23,7 @@ pub fn target() -> TargetResult { target_os: "none".to_string(), target_env: "".to_string(), target_vendor: "".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { // The ARMv6-M architecture doesn't support unaligned loads/stores so we disable them diff --git a/src/librustc_back/target/thumbv7em_none_eabi.rs b/src/librustc_back/target/thumbv7em_none_eabi.rs index ddad4e3624f..13f9cc5f65f 100644 --- a/src/librustc_back/target/thumbv7em_none_eabi.rs +++ b/src/librustc_back/target/thumbv7em_none_eabi.rs @@ -19,6 +19,7 @@ // To opt-in to hardware accelerated floating point operations, you can use, for example, // `-C target-feature=+vfp4` or `-C target-cpu=cortex-m4`. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -31,6 +32,7 @@ pub fn target() -> TargetResult { target_os: "none".to_string(), target_env: "".to_string(), target_vendor: "".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { max_atomic_width: Some(32), diff --git a/src/librustc_back/target/thumbv7em_none_eabihf.rs b/src/librustc_back/target/thumbv7em_none_eabihf.rs index a9fac48e8e5..929b6db6fb2 100644 --- a/src/librustc_back/target/thumbv7em_none_eabihf.rs +++ b/src/librustc_back/target/thumbv7em_none_eabihf.rs @@ -18,6 +18,7 @@ // // To opt into double precision hardware support, use the `-C target-feature=-fp-only-sp` flag. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -30,6 +31,7 @@ pub fn target() -> TargetResult { target_os: "none".to_string(), target_env: "".to_string(), target_vendor: "".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { // `+vfp4` is the lowest common denominator between the Cortex-M4 (vfp4-16) and the diff --git a/src/librustc_back/target/thumbv7m_none_eabi.rs b/src/librustc_back/target/thumbv7m_none_eabi.rs index ed61dd0459b..8d46e7cb907 100644 --- a/src/librustc_back/target/thumbv7m_none_eabi.rs +++ b/src/librustc_back/target/thumbv7m_none_eabi.rs @@ -10,6 +10,7 @@ // Targets the Cortex-M3 processor (ARMv7-M) +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; pub fn target() -> TargetResult { @@ -22,6 +23,7 @@ pub fn target() -> TargetResult { target_os: "none".to_string(), target_env: "".to_string(), target_vendor: "".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { max_atomic_width: Some(32), diff --git a/src/librustc_back/target/wasm32_unknown_emscripten.rs b/src/librustc_back/target/wasm32_unknown_emscripten.rs index b1967fa8f37..a51f59d6ff1 100644 --- a/src/librustc_back/target/wasm32_unknown_emscripten.rs +++ b/src/librustc_back/target/wasm32_unknown_emscripten.rs @@ -8,10 +8,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use super::{Target, TargetOptions}; +use LinkerFlavor; +use super::{LinkArgs, Target, TargetOptions}; use super::emscripten_base::{cmd}; pub fn target() -> Result<Target, String> { + let mut post_link_args = LinkArgs::new(); + post_link_args.insert(LinkerFlavor::Gcc, + vec!["-s".to_string(), + "BINARYEN=1".to_string(), + "-s".to_string(), + "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string()]); + let opts = TargetOptions { linker: cmd("emcc"), ar: cmd("emar"), @@ -26,8 +34,7 @@ pub fn target() -> Result<Target, String> { obj_is_bitcode: true, is_like_emscripten: true, max_atomic_width: Some(32), - post_link_args: vec!["-s".to_string(), "BINARYEN=1".to_string(), - "-s".to_string(), "ERROR_ON_UNDEFINED_SYMBOLS=1".to_string()], + post_link_args: post_link_args, target_family: Some("unix".to_string()), .. Default::default() }; @@ -40,6 +47,7 @@ pub fn target() -> Result<Target, String> { target_vendor: "unknown".to_string(), data_layout: "e-p:32:32-i64:64-v128:32:128-n32-S128".to_string(), arch: "wasm32".to_string(), + linker_flavor: LinkerFlavor::Em, options: opts, }) } diff --git a/src/librustc_back/target/windows_base.rs b/src/librustc_back/target/windows_base.rs index db02e142fcc..9bde24a28dd 100644 --- a/src/librustc_back/target/windows_base.rs +++ b/src/librustc_back/target/windows_base.rs @@ -8,26 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use target::TargetOptions; +use LinkerFlavor; +use target::{LinkArgs, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { - TargetOptions { - // FIXME(#13846) this should be enabled for windows - function_sections: false, - linker: "gcc".to_string(), - dynamic_linking: true, - executables: true, - dll_prefix: "".to_string(), - dll_suffix: ".dll".to_string(), - exe_suffix: ".exe".to_string(), - staticlib_prefix: "".to_string(), - staticlib_suffix: ".lib".to_string(), - no_default_libraries: true, - target_family: Some("windows".to_string()), - is_like_windows: true, - allows_weak_linkage: false, - pre_link_args: vec![ + let mut pre_link_args = LinkArgs::new(); + pre_link_args.insert(LinkerFlavor::Gcc, vec![ // And here, we see obscure linker flags #45. On windows, it has been // found to be necessary to have this flag to compile liblibc. // @@ -64,7 +51,34 @@ pub fn opts() -> TargetOptions { // Do not use the standard system startup files or libraries when linking "-nostdlib".to_string(), - ], + ]); + + let mut late_link_args = LinkArgs::new(); + late_link_args.insert(LinkerFlavor::Gcc, vec![ + "-lmingwex".to_string(), + "-lmingw32".to_string(), + "-lgcc".to_string(), // alas, mingw* libraries above depend on libgcc + "-lmsvcrt".to_string(), + "-luser32".to_string(), + "-lkernel32".to_string(), + ]); + + TargetOptions { + // FIXME(#13846) this should be enabled for windows + function_sections: false, + linker: "gcc".to_string(), + dynamic_linking: true, + executables: true, + dll_prefix: "".to_string(), + dll_suffix: ".dll".to_string(), + exe_suffix: ".exe".to_string(), + staticlib_prefix: "".to_string(), + staticlib_suffix: ".lib".to_string(), + no_default_libraries: true, + target_family: Some("windows".to_string()), + is_like_windows: true, + allows_weak_linkage: false, + pre_link_args: pre_link_args, pre_link_objects_exe: vec![ "crt2.o".to_string(), // mingw C runtime initialization for executables "rsbegin.o".to_string(), // Rust compiler runtime initialization, see rsbegin.rs @@ -73,14 +87,7 @@ pub fn opts() -> TargetOptions { "dllcrt2.o".to_string(), // mingw C runtime initialization for dlls "rsbegin.o".to_string(), ], - late_link_args: vec![ - "-lmingwex".to_string(), - "-lmingw32".to_string(), - "-lgcc".to_string(), // alas, mingw* libraries above depend on libgcc - "-lmsvcrt".to_string(), - "-luser32".to_string(), - "-lkernel32".to_string(), - ], + late_link_args: late_link_args, post_link_objects: vec![ "rsend.o".to_string() ], diff --git a/src/librustc_back/target/windows_msvc_base.rs b/src/librustc_back/target/windows_msvc_base.rs index efa215b419d..421f59aea93 100644 --- a/src/librustc_back/target/windows_msvc_base.rs +++ b/src/librustc_back/target/windows_msvc_base.rs @@ -8,10 +8,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use target::TargetOptions; +use LinkerFlavor; +use target::{LinkArgs, TargetOptions}; use std::default::Default; pub fn opts() -> TargetOptions { + let mut args = LinkArgs::new(); + args.insert(LinkerFlavor::Msvc, + vec!["/NOLOGO".to_string(), + "/NXCOMPAT".to_string()]); + TargetOptions { function_sections: true, linker: "link.exe".to_string(), @@ -56,10 +62,7 @@ pub fn opts() -> TargetOptions { target_family: Some("windows".to_string()), is_like_windows: true, is_like_msvc: true, - pre_link_args: vec![ - "/NOLOGO".to_string(), - "/NXCOMPAT".to_string(), - ], + pre_link_args: args, exe_allocation_crate: "alloc_system".to_string(), .. Default::default() diff --git a/src/librustc_back/target/x86_64_apple_darwin.rs b/src/librustc_back/target/x86_64_apple_darwin.rs index b3c1561dbcc..8fd1b80430f 100644 --- a/src/librustc_back/target/x86_64_apple_darwin.rs +++ b/src/librustc_back/target/x86_64_apple_darwin.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { @@ -15,7 +16,7 @@ pub fn target() -> TargetResult { base.cpu = "core2".to_string(); base.max_atomic_width = Some(128); // core2 support cmpxchg16b base.eliminate_frame_pointer = false; - base.pre_link_args.push("-m64".to_string()); + base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]); Ok(Target { llvm_target: "x86_64-apple-darwin".to_string(), @@ -26,6 +27,7 @@ pub fn target() -> TargetResult { target_os: "macos".to_string(), target_env: "".to_string(), target_vendor: "apple".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/x86_64_apple_ios.rs b/src/librustc_back/target/x86_64_apple_ios.rs index 7a58bb34ce7..bbd81fd86ff 100644 --- a/src/librustc_back/target/x86_64_apple_ios.rs +++ b/src/librustc_back/target/x86_64_apple_ios.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetOptions, TargetResult}; use super::apple_ios_base::{opts, Arch}; @@ -22,6 +23,7 @@ pub fn target() -> TargetResult { target_os: "ios".to_string(), target_env: "".to_string(), target_vendor: "apple".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: TargetOptions { max_atomic_width: Some(64), .. base diff --git a/src/librustc_back/target/x86_64_pc_windows_gnu.rs b/src/librustc_back/target/x86_64_pc_windows_gnu.rs index 321585cd65e..10e88d88ee3 100644 --- a/src/librustc_back/target/x86_64_pc_windows_gnu.rs +++ b/src/librustc_back/target/x86_64_pc_windows_gnu.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::windows_base::opts(); base.cpu = "x86-64".to_string(); - base.pre_link_args.push("-m64".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); base.max_atomic_width = Some(64); Ok(Target { @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "windows".to_string(), target_env: "gnu".to_string(), target_vendor: "pc".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/x86_64_pc_windows_msvc.rs b/src/librustc_back/target/x86_64_pc_windows_msvc.rs index ea8909d213e..b07031c4bf1 100644 --- a/src/librustc_back/target/x86_64_pc_windows_msvc.rs +++ b/src/librustc_back/target/x86_64_pc_windows_msvc.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { @@ -24,6 +25,7 @@ pub fn target() -> TargetResult { target_os: "windows".to_string(), target_env: "msvc".to_string(), target_vendor: "pc".to_string(), + linker_flavor: LinkerFlavor::Msvc, options: base, }) } diff --git a/src/librustc_back/target/x86_64_rumprun_netbsd.rs b/src/librustc_back/target/x86_64_rumprun_netbsd.rs index 33137214396..eea4389cfd6 100644 --- a/src/librustc_back/target/x86_64_rumprun_netbsd.rs +++ b/src/librustc_back/target/x86_64_rumprun_netbsd.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); base.cpu = "x86-64".to_string(); - base.pre_link_args.push("-m64".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); base.linker = "x86_64-rumprun-netbsd-gcc".to_string(); base.ar = "x86_64-rumprun-netbsd-ar".to_string(); base.max_atomic_width = Some(64); @@ -34,6 +35,7 @@ pub fn target() -> TargetResult { target_os: "netbsd".to_string(), target_env: "".to_string(), target_vendor: "rumprun".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/x86_64_sun_solaris.rs b/src/librustc_back/target/x86_64_sun_solaris.rs index 8e4fd94e7bc..fe8691f3695 100644 --- a/src/librustc_back/target/x86_64_sun_solaris.rs +++ b/src/librustc_back/target/x86_64_sun_solaris.rs @@ -8,11 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::solaris_base::opts(); - base.pre_link_args.push("-m64".to_string()); + base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "solaris".to_string(), target_env: "".to_string(), target_vendor: "sun".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/x86_64_unknown_bitrig.rs b/src/librustc_back/target/x86_64_unknown_bitrig.rs index eda16c29466..5f87fe177a9 100644 --- a/src/librustc_back/target/x86_64_unknown_bitrig.rs +++ b/src/librustc_back/target/x86_64_unknown_bitrig.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::bitrig_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.push("-m64".to_string()); + base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]); Ok(Target { llvm_target: "x86_64-unknown-bitrig".to_string(), @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "bitrig".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/x86_64_unknown_dragonfly.rs b/src/librustc_back/target/x86_64_unknown_dragonfly.rs index 194efb8fc23..96f608409ff 100644 --- a/src/librustc_back/target/x86_64_unknown_dragonfly.rs +++ b/src/librustc_back/target/x86_64_unknown_dragonfly.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::dragonfly_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.push("-m64".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); Ok(Target { llvm_target: "x86_64-unknown-dragonfly".to_string(), @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "dragonfly".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/x86_64_unknown_freebsd.rs b/src/librustc_back/target/x86_64_unknown_freebsd.rs index b127bee163b..500629a1680 100644 --- a/src/librustc_back/target/x86_64_unknown_freebsd.rs +++ b/src/librustc_back/target/x86_64_unknown_freebsd.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::freebsd_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.push("-m64".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); Ok(Target { llvm_target: "x86_64-unknown-freebsd".to_string(), @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "freebsd".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/x86_64_unknown_fuchsia.rs b/src/librustc_back/target/x86_64_unknown_fuchsia.rs index 08fe17a556e..6e37896d414 100644 --- a/src/librustc_back/target/x86_64_unknown_fuchsia.rs +++ b/src/librustc_back/target/x86_64_unknown_fuchsia.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::fuchsia_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.push("-m64".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); Ok(Target { llvm_target: "x86_64-unknown-fuchsia".to_string(), @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "fuchsia".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/x86_64_unknown_haiku.rs b/src/librustc_back/target/x86_64_unknown_haiku.rs index 7cf0599037c..7fab9128b29 100644 --- a/src/librustc_back/target/x86_64_unknown_haiku.rs +++ b/src/librustc_back/target/x86_64_unknown_haiku.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::haiku_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.push("-m64".to_string()); + base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string()]); Ok(Target { llvm_target: "x86_64-unknown-haiku".to_string(), @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "haiku".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/x86_64_unknown_linux_gnu.rs b/src/librustc_back/target/x86_64_unknown_linux_gnu.rs index f95bcb556e5..f73055cebaa 100644 --- a/src/librustc_back/target/x86_64_unknown_linux_gnu.rs +++ b/src/librustc_back/target/x86_64_unknown_linux_gnu.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.push("-m64".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); Ok(Target { llvm_target: "x86_64-unknown-linux-gnu".to_string(), @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "gnu".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/x86_64_unknown_linux_musl.rs b/src/librustc_back/target/x86_64_unknown_linux_musl.rs index c3bf9dcca6e..38b9c0bace5 100644 --- a/src/librustc_back/target/x86_64_unknown_linux_musl.rs +++ b/src/librustc_back/target/x86_64_unknown_linux_musl.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::linux_musl_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.push("-m64".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); Ok(Target { llvm_target: "x86_64-unknown-linux-musl".to_string(), @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "linux".to_string(), target_env: "musl".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/x86_64_unknown_netbsd.rs b/src/librustc_back/target/x86_64_unknown_netbsd.rs index 87a7c184644..6fe2e3fc08e 100644 --- a/src/librustc_back/target/x86_64_unknown_netbsd.rs +++ b/src/librustc_back/target/x86_64_unknown_netbsd.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::netbsd_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.push("-m64".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); Ok(Target { llvm_target: "x86_64-unknown-netbsd".to_string(), @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "netbsd".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/x86_64_unknown_openbsd.rs b/src/librustc_back/target/x86_64_unknown_openbsd.rs index e9d645b0d38..b292b5fc1e4 100644 --- a/src/librustc_back/target/x86_64_unknown_openbsd.rs +++ b/src/librustc_back/target/x86_64_unknown_openbsd.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::openbsd_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.push("-m64".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); Ok(Target { llvm_target: "x86_64-unknown-openbsd".to_string(), @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "openbsd".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } diff --git a/src/librustc_back/target/x86_64_unknown_redox.rs b/src/librustc_back/target/x86_64_unknown_redox.rs index cecac06b235..a693e76099b 100644 --- a/src/librustc_back/target/x86_64_unknown_redox.rs +++ b/src/librustc_back/target/x86_64_unknown_redox.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use LinkerFlavor; use target::{Target, TargetResult}; pub fn target() -> TargetResult { let mut base = super::redox_base::opts(); base.cpu = "x86-64".to_string(); base.max_atomic_width = Some(64); - base.pre_link_args.push("-m64".to_string()); + base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string()); Ok(Target { llvm_target: "x86_64-unknown-redox".to_string(), @@ -25,6 +26,7 @@ pub fn target() -> TargetResult { target_os: "redox".to_string(), target_env: "".to_string(), target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, options: base, }) } |
