Skip to content

Commit 34dc0e0

Browse files
committedDec 28, 2015
Link with ld.gold by default
To disable, pass `-C disable-gold`
1 parent 27a1834 commit 34dc0e0

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed
 

‎src/librustc/session/config.rs

+2
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
539539
"explicitly enable the cfg(debug_assertions) directive"),
540540
inline_threshold: Option<usize> = (None, parse_opt_uint,
541541
"set the inlining threshold for"),
542+
disable_gold: bool = (false, parse_bool,
543+
"disable use of the ld.gold linker"),
542544
}
543545

544546

‎src/librustc_trans/back/link.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1060,6 +1060,10 @@ fn link_args(cmd: &mut Linker,
10601060
cmd.args(&rpath::get_rpath_flags(&mut rpath_config));
10611061
}
10621062

1063+
// Use the gold linker if possible instead of ld. It is much
1064+
// faster.
1065+
cmd.try_gold_linker();
1066+
10631067
// Finally add all the linker arguments provided on the command line along
10641068
// with any #[link_args] attributes found inside the crate
10651069
if let Some(ref args) = sess.opts.cg.link_args {

‎src/librustc_trans/back/linker.rs

+51
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use std::env;
1112
use std::ffi::OsString;
1213
use std::fs::{self, File};
1314
use std::io::{self, BufWriter};
@@ -56,6 +57,7 @@ pub trait Linker {
5657
fn no_whole_archives(&mut self);
5758
fn export_symbols(&mut self, sess: &Session, trans: &CrateTranslation,
5859
tmpdir: &Path);
60+
fn try_gold_linker(&mut self);
5961
}
6062

6163
pub struct GnuLinker<'a> {
@@ -199,6 +201,53 @@ impl<'a> Linker for GnuLinker<'a> {
199201
fn export_symbols(&mut self, _: &Session, _: &CrateTranslation, _: &Path) {
200202
// noop, visibility in object files takes care of this
201203
}
204+
205+
fn try_gold_linker(&mut self) {
206+
// Only use gold under specific conditions that we know work
207+
208+
let gold_exists = match env::var_os("PATH") {
209+
Some(ref env_path) => {
210+
env::split_paths(env_path).any(|mut p| {
211+
p.push("ld.gold");
212+
p.exists()
213+
})
214+
}
215+
None => false
216+
};
217+
let host_is_linux = cfg!(target_os = "linux");
218+
// Defensively prevent trying to use gold for bogus cross-targets.
219+
let target_is_host_compatible = {
220+
let host_os_is_target_os = self.sess.target.target.target_os == env::consts::OS;
221+
let host_arch_is_target_arch = self.sess.target.target.arch == env::consts::ARCH;
222+
// Support x86_64->i686 and reverse
223+
let host_and_target_are_x86ish =
224+
(self.sess.target.target.arch == "x86" ||
225+
self.sess.target.target.arch == "x86_64") &&
226+
(env::consts::ARCH == "x86" ||
227+
env::consts::ARCH == "x86_64");
228+
host_os_is_target_os && (host_arch_is_target_arch || host_and_target_are_x86ish)
229+
};
230+
// We have strong confidence that x86 works, but not much
231+
// visibility into other architectures.
232+
let target_works_with_gold =
233+
self.sess.target.target.arch == "x86" ||
234+
self.sess.target.target.arch == "x86_64";
235+
let opt_out = self.sess.opts.cg.disable_gold;
236+
237+
let can_use_gold =
238+
gold_exists &&
239+
host_is_linux &&
240+
target_is_host_compatible &&
241+
target_works_with_gold &&
242+
!opt_out;
243+
244+
if can_use_gold {
245+
info!("linking with ld.gold");
246+
self.cmd.arg("-fuse-ld=gold");
247+
} else {
248+
info!("linking with ld");
249+
}
250+
}
202251
}
203252

204253
pub struct MsvcLinker<'a> {
@@ -358,4 +407,6 @@ impl<'a> Linker for MsvcLinker<'a> {
358407
arg.push(path);
359408
self.cmd.arg(&arg);
360409
}
410+
411+
fn try_gold_linker(&mut self) {}
361412
}

0 commit comments

Comments
 (0)