Rollup merge of #126832 - petrochenkov:linkarg, r=jieyouxu
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
This commit is contained in:
commit
6b2e644218
@ -45,7 +45,7 @@
|
||||
|
||||
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;
|
||||
@ -1306,12 +1306,12 @@ fn find_sanitizer_runtime(sess: &Session, filename: &str) -> PathBuf {
|
||||
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);
|
||||
@ -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.
|
||||
@ -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);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -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.
|
||||
@ -1936,15 +1935,15 @@ 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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1952,7 +1951,7 @@ fn add_late_link_args(
|
||||
/// 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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
@ -2393,8 +2395,7 @@ 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"
|
||||
@ -2402,22 +2403,21 @@ fn add_order_independent_options(
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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!(),
|
||||
}
|
||||
@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -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() {
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -9,16 +9,10 @@ pub struct RPathConfig<'a> {
|
||||
pub libs: &'a [&'a Path],
|
||||
pub out_filename: PathBuf,
|
||||
pub is_like_osx: bool,
|
||||
pub has_rpath: bool,
|
||||
pub linker_is_gnu: bool,
|
||||
}
|
||||
|
||||
pub fn get_rpath_flags(config: &RPathConfig<'_>) -> Vec<OsString> {
|
||||
// No rpath on windows
|
||||
if !config.has_rpath {
|
||||
return Vec::new();
|
||||
}
|
||||
|
||||
debug!("preparing the RPATH!");
|
||||
|
||||
let rpaths = get_rpaths(config);
|
||||
|
@ -37,7 +37,6 @@ fn test_rpath_relative() {
|
||||
if cfg!(target_os = "macos") {
|
||||
let config = &mut RPathConfig {
|
||||
libs: &[],
|
||||
has_rpath: true,
|
||||
is_like_osx: true,
|
||||
linker_is_gnu: false,
|
||||
out_filename: PathBuf::from("bin/rustc"),
|
||||
@ -48,7 +47,6 @@ fn test_rpath_relative() {
|
||||
let config = &mut RPathConfig {
|
||||
libs: &[],
|
||||
out_filename: PathBuf::from("bin/rustc"),
|
||||
has_rpath: true,
|
||||
is_like_osx: false,
|
||||
linker_is_gnu: true,
|
||||
};
|
||||
@ -62,7 +60,6 @@ fn test_rpath_relative_issue_119571() {
|
||||
let config = &mut RPathConfig {
|
||||
libs: &[],
|
||||
out_filename: PathBuf::from("rustc"),
|
||||
has_rpath: true,
|
||||
is_like_osx: false,
|
||||
linker_is_gnu: true,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user