Skip to content

Commit 4936b3a

Browse files
Rollup merge of rust-lang#118202 - azhogin:azhogin/link_args_wrapping, r=petrochenkov
Added linker_arg(s) Linker trait methods for link-arg to be prefixed "-Wl," for cc-like linker args and not verbatim rust-lang#99427 (comment) > here's one possible improvement to -l link-arg making it more portable between linkers and useful - befriending it with the verbatim modifier (rust-lang#99425). > > -l link-arg:-verbatim=-foo would add -Wl,-foo (or equivalent) when C compiler is used as a linker, and just -foo when bare linker is used. > -l link-arg:+verbatim=-bar on the other hand would always pass just -bar.
2 parents 7aa513b + 7a88458 commit 4936b3a

File tree

4 files changed

+49
-34
lines changed

4 files changed

+49
-34
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use tempfile::Builder as TempFileBuilder;
4444
use itertools::Itertools;
4545
use std::cell::OnceCell;
4646
use std::collections::BTreeSet;
47-
use std::ffi::OsString;
47+
use std::ffi::{OsStr, OsString};
4848
use std::fs::{read, File, OpenOptions};
4949
use std::io::{BufWriter, Write};
5050
use std::ops::Deref;
@@ -2527,7 +2527,7 @@ fn add_native_libs_from_crate(
25272527
NativeLibKind::WasmImportModule => {}
25282528
NativeLibKind::LinkArg => {
25292529
if link_static {
2530-
cmd.arg(name);
2530+
cmd.linker_arg(OsStr::new(name), verbatim);
25312531
}
25322532
}
25332533
}

compiler/rustc_codegen_ssa/src/back/linker.rs

+38-32
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,14 @@ pub trait Linker {
196196
fn add_no_exec(&mut self) {}
197197
fn add_as_needed(&mut self) {}
198198
fn reset_per_library_state(&mut self) {}
199+
fn linker_arg(&mut self, arg: &OsStr, verbatim: bool) {
200+
self.linker_args(&[arg], verbatim);
201+
}
202+
fn linker_args(&mut self, args: &[&OsStr], _verbatim: bool) {
203+
args.into_iter().for_each(|a| {
204+
self.cmd().arg(a);
205+
});
206+
}
199207
}
200208

201209
impl dyn Linker + '_ {
@@ -223,38 +231,12 @@ pub struct GccLinker<'a> {
223231
}
224232

225233
impl<'a> GccLinker<'a> {
226-
/// Passes an argument directly to the linker.
227-
///
228-
/// When the linker is not ld-like such as when using a compiler as a linker, the argument is
229-
/// prepended by `-Wl,`.
230-
fn linker_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
231-
self.linker_args(&[arg]);
232-
self
234+
fn linker_arg(&mut self, arg: impl AsRef<OsStr>) {
235+
Linker::linker_arg(self, arg.as_ref(), false);
233236
}
234-
235-
/// Passes a series of arguments directly to the linker.
236-
///
237-
/// When the linker is ld-like, the arguments are simply appended to the command. When the
238-
/// linker is not ld-like such as when using a compiler as a linker, the arguments are joined by
239-
/// commas to form an argument that is then prepended with `-Wl`. In this situation, only a
240-
/// single argument is appended to the command to ensure that the order of the arguments is
241-
/// preserved by the compiler.
242-
fn linker_args(&mut self, args: &[impl AsRef<OsStr>]) -> &mut Self {
243-
if self.is_ld {
244-
args.into_iter().for_each(|a| {
245-
self.cmd.arg(a);
246-
});
247-
} else {
248-
if !args.is_empty() {
249-
let mut s = OsString::from("-Wl");
250-
for a in args {
251-
s.push(",");
252-
s.push(a);
253-
}
254-
self.cmd.arg(s);
255-
}
256-
}
257-
self
237+
fn linker_args(&mut self, args: &[impl AsRef<OsStr>]) {
238+
let args_vec: Vec<&OsStr> = args.iter().map(|x| x.as_ref()).collect();
239+
Linker::linker_args(self, &args_vec, false);
258240
}
259241

260242
fn takes_hints(&self) -> bool {
@@ -361,6 +343,30 @@ impl<'a> GccLinker<'a> {
361343
}
362344

363345
impl<'a> Linker for GccLinker<'a> {
346+
/// Passes a series of arguments directly to the linker.
347+
///
348+
/// When the linker is ld-like, the arguments are simply appended to the command. When the
349+
/// linker is not ld-like such as when using a compiler as a linker, the arguments are joined by
350+
/// commas to form an argument that is then prepended with `-Wl`. In this situation, only a
351+
/// single argument is appended to the command to ensure that the order of the arguments is
352+
/// preserved by the compiler.
353+
fn linker_args(&mut self, args: &[&OsStr], verbatim: bool) {
354+
if self.is_ld || verbatim {
355+
args.into_iter().for_each(|a| {
356+
self.cmd.arg(a);
357+
});
358+
} else {
359+
if !args.is_empty() {
360+
let mut s = OsString::from("-Wl");
361+
for a in args {
362+
s.push(",");
363+
s.push(a);
364+
}
365+
self.cmd.arg(s);
366+
}
367+
}
368+
}
369+
364370
fn cmd(&mut self) -> &mut Command {
365371
&mut self.cmd
366372
}
@@ -531,7 +537,7 @@ impl<'a> Linker for GccLinker<'a> {
531537
self.linker_arg("-force_load");
532538
self.linker_arg(&lib);
533539
} else {
534-
self.linker_arg("--whole-archive").cmd.arg(lib);
540+
self.linker_args(&[OsString::from("--whole-archive"), lib.into()]);
535541
self.linker_arg("--no-whole-archive");
536542
}
537543
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# only-linux
2+
3+
include ../tools.mk
4+
5+
all:
6+
$(RUSTC) rs.rs -Z unstable-options -C linker-flavor=gnu-cc -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*-Wl,a1.*l2.*-Wl,a2.*d1.*-Wl,a3'
7+
$(RUSTC) rs.rs -Z unstable-options -C linker-flavor=gnu-cc -l static=l1 -l link-arg:+verbatim=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*-Wl,a2.*d1.*-Wl,a3'
8+
$(RUSTC) rs.rs -Z unstable-options -C linker-flavor=ld -l static=l1 -l link-arg=a1 -l static=l2 -l link-arg=a2 -l dylib=d1 -l link-arg=a3 --print link-args | $(CGREP) -e 'l1.*"a1".*l2.*"a2".*d1.*"a3"'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn main() {}

0 commit comments

Comments
 (0)