Skip to content

rustc_codegen_ssa: Refactor construction of linker arguments #70868

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Apr 9, 2020
Merged
Next Next commit
linker: Make argument building interface in trait Linker richer
by redirecting everything to `Command`
  • Loading branch information
petrochenkov committed Apr 6, 2020
commit ce25dabc66d4b7905dba3bf63ad766d9d6f421ab
9 changes: 4 additions & 5 deletions src/librustc_codegen_ssa/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,7 @@ fn link_sanitizer_runtime(sess: &Session, crate_type: config::CrateType, linker:
// PR #41352 for details).
let libname = format!("rustc{}_rt.{}", channel, name);
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));
}
"x86_64-unknown-linux-gnu" | "x86_64-fuchsia" | "aarch64-fuchsia" => {
Expand Down Expand Up @@ -1300,16 +1300,15 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(
}

let attr_link_args = codegen_results.crate_info.link_args.iter();
let user_link_args: Vec<_> =
sess.opts.cg.link_args.iter().chain(attr_link_args).cloned().collect();
let user_link_args = sess.opts.cg.link_args.iter().chain(attr_link_args);

if crate_type == config::CrateType::Executable {
let mut position_independent_executable = false;

if t.options.position_independent_executables {
if is_pic(sess)
&& !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;
}
Expand Down Expand Up @@ -1440,7 +1439,7 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(

// Finally add all the linker arguments provided on the command line along
// with any #[link_args] attributes found inside the crate
cmd.args(&user_link_args);
cmd.args(user_link_args);
}

// # Native library linking
Expand Down
47 changes: 28 additions & 19 deletions src/librustc_codegen_ssa/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ impl LinkerInfo {
/// used to dispatch on whether a GNU-like linker (generally `ld.exe`) or an
/// MSVC linker (e.g., `link.exe`) is being used.
pub trait Linker {
fn cmd(&mut self) -> &mut Command;
fn link_dylib(&mut self, lib: Symbol);
fn link_rust_dylib(&mut self, lib: Symbol, path: &Path);
fn link_framework(&mut self, framework: Symbol);
Expand All @@ -111,7 +112,6 @@ pub trait Linker {
fn no_default_libraries(&mut self);
fn build_dylib(&mut self, out_filename: &Path);
fn build_static_executable(&mut self);
fn args(&mut self, args: &[String]);
fn export_symbols(&mut self, tmpdir: &Path, crate_type: CrateType);
fn subsystem(&mut self, subsystem: &str);
fn group_start(&mut self);
Expand All @@ -121,6 +121,16 @@ pub trait Linker {
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> {
cmd: Command,
sess: &'a Session,
Expand Down Expand Up @@ -208,6 +218,9 @@ impl<'a> GccLinker<'a> {
}

impl<'a> Linker for GccLinker<'a> {
fn cmd(&mut self) -> &mut Command {
&mut self.cmd
}
fn link_dylib(&mut self, lib: Symbol) {
self.hint_dynamic();
self.cmd.arg(format!("-l{}", lib));
Expand Down Expand Up @@ -251,9 +264,6 @@ impl<'a> Linker for GccLinker<'a> {
fn build_static_executable(&mut self) {
self.cmd.arg("-static");
}
fn args(&mut self, args: &[String]) {
self.cmd.args(args);
}

fn link_rust_dylib(&mut self, lib: Symbol, _path: &Path) {
self.hint_dynamic();
Expand Down Expand Up @@ -545,15 +555,15 @@ pub struct MsvcLinker<'a> {
}

impl<'a> Linker for MsvcLinker<'a> {
fn cmd(&mut self) -> &mut Command {
&mut self.cmd
}
fn link_rlib(&mut self, lib: &Path) {
self.cmd.arg(lib);
}
fn add_object(&mut self, path: &Path) {
self.cmd.arg(path);
}
fn args(&mut self, args: &[String]) {
self.cmd.args(args);
}

fn build_dylib(&mut self, out_filename: &Path) {
self.cmd.arg("/DLL");
Expand Down Expand Up @@ -778,6 +788,9 @@ pub struct EmLinker<'a> {
}

impl<'a> Linker for EmLinker<'a> {
fn cmd(&mut self) -> &mut Command {
&mut self.cmd
}
fn include_path(&mut self, path: &Path) {
self.cmd.arg("-L").arg(path);
}
Expand Down Expand Up @@ -837,10 +850,6 @@ impl<'a> Linker for EmLinker<'a> {
// noop
}

fn args(&mut self, args: &[String]) {
self.cmd.args(args);
}

fn framework_path(&mut self, _path: &Path) {
bug!("frameworks are not supported on Emscripten")
}
Expand Down Expand Up @@ -992,6 +1001,10 @@ impl<'a> WasmLd<'a> {
}

impl<'a> Linker for WasmLd<'a> {
fn cmd(&mut self) -> &mut Command {
&mut self.cmd
}

fn link_dylib(&mut self, lib: Symbol) {
self.cmd.arg("-l").sym_arg(lib);
}
Expand Down Expand Up @@ -1030,10 +1043,6 @@ impl<'a> Linker for WasmLd<'a> {

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) {
self.cmd.arg("-l").sym_arg(lib);
}
Expand Down Expand Up @@ -1162,6 +1171,10 @@ pub struct PtxLinker<'a> {
}

impl<'a> Linker for PtxLinker<'a> {
fn cmd(&mut self) -> &mut Command {
&mut self.cmd
}

fn link_rlib(&mut self, path: &Path) {
self.cmd.arg("--rlib").arg(path);
}
Expand All @@ -1182,10 +1195,6 @@ impl<'a> Linker for PtxLinker<'a> {
self.cmd.arg("--bitcode").arg(path);
}

fn args(&mut self, args: &[String]) {
self.cmd.args(args);
}

fn optimize(&mut self) {
match self.sess.lto() {
Lto::Thin | Lto::Fat | Lto::ThinLocal => {
Expand Down