use session::{early_error, early_warn, Session};
use session::search_paths::SearchPaths;
-use rustc_back::PanicStrategy;
+use rustc_back::{LinkerFlavor, PanicStrategy};
use rustc_back::target::Target;
use lint;
use middle::cstore;
Some("either `panic` or `abort`");
pub const parse_sanitizer: Option<&'static str> =
Some("one of: `address`, `leak`, `memory` or `thread`");
+ pub const parse_linker_flavor: Option<&'static str> =
+ Some(::rustc_back::LinkerFlavor::one_of());
}
#[allow(dead_code)]
mod $mod_set {
use super::{$struct_name, Passes, SomePasses, AllPasses, Sanitizer};
- use rustc_back::PanicStrategy;
+ use rustc_back::{LinkerFlavor, PanicStrategy};
$(
pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool {
}
true
}
+
+ fn parse_linker_flavor(slote: &mut Option<LinkerFlavor>, v: Option<&str>) -> bool {
+ match v.and_then(LinkerFlavor::from_str) {
+ Some(lf) => *slote = Some(lf),
+ _ => return false,
+ }
+ true
+ }
}
) }
"pass `-install_name @rpath/...` to the macOS linker"),
sanitizer: Option<Sanitizer> = (None, parse_sanitizer, [TRACKED],
"Use a sanitizer"),
+ linker_flavor: Option<LinkerFlavor> = (None, parse_linker_flavor, [UNTRACKED],
+ "Linker flavor"),
}
pub fn default_lib_output() -> CrateType {
use syntax::feature_gate::AttributeType;
use syntax_pos::{Span, MultiSpan};
-use rustc_back::PanicStrategy;
+use rustc_back::{LinkerFlavor, PanicStrategy};
use rustc_back::target::Target;
use rustc_data_structures::flock;
use llvm;
pub fn panic_strategy(&self) -> PanicStrategy {
self.opts.cg.panic.unwrap_or(self.target.target.options.panic_strategy)
}
+ pub fn linker_flavor(&self) -> LinkerFlavor {
+ self.opts.debugging_opts.linker_flavor.unwrap_or(self.target.target.linker_flavor)
+ }
pub fn no_landing_pads(&self) -> bool {
self.opts.debugging_opts.no_landing_pads || self.panic_strategy() == PanicStrategy::Abort
}
use serialize::json::{Json, ToJson};
+macro_rules! linker_flavor {
+ ($(($variant:ident, $string:expr),)+) => {
+ #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Hash,
+ RustcEncodable, RustcDecodable)]
+ pub enum LinkerFlavor {
+ $($variant,)+
+ }
+
+ impl LinkerFlavor {
+ pub const fn one_of() -> &'static str {
+ concat!("one of: ", $($string, " ",)+)
+ }
+
+ pub fn from_str(s: &str) -> Option<Self> {
+ Some(match s {
+ $($string => LinkerFlavor::$variant,)+
+ _ => return None,
+ })
+ }
+
+ pub fn desc(&self) -> &str {
+ match *self {
+ $(LinkerFlavor::$variant => $string,)+
+ }
+ }
+ }
+
+ impl ToJson for LinkerFlavor {
+ fn to_json(&self) -> Json {
+ self.desc().to_json()
+ }
+ }
+ }
+}
+
+linker_flavor! {
+ (Em, "em"),
+ (Gcc, "gcc"),
+ (Ld, "ld"),
+ (Msvc, "msvc"),
+}
+
#[derive(Clone, Copy, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
pub enum PanicStrategy {
Unwind,
// 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};
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,
// 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
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
// 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 {
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
// 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 {
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
// 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 {
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
// 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;
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
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()
// 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::*;
}
}
-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"
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 {
// 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 {
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
// 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 {
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(),
// 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 {
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(),
// 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 {
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
// 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 {
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
// 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 {
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(),
}
})
}
-
// 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};
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),
// 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
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
// 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 {
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
}
})
}
-
// 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 {
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
// 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};
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),
// 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"),
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()
};
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,
})
}
// 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()
// 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()
// 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,
// 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};
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
// 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(),
target_os: "macos".to_string(),
target_env: "".to_string(),
target_vendor: "apple".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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
target_os: "android".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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 {
// 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(),
target_os: "windows".to_string(),
target_env: "gnu".to_string(),
target_vendor: "pc".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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 {
// 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(),
target_os: "windows".to_string(),
target_env: "msvc".to_string(),
target_vendor: "pc".to_string(),
+ linker_flavor: LinkerFlavor::Msvc,
options: base,
})
}
// 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(),
target_os: "dragonfly".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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(),
target_os: "freebsd".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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(),
target_os: "haiku".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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(),
target_os: "linux".to_string(),
target_env: "gnu".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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.
target_os: "linux".to_string(),
target_env: "musl".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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(),
target_os: "netbsd".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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(),
target_os: "openbsd".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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(),
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,
})
}
// 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,
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+use LinkerFlavor;
use target::TargetOptions;
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
// 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
// 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 {
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(),
// 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 {
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(),
// 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 {
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(),
// 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 {
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(),
// 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 {
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(),
// 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 {
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(),
// 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 {
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(),
// 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 {
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(),
use std::io::prelude::*;
use syntax::abi::{Abi, lookup as lookup_abi};
-use PanicStrategy;
+use {LinkerFlavor, PanicStrategy};
mod android_base;
mod apple_base;
mod fuchsia_base;
mod redox_base;
+pub type LinkArgs = BTreeMap<LinkerFlavor, Vec<String>>;
pub type TargetResult = Result<Target, String>;
macro_rules! supported_targets {
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,
}
/// 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
/// 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>,
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(),
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(),
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(),
};
.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);
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);
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);
// 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()
}
// 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,
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()
// 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
target_os: "linux".to_string(),
target_env: "gnu".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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
target_os: "linux".to_string(),
target_env: "gnu".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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
target_os: "linux".to_string(),
target_env: "gnu".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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,
// 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 {
target_os: "linux".to_string(),
target_env: "gnu".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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 {
target_os: "linux".to_string(),
target_env: "gnu".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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 {
target_os: "netbsd".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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);
target_os: "solaris".to_string(),
target_env: "".to_string(),
target_vendor: "sun".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// Targets the Cortex-M0, Cortex-M0+ and Cortex-M1 processors (ARMv6-M architecture)
+use LinkerFlavor;
use target::{Target, TargetOptions, TargetResult};
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
// 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 {
target_os: "none".to_string(),
target_env: "".to_string(),
target_vendor: "".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: TargetOptions {
max_atomic_width: Some(32),
//
// 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 {
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
// Targets the Cortex-M3 processor (ARMv7-M)
+use LinkerFlavor;
use target::{Target, TargetOptions, TargetResult};
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),
// 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"),
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()
};
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,
})
}
// 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.
//
// 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
"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()
],
// 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(),
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()
// 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 {
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(),
target_os: "macos".to_string(),
target_env: "".to_string(),
target_vendor: "apple".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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};
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
// 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 {
target_os: "windows".to_string(),
target_env: "gnu".to_string(),
target_vendor: "pc".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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 {
target_os: "windows".to_string(),
target_env: "msvc".to_string(),
target_vendor: "pc".to_string(),
+ linker_flavor: LinkerFlavor::Msvc,
options: base,
})
}
// 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);
target_os: "netbsd".to_string(),
target_env: "".to_string(),
target_vendor: "rumprun".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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);
target_os: "solaris".to_string(),
target_env: "".to_string(),
target_vendor: "sun".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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(),
target_os: "bitrig".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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(),
target_os: "dragonfly".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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(),
target_os: "freebsd".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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(),
target_os: "fuchsia".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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(),
target_os: "haiku".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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(),
target_os: "linux".to_string(),
target_env: "gnu".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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(),
target_os: "linux".to_string(),
target_env: "musl".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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(),
target_os: "netbsd".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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(),
target_os: "openbsd".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
// 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(),
target_os: "redox".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
+ linker_flavor: LinkerFlavor::Gcc,
options: base,
})
}
}
}
}
+#[link(name = "ffi")] extern {}
outputs: &OutputFilenames,
tmpdir: &Path) {
info!("preparing {:?} from {:?} to {:?}", crate_type, objects, out_filename);
+ let flavor = sess.linker_flavor();
// The invocations of cc share some flags across platforms
let (pname, mut cmd, extra) = get_linker(sess);
cmd.env("PATH", command_path(sess, extra));
let root = sess.target_filesearch(PathKind::Native).get_lib_path();
- cmd.args(&sess.target.target.options.pre_link_args);
+ if let Some(args) = sess.target.target.options.pre_link_args.get(&flavor) {
+ cmd.args(args);
+ }
let pre_link_objects = if crate_type == config::CrateTypeExecutable {
&sess.target.target.options.pre_link_objects_exe
objects, out_filename, outputs, trans);
cmd = linker.finalize();
}
- cmd.args(&sess.target.target.options.late_link_args);
+ if let Some(args) = sess.target.target.options.late_link_args.get(&flavor) {
+ cmd.args(args);
+ }
for obj in &sess.target.target.options.post_link_objects {
cmd.arg(root.join(obj));
}
- cmd.args(&sess.target.target.options.post_link_args);
+ if let Some(args) = sess.target.target.options.post_link_args.get(&flavor) {
+ cmd.args(args);
+ }
if sess.opts.debugging_opts.print_link_args {
println!("{:?}", &cmd);
// except according to those terms.
use std::collections::HashMap;
-use std::ffi::OsString;
+use std::ffi::{OsStr, OsString};
use std::fs::{self, File};
use std::io::prelude::*;
use std::io::{self, BufWriter};
use back::symbol_export::{self, ExportedSymbols};
use middle::dependency_format::Linkage;
use rustc::hir::def_id::{LOCAL_CRATE, CrateNum};
+use rustc_back::LinkerFlavor;
use session::Session;
use session::config::{self, CrateType, OptLevel, DebugInfoLevel};
use serialize::{json, Encoder};
pub fn to_linker(&'a self,
cmd: Command,
sess: &'a Session) -> Box<Linker+'a> {
- if sess.target.target.options.is_like_msvc {
- Box::new(MsvcLinker {
- cmd: cmd,
- sess: sess,
- info: self
- }) as Box<Linker>
- } else if sess.target.target.options.is_like_emscripten {
- Box::new(EmLinker {
- cmd: cmd,
- sess: sess,
- info: self
- }) as Box<Linker>
- } else {
- Box::new(GnuLinker {
- cmd: cmd,
- sess: sess,
- info: self,
- hinted_static: false,
- }) as Box<Linker>
+ match sess.linker_flavor() {
+ LinkerFlavor::Msvc => {
+ Box::new(MsvcLinker {
+ cmd: cmd,
+ sess: sess,
+ info: self
+ }) as Box<Linker>
+ }
+ LinkerFlavor::Em => {
+ Box::new(EmLinker {
+ cmd: cmd,
+ sess: sess,
+ info: self
+ }) as Box<Linker>
+ }
+ LinkerFlavor::Gcc => {
+ Box::new(GccLinker {
+ cmd: cmd,
+ sess: sess,
+ info: self,
+ hinted_static: false,
+ is_ld: false,
+ }) as Box<Linker>
+ }
+ LinkerFlavor::Ld => {
+ Box::new(GccLinker {
+ cmd: cmd,
+ sess: sess,
+ info: self,
+ hinted_static: false,
+ is_ld: true,
+ }) as Box<Linker>
+ }
}
}
}
fn finalize(&mut self) -> Command;
}
-pub struct GnuLinker<'a> {
+pub struct GccLinker<'a> {
cmd: Command,
sess: &'a Session,
info: &'a LinkerInfo,
hinted_static: bool, // Keeps track of the current hinting mode.
+ // Link as ld
+ is_ld: bool,
}
-impl<'a> GnuLinker<'a> {
+impl<'a> GccLinker<'a> {
+ /// Argument that must be passed *directly* to the linker
+ ///
+ /// These arguments need to be prepended with '-Wl,' when a gcc-style linker is used
+ fn linker_arg<S>(&mut self, arg: S) -> &mut Self
+ where S: AsRef<OsStr>
+ {
+ if !self.is_ld {
+ let mut os = OsString::from("-Wl,");
+ os.push(arg.as_ref());
+ self.cmd.arg(os);
+ } else {
+ self.cmd.arg(arg);
+ }
+ self
+ }
+
fn takes_hints(&self) -> bool {
!self.sess.target.target.options.is_like_osx
}
fn hint_static(&mut self) {
if !self.takes_hints() { return }
if !self.hinted_static {
- self.cmd.arg("-Wl,-Bstatic");
+ self.linker_arg("-Bstatic");
self.hinted_static = true;
}
}
fn hint_dynamic(&mut self) {
if !self.takes_hints() { return }
if self.hinted_static {
- self.cmd.arg("-Wl,-Bdynamic");
+ self.linker_arg("-Bdynamic");
self.hinted_static = false;
}
}
}
-impl<'a> Linker for GnuLinker<'a> {
+impl<'a> Linker for GccLinker<'a> {
fn link_dylib(&mut self, lib: &str) { self.hint_dynamic(); self.cmd.arg("-l").arg(lib); }
fn link_staticlib(&mut self, lib: &str) { self.hint_static(); self.cmd.arg("-l").arg(lib); }
fn link_rlib(&mut self, lib: &Path) { self.hint_static(); self.cmd.arg(lib); }
self.hint_static();
let target = &self.sess.target.target;
if !target.options.is_like_osx {
- self.cmd.arg("-Wl,--whole-archive")
- .arg("-l").arg(lib)
- .arg("-Wl,--no-whole-archive");
+ self.linker_arg("--whole-archive").cmd.arg("-l").arg(lib);
+ self.linker_arg("--no-whole-archive");
} else {
// -force_load is the macOS equivalent of --whole-archive, but it
// involves passing the full path to the library to link.
- let mut v = OsString::from("-Wl,-force_load,");
+ let mut v = OsString::from("-force_load,");
v.push(&archive::find_library(lib, search_path, &self.sess));
- self.cmd.arg(&v);
+ self.linker_arg(&v);
}
}
fn link_whole_rlib(&mut self, lib: &Path) {
self.hint_static();
if self.sess.target.target.options.is_like_osx {
- let mut v = OsString::from("-Wl,-force_load,");
+ let mut v = OsString::from("-force_load,");
v.push(lib);
- self.cmd.arg(&v);
+ self.linker_arg(&v);
} else {
- self.cmd.arg("-Wl,--whole-archive").arg(lib)
- .arg("-Wl,--no-whole-archive");
+ self.linker_arg("--whole-archive").cmd.arg(lib);
+ self.linker_arg("--no-whole-archive");
}
}
// for partial linking when using multiple codegen units (-r). So we
// insert it here.
if self.sess.target.target.options.is_like_osx {
- self.cmd.arg("-Wl,-dead_strip");
+ self.linker_arg("-dead_strip");
} else if self.sess.target.target.options.is_like_solaris {
- self.cmd.arg("-Wl,-z");
- self.cmd.arg("-Wl,ignore");
+ self.linker_arg("-z");
+ self.linker_arg("ignore");
// If we're building a dylib, we don't use --gc-sections because LLVM
// has already done the best it can do, and we also don't want to
// --gc-sections drops the size of hello world from 1.8MB to 597K, a 67%
// reduction.
} else if !keep_metadata {
- self.cmd.arg("-Wl,--gc-sections");
+ self.linker_arg("--gc-sections");
}
}
// need a numeric argument, but other linkers do.
if self.sess.opts.optimize == config::OptLevel::Default ||
self.sess.opts.optimize == config::OptLevel::Aggressive {
- self.cmd.arg("-Wl,-O1");
+ self.linker_arg("-O1");
}
}
}
fn no_default_libraries(&mut self) {
- self.cmd.arg("-nodefaultlibs");
+ if !self.is_ld {
+ self.cmd.arg("-nodefaultlibs");
+ }
}
fn build_dylib(&mut self, out_filename: &Path) {
// On mac we need to tell the linker to let this library be rpathed
if self.sess.target.target.options.is_like_osx {
- self.cmd.args(&["-dynamiclib", "-Wl,-dylib"]);
+ self.cmd.arg("-dynamiclib");
+ self.linker_arg("-dylib");
// Note that the `osx_rpath_install_name` option here is a hack
// purely to support rustbuild right now, we should get a more
// the right `-Wl,-install_name` with an `@rpath` in it.
if self.sess.opts.cg.rpath ||
self.sess.opts.debugging_opts.osx_rpath_install_name {
- let mut v = OsString::from("-Wl,-install_name,@rpath/");
+ let mut v = OsString::from("-install_name,@rpath/");
v.push(out_filename.file_name().unwrap());
- self.cmd.arg(&v);
+ self.linker_arg(&v);
}
} else {
self.cmd.arg("-shared");
}
if self.sess.target.target.options.is_like_osx {
- arg.push("-Wl,-exported_symbols_list,");
+ if !self.is_ld {
+ arg.push("-Wl,")
+ }
+ arg.push("-exported_symbols_list,");
} else if self.sess.target.target.options.is_like_solaris {
- arg.push("-Wl,-M,");
+ if !self.is_ld {
+ arg.push("-Wl,")
+ }
+ arg.push("-M,");
} else {
- arg.push("-Wl,--version-script=");
+ if !self.is_ld {
+ arg.push("-Wl,")
+ }
+ arg.push("--version-script=");
}
arg.push(&path);
}
fn subsystem(&mut self, subsystem: &str) {
- self.cmd.arg(&format!("-Wl,--subsystem,{}", subsystem));
+ self.cmd.arg(&format!("--subsystem,{}", subsystem));
}
fn finalize(&mut self) -> Command {
{
"data-layout": "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128",
+ "linker-flavor": "gcc",
"llvm-target": "i686-unknown-linux-gnu",
"target-endian": "little",
"target-pointer-width": "32",
{
"data-layout": "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32",
+ "linker-flavor": "gcc",
"target-endian": "little",
"target-pointer-width": "32",
"arch": "x86",
{
"pre-link-args": ["-m64"],
"data-layout": "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128",
+ "linker-flavor": "gcc",
"llvm-target": "x86_64-unknown-linux-gnu",
"target-endian": "little",
"target-pointer-width": "64",