Skip to content
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

linker: Refactor interface for passing arguments to linker #126832

Merged
merged 2 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 40 additions & 35 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ use tempfile::Builder as TempFileBuilder;

use itertools::Itertools;
use std::collections::BTreeSet;
use std::ffi::{OsStr, OsString};
use std::ffi::OsString;
use std::fs::{read, File, OpenOptions};
use std::io::{BufWriter, Write};
use std::ops::Deref;
Expand Down Expand Up @@ -1306,12 +1306,12 @@ fn link_sanitizer_runtime(
let filename = format!("rustc{channel}_rt.{name}");
let path = find_sanitizer_runtime(sess, &filename);
let rpath = path.to_str().expect("non-utf8 component in path");
linker.args(&["-Wl,-rpath", "-Xlinker", rpath]);
linker.cc_args(&["-Wl,-rpath", "-Xlinker", rpath]);
linker.link_dylib_by_name(&filename, false, true);
} else if sess.target.is_like_msvc && flavor == LinkerFlavor::Msvc(Lld::No) && name == "asan" {
// MSVC provides the `/INFERASANLIBS` argument to automatically find the
// compatible ASAN library.
linker.arg("/INFERASANLIBS");
linker.link_arg("/INFERASANLIBS");
} else {
let filename = format!("librustc{channel}_rt.{name}.a");
let path = find_sanitizer_runtime(sess, &filename).join(&filename);
Expand Down Expand Up @@ -1888,9 +1888,9 @@ fn add_post_link_objects(
/// FIXME: Determine where exactly these args need to be inserted.
fn add_pre_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
if let Some(args) = sess.target.pre_link_args.get(&flavor) {
cmd.args(args.iter().map(Deref::deref));
cmd.verbatim_args(args.iter().map(Deref::deref));
}
cmd.args(&sess.opts.unstable_opts.pre_link_args);
cmd.verbatim_args(&sess.opts.unstable_opts.pre_link_args);
}

/// Add a link script embedded in the target, if applicable.
Expand All @@ -1908,8 +1908,7 @@ fn add_link_script(cmd: &mut dyn Linker, sess: &Session, tmpdir: &Path, crate_ty
sess.dcx().emit_fatal(errors::LinkScriptWriteFailure { path, error });
}

cmd.arg("--script");
cmd.arg(path);
cmd.link_arg("--script").link_arg(path);
}
_ => {}
}
Expand All @@ -1918,7 +1917,7 @@ fn add_link_script(cmd: &mut dyn Linker, sess: &Session, tmpdir: &Path, crate_ty
/// Add arbitrary "user defined" args defined from command line.
/// FIXME: Determine where exactly these args need to be inserted.
fn add_user_defined_link_args(cmd: &mut dyn Linker, sess: &Session) {
cmd.args(&sess.opts.cg.link_args);
cmd.verbatim_args(&sess.opts.cg.link_args);
}

/// Add arbitrary "late link" args defined by the target spec.
Expand All @@ -1936,23 +1935,23 @@ fn add_late_link_args(
});
if any_dynamic_crate {
if let Some(args) = sess.target.late_link_args_dynamic.get(&flavor) {
cmd.args(args.iter().map(Deref::deref));
cmd.verbatim_args(args.iter().map(Deref::deref));
}
} else {
if let Some(args) = sess.target.late_link_args_static.get(&flavor) {
cmd.args(args.iter().map(Deref::deref));
cmd.verbatim_args(args.iter().map(Deref::deref));
}
}
if let Some(args) = sess.target.late_link_args.get(&flavor) {
cmd.args(args.iter().map(Deref::deref));
cmd.verbatim_args(args.iter().map(Deref::deref));
}
}

/// Add arbitrary "post-link" args defined by the target spec.
/// FIXME: Determine where exactly these args need to be inserted.
fn add_post_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
if let Some(args) = sess.target.post_link_args.get(&flavor) {
cmd.args(args.iter().map(Deref::deref));
cmd.verbatim_args(args.iter().map(Deref::deref));
}
}

Expand Down Expand Up @@ -2097,6 +2096,10 @@ fn add_rpath_args(
codegen_results: &CodegenResults,
out_filename: &Path,
) {
if !sess.target.has_rpath {
return;
}

// FIXME (#2397): At some point we want to rpath our guesses as to
// where extern libraries might live, based on the
// add_lib_search_paths
Expand All @@ -2115,11 +2118,10 @@ fn add_rpath_args(
let rpath_config = RPathConfig {
libs: &*libs,
out_filename: out_filename.to_path_buf(),
has_rpath: sess.target.has_rpath,
is_like_osx: sess.target.is_like_osx,
linker_is_gnu: sess.target.linker_flavor.is_gnu(),
};
cmd.args(&rpath::get_rpath_flags(&rpath_config));
cmd.cc_args(&rpath::get_rpath_flags(&rpath_config));
}
}

