Skip to content

Commit 89280e1

Browse files
committed
Auto merge of #126832 - petrochenkov:linkarg, r=<try>
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
2 parents c3774be + 5f9a0d3 commit 89280e1

File tree

4 files changed

+318
-383
lines changed

4 files changed

+318
-383
lines changed

Diff for: compiler/rustc_codegen_ssa/src/back/link.rs

+40-35
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use tempfile::Builder as TempFileBuilder;
4545

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

18961896
/// 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
19081908
sess.dcx().emit_fatal(errors::LinkScriptWriteFailure { path, error });
19091909
}
19101910

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

19241923
/// Add arbitrary "late link" args defined by the target spec.
@@ -1936,23 +1935,23 @@ fn add_late_link_args(
19361935
});
19371936
if any_dynamic_crate {
19381937
if let Some(args) = sess.target.late_link_args_dynamic.get(&flavor) {
1939-
cmd.args(args.iter().map(Deref::deref));
1938+
cmd.verbatim_args(args.iter().map(Deref::deref));
19401939
}
19411940
} else {
19421941
if let Some(args) = sess.target.late_link_args_static.get(&flavor) {
1943-
cmd.args(args.iter().map(Deref::deref));
1942+
cmd.verbatim_args(args.iter().map(Deref::deref));
19441943
}
19451944
}
19461945
if let Some(args) = sess.target.late_link_args.get(&flavor) {
1947-
cmd.args(args.iter().map(Deref::deref));
1946+
cmd.verbatim_args(args.iter().map(Deref::deref));
19481947
}
19491948
}
19501949

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

@@ -2097,6 +2096,10 @@ fn add_rpath_args(
20972096
codegen_results: &CodegenResults,
20982097
out_filename: &Path,
20992098
) {
2099+
if !sess.target.has_rpath {
2100+
return;
2101+
}
2102+
21002103
// FIXME (#2397): At some point we want to rpath our guesses as to
21012104
// where extern libraries might live, based on the
21022105
// add_lib_search_paths
@@ -2115,11 +2118,10 @@ fn add_rpath_args(
21152118
let rpath_config = RPathConfig {
21162119
libs: &*libs,
21172120
out_filename: out_filename.to_path_buf(),
2118-
has_rpath: sess.target.has_rpath,
21192121
is_like_osx: sess.target.is_like_osx,
21202122
linker_is_gnu: sess.target.linker_flavor.is_gnu(),
21212123
};
2122-
cmd.args(&rpath::get_rpath_flags(&rpath_config));
2124+
cmd.cc_args(&rpath::get_rpath_flags(&rpath_config));
21232125
}
21242126
}
21252127

@@ -2378,7 +2380,7 @@ fn add_order_independent_options(
23782380
} else {
23792381
""
23802382
};
2381-
cmd.arg(format!("--dynamic-linker={prefix}ld.so.1"));
2383+
cmd.link_arg(format!("--dynamic-linker={prefix}ld.so.1"));
23822384
}
23832385

