Skip to content

Commit

Permalink
Link with ld.gold by default
Browse files Browse the repository at this point in the history
To disable, pass `-C disable-gold`
  • Loading branch information
brson committed Dec 28, 2015
1 parent 27a1834 commit 34dc0e0
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/librustc/session/config.rs
Expand Up @@ -539,6 +539,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
"explicitly enable the cfg(debug_assertions) directive"),
inline_threshold: Option<usize> = (None, parse_opt_uint,
"set the inlining threshold for"),
disable_gold: bool = (false, parse_bool,
"disable use of the ld.gold linker"),
}


Expand Down
4 changes: 4 additions & 0 deletions src/librustc_trans/back/link.rs
Expand Up @@ -1060,6 +1060,10 @@ fn link_args(cmd: &mut Linker,
cmd.args(&rpath::get_rpath_flags(&mut rpath_config));
}

// Use the gold linker if possible instead of ld. It is much
// faster.
cmd.try_gold_linker();

// Finally add all the linker arguments provided on the command line along
// with any #[link_args] attributes found inside the crate
if let Some(ref args) = sess.opts.cg.link_args {
Expand Down
51 changes: 51 additions & 0 deletions src/librustc_trans/back/linker.rs
Expand Up @@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::env;
use std::ffi::OsString;
use std::fs::{self, File};
use std::io::{self, BufWriter};
Expand Down Expand Up @@ -56,6 +57,7 @@ pub trait Linker {
fn no_whole_archives(&mut self);
fn export_symbols(&mut self, sess: &Session, trans: &CrateTranslation,
tmpdir: &Path);
fn try_gold_linker(&mut self);
}

pub struct GnuLinker<'a> {
Expand Down Expand Up @@ -199,6 +201,53 @@ impl<'a> Linker for GnuLinker<'a> {
fn export_symbols(&mut self, _: &Session, _: &CrateTranslation, _: &Path) {
// noop, visibility in object files takes care of this
}

fn try_gold_linker(&mut self) {
// Only use gold under specific conditions that we know work

let gold_exists = match env::var_os("PATH") {
Some(ref env_path) => {
env::split_paths(env_path).any(|mut p| {
p.push("ld.gold");
p.exists()
})
}
None => false
};
let host_is_linux = cfg!(target_os = "linux");
// Defensively prevent trying to use gold for bogus cross-targets.
let target_is_host_compatible = {
let host_os_is_target_os = self.sess.target.target.target_os == env::consts::OS;
let host_arch_is_target_arch = self.sess.target.target.arch == env::consts::ARCH;
// Support x86_64->i686 and reverse
let host_and_target_are_x86ish =
(self.sess.target.target.arch == "x86" ||
self.sess.target.target.arch == "x86_64") &&
(env::consts::ARCH == "x86" ||
env::consts::ARCH == "x86_64");
host_os_is_target_os && (host_arch_is_target_arch || host_and_target_are_x86ish)
};
// We have strong confidence that x86 works, but not much
// visibility into other architectures.
let target_works_with_gold =
self.sess.target.target.arch == "x86" ||
self.sess.target.target.arch == "x86_64";
let opt_out = self.sess.opts.cg.disable_gold;

let can_use_gold =
gold_exists &&
host_is_linux &&
target_is_host_compatible &&
target_works_with_gold &&
!opt_out;

if can_use_gold {
info!("linking with ld.gold");
self.cmd.arg("-fuse-ld=gold");
} else {
info!("linking with ld");
}
}
}

pub struct MsvcLinker<'a> {
Expand Down Expand Up @@ -358,4 +407,6 @@ impl<'a> Linker for MsvcLinker<'a> {
arg.push(path);
self.cmd.arg(&arg);
}

fn try_gold_linker(&mut self) {}
}

0 comments on commit 34dc0e0

Please sign in to comment.