Skip to content

Commit

Permalink
Rollup merge of #126832 - petrochenkov:linkarg, r=jieyouxu
Browse files Browse the repository at this point in the history
linker: Refactor interface for passing arguments to linker

Separate arguments into passed to the underlying linker, to cc wrapper, or supported by both.
Also avoid allocations in all the argument passing functions.

The interfaces would look nicer if not the limitations on returning `&mut Self` in `dyn`-compatible traits, and unnecessary conflicts between `Trait` and `dyn Trait` methods.

try-job: armhf-gnu
try-job: aarch64-gnu
try-job: dist-x86_64-linux
try-job: x86_64-msvc
try-job: i686-msvc
try-job: dist-x86_64-apple
try-job: test-various
  • Loading branch information
GuillaumeGomez committed Jul 1, 2024
2 parents c4baa3f + 5f9a0d3 commit 6b2e644
Show file tree
Hide file tree
Showing 4 changed files with 318 additions and 383 deletions.
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

0 comments on commit 6b2e644

Please sign in to comment.