Expand Down Expand Up @@ -2378,7 +2380,7 @@ fn add_order_independent_options(
} else {
""
};
cmd.arg(format!("--dynamic-linker={prefix}ld.so.1"));
cmd.link_arg(format!("--dynamic-linker={prefix}ld.so.1"));
}

if sess.target.eh_frame_header {
Expand All @@ -2393,31 +2395,29 @@ fn add_order_independent_options(
}

if sess.target.os == "emscripten" {
cmd.arg("-s");
cmd.arg(if sess.panic_strategy() == PanicStrategy::Abort {
cmd.cc_arg("-s").cc_arg(if sess.panic_strategy() == PanicStrategy::Abort {
"DISABLE_EXCEPTION_CATCHING=1"
} else {
"DISABLE_EXCEPTION_CATCHING=0"
});
}

if flavor == LinkerFlavor::Llbc {
cmd.arg("--target");
cmd.arg(sess.target.llvm_target.as_ref());
cmd.arg("--target-cpu");
cmd.arg(&codegen_results.crate_info.target_cpu);
cmd.link_args(&[
"--target",
sess.target.llvm_target.as_ref(),
"--target-cpu",
&codegen_results.crate_info.target_cpu,
]);
} else if flavor == LinkerFlavor::Ptx {
cmd.arg("--fallback-arch");
cmd.arg(&codegen_results.crate_info.target_cpu);
cmd.link_args(&["--fallback-arch", &codegen_results.crate_info.target_cpu]);
} else if flavor == LinkerFlavor::Bpf {
cmd.arg("--cpu");
cmd.arg(&codegen_results.crate_info.target_cpu);
cmd.link_args(&["--cpu", &codegen_results.crate_info.target_cpu]);
if let Some(feat) = [sess.opts.cg.target_feature.as_str(), &sess.target.options.features]
.into_iter()
.find(|feat| !feat.is_empty())
{
cmd.arg("--cpu-features");
cmd.arg(feat);
cmd.link_args(&["--cpu-features", feat]);
}
}

Expand Down Expand Up @@ -2618,7 +2618,11 @@ fn add_native_libs_from_crate(
NativeLibKind::WasmImportModule => {}
NativeLibKind::LinkArg => {
if link_static {
cmd.linker_arg(OsStr::new(name), verbatim);
if verbatim {
cmd.verbatim_arg(name);
} else {
cmd.link_arg(name);
}
}
}
}
Expand Down Expand Up @@ -3012,10 +3016,10 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
// This is admittedly a bit strange, as on most targets
// `-isysroot` only applies to include header files, but on Apple
// targets this also applies to libraries and frameworks.
cmd.args(&["-isysroot", &sdk_root]);
cmd.cc_args(&["-isysroot", &sdk_root]);
}
LinkerFlavor::Darwin(Cc::No, _) => {
cmd.args(&["-syslibroot", &sdk_root]);
cmd.link_args(&["-syslibroot", &sdk_root]);
}
_ => unreachable!(),
}
Expand All @@ -3026,8 +3030,9 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
// search path.

// The flags are called `-L` and `-F` both in Clang, ld64 and ldd.
cmd.arg(format!("-L{sdk_root}/System/iOSSupport/usr/lib"));
cmd.arg(format!("-F{sdk_root}/System/iOSSupport/System/Library/Frameworks"));
let sdk_root = Path::new(&sdk_root);
cmd.include_path(&sdk_root.join("System/iOSSupport/usr/lib"));
cmd.framework_path(&sdk_root.join("System/iOSSupport/System/Library/Frameworks"));
}
}

Expand Down Expand Up @@ -3142,7 +3147,7 @@ fn add_lld_args(
for path in sess.get_tools_search_paths(false) {
let linker_path = path.join("gcc-ld");
linker_path_exists |= linker_path.exists();
cmd.arg({
cmd.cc_arg({
let mut arg = OsString::from("-B");
arg.push(linker_path);
arg
Expand All @@ -3162,7 +3167,7 @@ fn add_lld_args(
// is to use LLD but the `wasm32-wasip2` target relies on a wrapper around
// this, `wasm-component-ld`, which is overridden if this option is passed.
if !sess.target.is_like_wasm {
cmd.arg("-fuse-ld=lld");
cmd.cc_arg("-fuse-ld=lld");
}

if !flavor.is_gnu() {
Expand All @@ -3186,7 +3191,7 @@ fn add_lld_args(
// targeting a different linker flavor on macOS, and that's also always
// the case when targeting WASM.
if sess.target.linker_flavor != sess.host.linker_flavor {
cmd.arg(format!("--target={}", sess.target.llvm_target));
cmd.cc_arg(format!("--target={}", sess.target.llvm_target));
}
}
}
Loading
Loading