1
Fork 0

linker: Make argument building interface in trait Linker richer

by redirecting everything to `Command`
This commit is contained in:
Vadim Petrochenkov 2020-04-05 02:11:29 +03:00
parent 6dee5f1126
commit ce25dabc66
2 changed files with 32 additions and 24 deletions

View file

@ -787,7 +787,7 @@ fn link_sanitizer_runtime(sess: &Session, crate_type: config::CrateType, linker:
// PR #41352 for details). // PR #41352 for details).
let libname = format!("rustc{}_rt.{}", channel, name); let libname = format!("rustc{}_rt.{}", channel, name);
let rpath = default_tlib.to_str().expect("non-utf8 component in path"); let rpath = default_tlib.to_str().expect("non-utf8 component in path");
linker.args(&["-Wl,-rpath".into(), "-Xlinker".into(), rpath.into()]); linker.args(&["-Wl,-rpath", "-Xlinker", rpath]);
linker.link_dylib(Symbol::intern(&libname)); linker.link_dylib(Symbol::intern(&libname));
} }
"x86_64-unknown-linux-gnu" | "x86_64-fuchsia" | "aarch64-fuchsia" => { "x86_64-unknown-linux-gnu" | "x86_64-fuchsia" | "aarch64-fuchsia" => {
@ -1300,8 +1300,7 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(
} }
let attr_link_args = codegen_results.crate_info.link_args.iter(); let attr_link_args = codegen_results.crate_info.link_args.iter();
let user_link_args: Vec<_> = let user_link_args = sess.opts.cg.link_args.iter().chain(attr_link_args);
sess.opts.cg.link_args.iter().chain(attr_link_args).cloned().collect();
if crate_type == config::CrateType::Executable { if crate_type == config::CrateType::Executable {
let mut position_independent_executable = false; let mut position_independent_executable = false;
@ -1309,7 +1308,7 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(
if t.options.position_independent_executables { if t.options.position_independent_executables {
if is_pic(sess) if is_pic(sess)
&& !sess.crt_static(Some(crate_type)) && !sess.crt_static(Some(crate_type))
&& !user_link_args.iter().any(|x| x == "-static") && !user_link_args.clone().any(|x| x == "-static")
{ {
position_independent_executable = true; position_independent_executable = true;
} }
@ -1440,7 +1439,7 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(
// Finally add all the linker arguments provided on the command line along // Finally add all the linker arguments provided on the command line along
// with any #[link_args] attributes found inside the crate // with any #[link_args] attributes found inside the crate
cmd.args(&user_link_args); cmd.args(user_link_args);
} }
// # Native library linking // # Native library linking

View file

@ -87,6 +87,7 @@ impl LinkerInfo {
/// used to dispatch on whether a GNU-like linker (generally `ld.exe`) or an /// used to dispatch on whether a GNU-like linker (generally `ld.exe`) or an
/// MSVC linker (e.g., `link.exe`) is being used. /// MSVC linker (e.g., `link.exe`) is being used.
pub trait Linker { pub trait Linker {
fn cmd(&mut self) -> &mut Command;
fn link_dylib(&mut self, lib: Symbol); fn link_dylib(&mut self, lib: Symbol);
fn link_rust_dylib(&mut self, lib: Symbol, path: &Path); fn link_rust_dylib(&mut self, lib: Symbol, path: &Path);
fn link_framework(&mut self, framework: Symbol); fn link_framework(&mut self, framework: Symbol);
@ -111,7 +112,6 @@ pub trait Linker {
fn no_default_libraries(&mut self); fn no_default_libraries(&mut self);
fn build_dylib(&mut self, out_filename: &Path); fn build_dylib(&mut self, out_filename: &Path);
fn build_static_executable(&mut self); fn build_static_executable(&mut self);
fn args(&mut self, args: &[String]);
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType); fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType);
fn subsystem(&mut self, subsystem: &str); fn subsystem(&mut self, subsystem: &str);
fn group_start(&mut self); fn group_start(&mut self);
@ -121,6 +121,16 @@ pub trait Linker {
fn finalize(&mut self) -> Command; fn finalize(&mut self) -> Command;
} }
impl dyn Linker + '_ {
pub fn arg(&mut self, arg: impl AsRef<OsStr>) {
self.cmd().arg(arg);
}
pub fn args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>>) {
self.cmd().args(args);
}
}
pub struct GccLinker<'a> { pub struct GccLinker<'a> {
cmd: Command, cmd: Command,
sess: &'a Session, sess: &'a Session,
@ -208,6 +218,9 @@ impl<'a> GccLinker<'a> {
} }
impl<'a> Linker for GccLinker<'a> { impl<'a> Linker for GccLinker<'a> {
fn cmd(&mut self) -> &mut Command {
&mut self.cmd
}
fn link_dylib(&mut self, lib: Symbol) { fn link_dylib(&mut self, lib: Symbol) {
self.hint_dynamic(); self.hint_dynamic();
self.cmd.arg(format!("-l{}", lib)); self.cmd.arg(format!("-l{}", lib));
@ -251,9 +264,6 @@ impl<'a> Linker for GccLinker<'a> {
fn build_static_executable(&mut self) { fn build_static_executable(&mut self) {
self.cmd.arg("-static"); self.cmd.arg("-static");
} }
fn args(&mut self, args: &[String]) {
self.cmd.args(args);
}
fn link_rust_dylib(&mut self, lib: Symbol, _path: &Path) { fn link_rust_dylib(&mut self, lib: Symbol, _path: &Path) {
self.hint_dynamic(); self.hint_dynamic();
@ -545,15 +555,15 @@ pub struct MsvcLinker<'a> {
} }
impl<'a> Linker for MsvcLinker<'a> { impl<'a> Linker for MsvcLinker<'a> {
fn cmd(&mut self) -> &mut Command {
&mut self.cmd
}
fn link_rlib(&mut self, lib: &Path) { fn link_rlib(&mut self, lib: &Path) {
self.cmd.arg(lib); self.cmd.arg(lib);
} }
fn add_object(&mut self, path: &Path) { fn add_object(&mut self, path: &Path) {
self.cmd.arg(path); self.cmd.arg(path);
} }
fn args(&mut self, args: &[String]) {
self.cmd.args(args);
}
fn build_dylib(&mut self, out_filename: &Path) { fn build_dylib(&mut self, out_filename: &Path) {
self.cmd.arg("/DLL"); self.cmd.arg("/DLL");
@ -778,6 +788,9 @@ pub struct EmLinker<'a> {
} }
impl<'a> Linker for EmLinker<'a> { impl<'a> Linker for EmLinker<'a> {
fn cmd(&mut self) -> &mut Command {
&mut self.cmd
}
fn include_path(&mut self, path: &Path) { fn include_path(&mut self, path: &Path) {
self.cmd.arg("-L").arg(path); self.cmd.arg("-L").arg(path);
} }
@ -837,10 +850,6 @@ impl<'a> Linker for EmLinker<'a> {
// noop // noop
} }
fn args(&mut self, args: &[String]) {
self.cmd.args(args);
}
fn framework_path(&mut self, _path: &Path) { fn framework_path(&mut self, _path: &Path) {
bug!("frameworks are not supported on Emscripten") bug!("frameworks are not supported on Emscripten")
} }
@ -992,6 +1001,10 @@ impl<'a> WasmLd<'a> {
} }
impl<'a> Linker for WasmLd<'a> { impl<'a> Linker for WasmLd<'a> {
fn cmd(&mut self) -> &mut Command {
&mut self.cmd
}
fn link_dylib(&mut self, lib: Symbol) { fn link_dylib(&mut self, lib: Symbol) {
self.cmd.arg("-l").sym_arg(lib); self.cmd.arg("-l").sym_arg(lib);
} }
@ -1030,10 +1043,6 @@ impl<'a> Linker for WasmLd<'a> {
fn build_static_executable(&mut self) {} fn build_static_executable(&mut self) {}
fn args(&mut self, args: &[String]) {
self.cmd.args(args);
}
fn link_rust_dylib(&mut self, lib: Symbol, _path: &Path) { fn link_rust_dylib(&mut self, lib: Symbol, _path: &Path) {
self.cmd.arg("-l").sym_arg(lib); self.cmd.arg("-l").sym_arg(lib);
} }
@ -1162,6 +1171,10 @@ pub struct PtxLinker<'a> {
} }
impl<'a> Linker for PtxLinker<'a> { impl<'a> Linker for PtxLinker<'a> {
fn cmd(&mut self) -> &mut Command {
&mut self.cmd
}
fn link_rlib(&mut self, path: &Path) { fn link_rlib(&mut self, path: &Path) {
self.cmd.arg("--rlib").arg(path); self.cmd.arg("--rlib").arg(path);
} }
@ -1182,10 +1195,6 @@ impl<'a> Linker for PtxLinker<'a> {
self.cmd.arg("--bitcode").arg(path); self.cmd.arg("--bitcode").arg(path);
} }
fn args(&mut self, args: &[String]) {
self.cmd.args(args);
}
fn optimize(&mut self) { fn optimize(&mut self) {
match self.sess.lto() { match self.sess.lto() {
Lto::Thin | Lto::Fat | Lto::ThinLocal => { Lto::Thin | Lto::Fat | Lto::ThinLocal => {