23842386
if sess.target.eh_frame_header {
@@ -2393,31 +2395,29 @@ fn add_order_independent_options(
23932395
}
23942396

23952397
if sess.target.os == "emscripten" {
2396-
cmd.arg("-s");
2397-
cmd.arg(if sess.panic_strategy() == PanicStrategy::Abort {
2398+
cmd.cc_arg("-s").cc_arg(if sess.panic_strategy() == PanicStrategy::Abort {
23982399
"DISABLE_EXCEPTION_CATCHING=1"
23992400
} else {
24002401
"DISABLE_EXCEPTION_CATCHING=0"
24012402
});
24022403
}
24032404

24042405
if flavor == LinkerFlavor::Llbc {
2405-
cmd.arg("--target");
2406-
cmd.arg(sess.target.llvm_target.as_ref());
2407-
cmd.arg("--target-cpu");
2408-
cmd.arg(&codegen_results.crate_info.target_cpu);
2406+
cmd.link_args(&[
2407+
"--target",
2408+
sess.target.llvm_target.as_ref(),
2409+
"--target-cpu",
2410+
&codegen_results.crate_info.target_cpu,
2411+
]);
24092412
} else if flavor == LinkerFlavor::Ptx {
2410-
cmd.arg("--fallback-arch");
2411-
cmd.arg(&codegen_results.crate_info.target_cpu);
2413+
cmd.link_args(&["--fallback-arch", &codegen_results.crate_info.target_cpu]);
24122414
} else if flavor == LinkerFlavor::Bpf {
2413-
cmd.arg("--cpu");
2414-
cmd.arg(&codegen_results.crate_info.target_cpu);
2415+
cmd.link_args(&["--cpu", &codegen_results.crate_info.target_cpu]);
24152416
if let Some(feat) = [sess.opts.cg.target_feature.as_str(), &sess.target.options.features]
24162417
.into_iter()
24172418
.find(|feat| !feat.is_empty())
24182419
{
2419-
cmd.arg("--cpu-features");
2420-
cmd.arg(feat);
2420+
cmd.link_args(&["--cpu-features", feat]);
24212421
}
24222422
}
24232423

@@ -2618,7 +2618,11 @@ fn add_native_libs_from_crate(
26182618
NativeLibKind::WasmImportModule => {}
26192619
NativeLibKind::LinkArg => {
26202620
if link_static {
2621-
cmd.linker_arg(OsStr::new(name), verbatim);
2621+
if verbatim {
2622+
cmd.verbatim_arg(name);
2623+
} else {
2624+
cmd.link_arg(name);
2625+
}
26222626
}
26232627
}
26242628
}
@@ -3012,10 +3016,10 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
30123016
// This is admittedly a bit strange, as on most targets
30133017
// `-isysroot` only applies to include header files, but on Apple
30143018
// targets this also applies to libraries and frameworks.
3015-
cmd.args(&["-isysroot", &sdk_root]);
3019+
cmd.cc_args(&["-isysroot", &sdk_root]);
30163020
}
30173021
LinkerFlavor::Darwin(Cc::No, _) => {
3018-
cmd.args(&["-syslibroot", &sdk_root]);
3022+
cmd.link_args(&["-syslibroot", &sdk_root]);
30193023
}
30203024
_ => unreachable!(),
30213025
}
@@ -3026,8 +3030,9 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
30263030
// search path.
30273031

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

@@ -3142,7 +3147,7 @@ fn add_lld_args(
31423147
for path in sess.get_tools_search_paths(false) {
31433148
let linker_path = path.join("gcc-ld");
31443149
linker_path_exists |= linker_path.exists();
3145-
cmd.arg({
3150+
cmd.cc_arg({
31463151
let mut arg = OsString::from("-B");
31473152
arg.push(linker_path);
31483153
arg
@@ -3162,7 +3167,7 @@ fn add_lld_args(
31623167
// is to use LLD but the `wasm32-wasip2` target relies on a wrapper around
31633168
// this, `wasm-component-ld`, which is overridden if this option is passed.
31643169
if !sess.target.is_like_wasm {
3165-
cmd.arg("-fuse-ld=lld");
3170+
cmd.cc_arg("-fuse-ld=lld");
31663171
}
31673172

31683173
if !flavor.is_gnu() {
@@ -3186,7 +3191,7 @@ fn add_lld_args(
31863191
// targeting a different linker flavor on macOS, and that's also always
31873192
// the case when targeting WASM.
31883193
if sess.target.linker_flavor != sess.host.linker_flavor {
3189-
cmd.arg(format!("--target={}", sess.target.llvm_target));
3194+
cmd.cc_arg(format!("--target={}", sess.target.llvm_target));
31903195
}
31913196
}
31923197
}

0 commit comments

Comments
 (0)