Skip to content

Commit 598498f

Browse files
committed
rustc_trans: Linker fully wraps command
1 parent be4249e commit 598498f

File tree

2 files changed

+190
-97
lines changed

2 files changed

+190
-97
lines changed

src/librustc_trans/back/link.rs

Lines changed: 83 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -135,14 +135,14 @@ pub fn build_link_meta(tcx: &TyCtxt,
135135
return r;
136136
}
137137

138-
pub fn get_linker(sess: &Session) -> (String, Command) {
138+
pub fn get_linker(sess: &Session) -> (&str, Command) {
139139
if let Some(ref linker) = sess.opts.cg.linker {
140-
(linker.clone(), Command::new(linker))
140+
(linker, Command::new(linker))
141141
} else if sess.target.target.options.is_like_msvc {
142-
("link.exe".to_string(), msvc::link_exe_cmd(sess))
142+
("link.exe", msvc::link_exe_cmd(sess))
143143
} else {
144-
(sess.target.target.options.linker.clone(),
145-
Command::new(&sess.target.target.options.linker))
144+
let linker = &sess.target.target.options.linker;
145+
(linker, Command::new(linker))
146146
}
147147
}
148148

@@ -621,6 +621,54 @@ fn link_natively(sess: &Session, dylib: bool,
621621
let (pname, mut cmd) = get_linker(sess);
622622
cmd.env("PATH", command_path(sess));
623623

624+
if sess.target.target.options.is_like_msvc {
625+
let mut linker = MsvcLinker {
626+
name: pname,
627+
cmd: cmd,
628+
sess: &sess,
629+
};
630+
link_natively_helper(&mut linker,
631+
sess,
632+
dylib,
633+
objects,
634+
out_filename,
635+
trans,
636+
outputs,
637+
tmpdir);
638+
} else {
639+
let mut linker = GnuLinker {
640+
name: pname,
641+
cmd: cmd,
642+
sess: &sess,
643+
};
644+
link_natively_helper(&mut linker,
645+
sess,
646+
dylib,
647+
objects,
648+
out_filename,
649+
trans,
650+
outputs,
651+
tmpdir);
652+
}
653+
654+
// On OSX, debuggers need this utility to get run to do some munging of
655+
// the symbols
656+
if sess.target.target.options.is_like_osx && sess.opts.debuginfo != NoDebugInfo {
657+
match Command::new("dsymutil").arg(out_filename).output() {
658+
Ok(..) => {}
659+
Err(e) => sess.fatal(&format!("failed to run dsymutil: {}", e)),
660+
}
661+
}
662+
}
663+
664+
fn link_natively_helper<T: Linker>(cmd: &mut T,
665+
sess: &Session,
666+
dylib: bool,
667+
objects: &[PathBuf],
668+
out_filename: &Path,
669+
trans: &CrateTranslation,
670+
outputs: &OutputFilenames,
671+
tmpdir: &Path) {
624672
let root = sess.target_filesearch(PathKind::Native).get_lib_path();
625673
cmd.args(&sess.target.target.options.pre_link_args);
626674

@@ -633,18 +681,18 @@ fn link_natively(sess: &Session, dylib: bool,
633681
cmd.arg(root.join(obj));
634682
}
635683

636-
{
637-
let mut linker = if sess.target.target.options.is_like_msvc {
638-
Box::new(MsvcLinker { cmd: &mut cmd, sess: &sess }) as Box<Linker>
639-
} else {
640-
Box::new(GnuLinker { cmd: &mut cmd, sess: &sess }) as Box<Linker>
641-
};
642-
link_args(&mut *linker, sess, dylib, tmpdir,
643-
objects, out_filename, trans, outputs);
644-
if !sess.target.target.options.no_compiler_rt {
645-
linker.link_staticlib("compiler-rt");
646-
}
684+
link_args(cmd,
685+
sess,
686+
dylib,
687+
tmpdir,
688+
objects,
689+
out_filename,
690+
trans,
691+
outputs);
692+
if !sess.target.target.options.no_compiler_rt {
693+
cmd.link_staticlib("compiler-rt");
647694
}
695+
648696
cmd.args(&sess.target.target.options.late_link_args);
649697
for obj in &sess.target.target.options.post_link_objects {
650698
cmd.arg(root.join(obj));
@@ -677,7 +725,7 @@ fn link_natively(sess: &Session, dylib: bool,
677725
let mut output = prog.stderr.clone();
678726
output.extend_from_slice(&prog.stdout);
679727
sess.struct_err(&format!("linking with `{}` failed: {}",
680-
pname,
728+
cmd,
681729
prog.status))
682730
.note(&format!("{:?}", &cmd))
683731
.note(&escape_string(&output[..]))
@@ -688,29 +736,19 @@ fn link_natively(sess: &Session, dylib: bool,
688736
info!("linker stdout:\n{}", escape_string(&prog.stdout[..]));
689737
},
690738
Err(e) => {
691-
sess.fatal(&format!("could not exec the linker `{}`: {}", pname, e));
692-
}
693-
}
694-
695-
696-
// On OSX, debuggers need this utility to get run to do some munging of
697-
// the symbols
698-
if sess.target.target.options.is_like_osx && sess.opts.debuginfo != NoDebugInfo {
699-
match Command::new("dsymutil").arg(out_filename).output() {
700-
Ok(..) => {}
701-
Err(e) => sess.fatal(&format!("failed to run dsymutil: {}", e)),
739+
sess.fatal(&format!("could not exec the linker `{}`: {}", cmd, e));
702740
}
703741
}
704742
}
705743

706-
fn link_args(cmd: &mut Linker,
707-
sess: &Session,
708-
dylib: bool,
709-
tmpdir: &Path,
710-
objects: &[PathBuf],
711-
out_filename: &Path,
712-
trans: &CrateTranslation,
713-
outputs: &OutputFilenames) {
744+
fn link_args<T: Linker>(cmd: &mut T,
745+
sess: &Session,
746+
dylib: bool,
747+
tmpdir: &Path,
748+
objects: &[PathBuf],
749+
out_filename: &Path,
750+
trans: &CrateTranslation,
751+
outputs: &OutputFilenames) {
714752

715753
// The default library location, we need this to find the runtime.
716754
// The location of crates will be determined as needed.
@@ -854,7 +892,7 @@ fn link_args(cmd: &mut Linker,
854892
// Also note that the native libraries linked here are only the ones located
855893
// in the current crate. Upstream crates with native library dependencies
856894
// may have their native library pulled in above.
857-
fn add_local_native_libraries(cmd: &mut Linker, sess: &Session) {
895+
fn add_local_native_libraries<T: Linker>(cmd: &mut T, sess: &Session) {
858896
sess.target_filesearch(PathKind::All).for_each_lib_search_path(|path, k| {
859897
match k {
860898
PathKind::Framework => { cmd.framework_path(path); }
@@ -904,8 +942,7 @@ fn add_local_native_libraries(cmd: &mut Linker, sess: &Session) {
904942
// Rust crates are not considered at all when creating an rlib output. All
905943
// dependencies will be linked when producing the final output (instead of
906944
// the intermediate rlib version)
907-
fn add_upstream_rust_crates(cmd: &mut Linker, sess: &Session,
908-
dylib: bool, tmpdir: &Path) {
945+
fn add_upstream_rust_crates<T: Linker>(cmd: &mut T, sess: &Session, dylib: bool, tmpdir: &Path) {
909946
// All of the heavy lifting has previously been accomplished by the
910947
// dependency_format module of the compiler. This is just crawling the
911948
// output of that module, adding crates as necessary.
@@ -979,8 +1016,11 @@ fn add_upstream_rust_crates(cmd: &mut Linker, sess: &Session,
9791016
// (aka we're making an executable), we can just pass the rlib blindly to
9801017
// the linker (fast) because it's fine if it's not actually included as
9811018
// we're at the end of the dependency chain.
982-
fn add_static_crate(cmd: &mut Linker, sess: &Session, tmpdir: &Path,
983-
dylib: bool, cratepath: &Path) {
1019+
fn add_static_crate<T: Linker>(cmd: &mut T,
1020+
sess: &Session,
1021+
tmpdir: &Path,
1022+
dylib: bool,
1023+
cratepath: &Path) {
9841024
if !sess.lto() && !dylib {
9851025
cmd.link_rlib(&fix_windows_verbatim_for_gcc(cratepath));
9861026
return
@@ -1027,7 +1067,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker, sess: &Session,
10271067
}
10281068

10291069
// Same thing as above, but for dynamic crates instead of static crates.
1030-
fn add_dynamic_crate(cmd: &mut Linker, sess: &Session, cratepath: &Path) {
1070+
fn add_dynamic_crate<T: Linker>(cmd: &mut T, sess: &Session, cratepath: &Path) {
10311071
// If we're performing LTO, then it should have been previously required
10321072
// that all upstream rust dependencies were available in an rlib format.
10331073
assert!(!sess.lto());
@@ -1062,7 +1102,7 @@ fn add_upstream_rust_crates(cmd: &mut Linker, sess: &Session,
10621102
// generic function calls a native function, then the generic function must
10631103
// be instantiated in the target crate, meaning that the native symbol must
10641104
// also be resolved in the target crate.
1065-
fn add_upstream_native_libraries(cmd: &mut Linker, sess: &Session) {
1105+
fn add_upstream_native_libraries<T: Linker>(cmd: &mut T, sess: &Session) {
10661106
// Be sure to use a topological sorting of crates because there may be
10671107
// interdependencies between native libraries. When passing -nodefaultlibs,
10681108
// for example, almost all native libraries depend on libc, so we have to

0 commit comments

Comments
 (0)