Skip to content

Commit

Permalink
rustc: Tweak default linker selection
Browse files Browse the repository at this point in the history
This commit refactors how the path to the linker that we're going to invoke is
selected. Previously all targets listed *both* a `LinkerFlavor` and a `linker`
(path) option, but this meant that whenever you changed one you had to change
the other. The purpose of this commit is to avoid coupling these where possible.

Target specifications now only unconditionally define the *flavor* of the linker
that they're using by default. If not otherwise specified each flavor now
implies a particular default linker to run. As a result, this means that if
you'd like to test out `ld` for example you should be able to do:

    rustc -Z linker-flavor=ld foo.rs

whereas previously you had to do

    rustc -Z linker-flavor=ld -C linker=ld foo.rs

This will hopefully make it a bit easier to tinker around with variants that
should otherwise be well known to work, for example with LLD, `ld` on OSX, etc.
  • Loading branch information
alexcrichton committed Mar 4, 2018
1 parent d69b248 commit 0129b01
Show file tree
Hide file tree
Showing 26 changed files with 83 additions and 118 deletions.
6 changes: 4 additions & 2 deletions src/bootstrap/dist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -606,8 +606,10 @@ impl Step for Std {
let mut src = builder.sysroot_libdir(compiler, target).to_path_buf();
src.pop(); // Remove the trailing /lib folder from the sysroot_libdir
cp_filtered(&src, &dst, &|path| {
path.file_name().and_then(|s| s.to_str()) !=
Some(build.config.rust_codegen_backends_dir.as_str())
let name = path.file_name().and_then(|s| s.to_str());
name != Some(build.config.rust_codegen_backends_dir.as_str()) &&
name != Some("bin")

});

let mut cmd = rust_installer(builder);
Expand Down
13 changes: 8 additions & 5 deletions src/bootstrap/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ impl Step for Llvm {
cfg.define("LLVM_NATIVE_BUILD", build.llvm_out(build.build).join("build"));
}

configure_cmake(build, target, &mut cfg);
configure_cmake(build, target, &mut cfg, false);

// FIXME: we don't actually need to build all LLVM tools and all LLVM
// libraries here, e.g. we just want a few components and a few
Expand Down Expand Up @@ -241,7 +241,8 @@ fn check_llvm_version(build: &Build, llvm_config: &Path) {

fn configure_cmake(build: &Build,
target: Interned<String>,
cfg: &mut cmake::Config) {
cfg: &mut cmake::Config,
building_dist_binaries: bool) {
if build.config.ninja {
cfg.generator("Ninja");
}
Expand Down Expand Up @@ -294,8 +295,10 @@ fn configure_cmake(build: &Build,
cfg.build_arg("-j").build_arg(build.jobs().to_string());
cfg.define("CMAKE_C_FLAGS", build.cflags(target).join(" "));
let mut cxxflags = build.cflags(target).join(" ");
if build.config.llvm_static_stdcpp && !target.contains("windows") {
cxxflags.push_str(" -static-libstdc++");
if building_dist_binaries {
if build.config.llvm_static_stdcpp && !target.contains("windows") {
cxxflags.push_str(" -static-libstdc++");
}
}
cfg.define("CMAKE_CXX_FLAGS", cxxflags);
if let Some(ar) = build.ar(target) {
Expand Down Expand Up @@ -350,7 +353,7 @@ impl Step for Lld {
t!(fs::create_dir_all(&out_dir));

let mut cfg = cmake::Config::new(build.src.join("src/tools/lld"));
configure_cmake(build, target, &mut cfg);
configure_cmake(build, target, &mut cfg, true);

cfg.out_dir(&out_dir)
.profile("Release")
Expand Down
6 changes: 6 additions & 0 deletions src/librustc_back/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ pub enum LinkerFlavor {
RustcEncodable, RustcDecodable)]
pub enum LldFlavor {
Wasm,
Ld64,
Ld,
Link,
}

impl ToJson for LinkerFlavor {
Expand Down Expand Up @@ -94,6 +97,9 @@ flavor_mappings! {
((LinkerFlavor::Ld), "ld"),
((LinkerFlavor::Msvc), "msvc"),
((LinkerFlavor::Lld(LldFlavor::Wasm)), "wasm-ld"),
((LinkerFlavor::Lld(LldFlavor::Ld64)), "ld64.lld"),
((LinkerFlavor::Lld(LldFlavor::Ld)), "ld.lld"),
((LinkerFlavor::Lld(LldFlavor::Link)), "lld-link"),
}

#[derive(Clone, Copy, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_back/target/aarch64_unknown_cloudabi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn target() -> TargetResult {
let mut base = super::cloudabi_base::opts();
base.max_atomic_width = Some(128);
base.abi_blacklist = super::arm_base::abi_blacklist();
base.linker = "aarch64-unknown-cloudabi-cc".to_string();
base.linker = Some("aarch64-unknown-cloudabi-cc".to_string());

Ok(Target {
llvm_target: "aarch64-unknown-cloudabi".to_string(),
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_back/target/armv7_unknown_cloudabi_eabihf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ pub fn target() -> TargetResult {
base.max_atomic_width = Some(64);
base.features = "+v7,+vfp3,+neon".to_string();
base.abi_blacklist = super::arm_base::abi_blacklist();
base.linker = "armv7-unknown-cloudabi-eabihf-cc".to_string();
base.linker = Some("armv7-unknown-cloudabi-eabihf-cc".to_string());

Ok(Target {
llvm_target: "armv7-unknown-cloudabi-eabihf".to_string(),
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_back/target/asmjs_unknown_emscripten.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

use LinkerFlavor;
use super::{LinkArgs, Target, TargetOptions};
use super::emscripten_base::{cmd};

pub fn target() -> Result<Target, String> {
let mut args = LinkArgs::new();
Expand All @@ -19,8 +18,6 @@ pub fn target() -> Result<Target, String> {
"ERROR_ON_UNDEFINED_SYMBOLS=1".to_string()]);

let opts = TargetOptions {
linker: cmd("emcc"),

dynamic_linking: false,
executables: true,
exe_suffix: ".js".to_string(),
Expand Down
17 changes: 0 additions & 17 deletions src/librustc_back/target/emscripten_base.rs

This file was deleted.

1 change: 0 additions & 1 deletion src/librustc_back/target/haiku_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use std::default::Default;

pub fn opts() -> TargetOptions {
TargetOptions {
linker: "cc".to_string(),
dynamic_linking: true,
executables: true,
has_rpath: false,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_back/target/i686_unknown_cloudabi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn target() -> TargetResult {
let mut base = super::cloudabi_base::opts();
base.cpu = "pentium4".to_string();
base.max_atomic_width = Some(64);
base.linker = "i686-unknown-cloudabi-cc".to_string();
base.linker = Some("i686-unknown-cloudabi-cc".to_string());
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m32".to_string());
base.stack_probes = true;

Expand Down
1 change: 0 additions & 1 deletion src/librustc_back/target/l4re_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ pub fn opts() -> Result<TargetOptions, String> {
has_elf_tls: false,
exe_allocation_crate: None,
panic_strategy: PanicStrategy::Abort,
linker: "ld".to_string(),
pre_link_args,
post_link_args,
target_family: Some("unix".to_string()),
Expand Down
9 changes: 4 additions & 5 deletions src/librustc_back/target/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ mod arm_base;
mod bitrig_base;
mod cloudabi_base;
mod dragonfly_base;
mod emscripten_base;
mod freebsd_base;
mod haiku_base;
mod linux_base;
Expand Down Expand Up @@ -279,8 +278,8 @@ pub struct TargetOptions {
/// Whether the target is built-in or loaded from a custom target specification.
pub is_builtin: bool,

/// Linker to invoke. Defaults to "cc".
pub linker: String,
/// Linker to invoke
pub linker: Option<String>,

/// Linker arguments that are unconditionally passed *before* any
/// user-defined libraries.
Expand Down Expand Up @@ -482,7 +481,7 @@ impl Default for TargetOptions {
fn default() -> TargetOptions {
TargetOptions {
is_builtin: false,
linker: option_env!("CFG_DEFAULT_LINKER").unwrap_or("cc").to_string(),
linker: option_env!("CFG_DEFAULT_LINKER").map(|s| s.to_string()),
pre_link_args: LinkArgs::new(),
post_link_args: LinkArgs::new(),
asm_args: Vec::new(),
Expand Down Expand Up @@ -732,7 +731,7 @@ impl Target {
}

key!(is_builtin, bool);
key!(linker);
key!(linker, optional);
key!(pre_link_args, link_args);
key!(pre_link_objects_exe, list);
key!(pre_link_objects_dll, list);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_back/target/msp430_none_elf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub fn target() -> TargetResult {
// to gcc to get object files. For this reason we have a hard
// dependency on this specific gcc.
asm_args: vec!["-mcpu=msp430".to_string()],
linker: "msp430-elf-gcc".to_string(),
linker: Some("msp430-elf-gcc".to_string()),
no_integrated_as: true,

// There are no atomic instructions available in the MSP430
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_back/target/thumb_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub fn opts() -> TargetOptions {
executables: true,
// In 99%+ of cases, we want to use the `arm-none-eabi-gcc` compiler (there aren't many
// options around)
linker: "arm-none-eabi-gcc".to_string(),
linker: Some("arm-none-eabi-gcc".to_string()),
// Because these devices have very little resources having an unwinder is too onerous so we
// default to "abort" because the "unwind" strategy is very rare.
panic_strategy: PanicStrategy::Abort,
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_back/target/wasm32_experimental_emscripten.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

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();
Expand All @@ -24,8 +23,6 @@ pub fn target() -> Result<Target, String> {
"-g3".to_string()]);

let opts = TargetOptions {
linker: cmd("emcc"),

dynamic_linking: false,
executables: true,
// Today emcc emits two files - a .js file to bootstrap and
Expand Down
3 changes: 0 additions & 3 deletions src/librustc_back/target/wasm32_unknown_emscripten.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@

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();
Expand All @@ -21,8 +20,6 @@ pub fn target() -> Result<Target, String> {
"ERROR_ON_UNDEFINED_SYMBOLS=1".to_string()]);

let opts = TargetOptions {
linker: cmd("emcc"),

dynamic_linking: false,
executables: true,
// Today emcc emits two files - a .js file to bootstrap and
Expand Down
2 changes: 0 additions & 2 deletions src/librustc_back/target/wasm32_unknown_unknown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ use super::{Target, TargetOptions, PanicStrategy};

pub fn target() -> Result<Target, String> {
let opts = TargetOptions {
linker: "lld".to_string(),

// we allow dynamic linking, but only cdylibs. Basically we allow a
// final library artifact that exports some symbols (a wasm module) but
// we don't allow intermediate `dylib` crate types
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_back/target/windows_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ pub fn opts() -> TargetOptions {
TargetOptions {
// FIXME(#13846) this should be enabled for windows
function_sections: false,
linker: "gcc".to_string(),
linker: Some("gcc".to_string()),
dynamic_linking: true,
executables: true,
dll_prefix: "".to_string(),
Expand Down
1 change: 0 additions & 1 deletion src/librustc_back/target/windows_msvc_base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ pub fn opts() -> TargetOptions {

TargetOptions {
function_sections: true,
linker: "link.exe".to_string(),
dynamic_linking: true,
executables: true,
dll_prefix: "".to_string(),
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_back/target/x86_64_rumprun_netbsd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn target() -> TargetResult {
let mut base = super::netbsd_base::opts();
base.cpu = "x86-64".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.linker = Some("x86_64-rumprun-netbsd-gcc".to_string());
base.max_atomic_width = Some(64);

base.dynamic_linking = false;
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_back/target/x86_64_unknown_cloudabi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub fn target() -> TargetResult {
let mut base = super::cloudabi_base::opts();
base.cpu = "x86-64".to_string();
base.max_atomic_width = Some(64);
base.linker = "x86_64-unknown-cloudabi-cc".to_string();
base.linker = Some("x86_64-unknown-cloudabi-cc".to_string());
base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
base.stack_probes = true;

Expand Down
4 changes: 1 addition & 3 deletions src/librustc_trans/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ test = false

[dependencies]
bitflags = "1.0"
cc = "1.0.1"
flate2 = "1.0"
jobserver = "0.1.5"
libc = "0.2"
Expand All @@ -34,9 +35,6 @@ syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
tempdir = "0.3"

[target."cfg(windows)".dependencies]
cc = "1.0.1"

[features]
# Used to communicate the feature to `rustc_back` in the same manner that the
# `rustc` driver script communicate this.
Expand Down
14 changes: 3 additions & 11 deletions src/librustc_trans/back/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,6 @@ impl Command {
self
}

pub fn envs<I, K, V>(&mut self, envs: I) -> &mut Command
where I: IntoIterator<Item=(K, V)>,
K: AsRef<OsStr>,
V: AsRef<OsStr>
{
for (key, value) in envs {
self._env(key.as_ref(), value.as_ref());
}
self
}

fn _env(&mut self, key: &OsStr, value: &OsStr) {
self.env.push((key.to_owned(), value.to_owned()));
}
Expand All @@ -112,6 +101,9 @@ impl Command {
let mut c = process::Command::new(p);
c.arg("-flavor").arg(match flavor {
LldFlavor::Wasm => "wasm",
LldFlavor::Ld => "gnu",
LldFlavor::Link => "link",
LldFlavor::Ld64 => "darwin",
});
c
}
Expand Down
Loading

0 comments on commit 0129b01

Please sign in to comment.