mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 23:04:33 +00:00
Rollup merge of #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 https://github.com/rust-lang/rust/issues/99427#issuecomment-1234443468 > here's one possible improvement to -l link-arg making it more portable between linkers and useful - befriending it with the verbatim modifier (https://github.com/rust-lang/rust/issues/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.
This commit is contained in:
commit
4936b3abdd
@ -44,7 +44,7 @@ use tempfile::Builder as TempFileBuilder;
|
||||
use itertools::Itertools;
|
||||
use std::cell::OnceCell;
|
||||
use std::collections::BTreeSet;
|
||||
use std::ffi::OsString;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::fs::{read, File, OpenOptions};
|
||||
use std::io::{BufWriter, Write};
|
||||
use std::ops::Deref;
|
||||
@ -2527,7 +2527,7 @@ fn add_native_libs_from_crate(
|
||||
NativeLibKind::WasmImportModule => {}
|
||||
NativeLibKind::LinkArg => {
|
||||
if link_static {
|
||||
cmd.arg(name);
|
||||
cmd.linker_arg(OsStr::new(name), verbatim);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -196,6 +196,14 @@ pub trait Linker {
|
||||
fn add_no_exec(&mut self) {}
|
||||
fn add_as_needed(&mut self) {}
|
||||
fn reset_per_library_state(&mut self) {}
|
||||
fn linker_arg(&mut self, arg: &OsStr, verbatim: bool) {
|
||||
self.linker_args(&[arg], verbatim);
|
||||
}
|
||||
fn linker_args(&mut self, args: &[&OsStr], _verbatim: bool) {
|
||||
args.into_iter().for_each(|a| {
|
||||
self.cmd().arg(a);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl dyn Linker + '_ {
|
||||
@ -223,38 +231,12 @@ pub struct GccLinker<'a> {
|
||||
}
|
||||
|
||||
impl<'a> GccLinker<'a> {
|
||||
/// Passes an argument directly to the linker.
|
||||
///
|
||||
/// When the linker is not ld-like such as when using a compiler as a linker, the argument is
|
||||
/// prepended by `-Wl,`.
|
||||
fn linker_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
|
||||
self.linker_args(&[arg]);
|
||||
self
|
||||
fn linker_arg(&mut self, arg: impl AsRef<OsStr>) {
|
||||
Linker::linker_arg(self, arg.as_ref(), false);
|
||||
}
|
||||
|
||||
/// Passes a series of arguments directly to the linker.
|
||||
///
|
||||
/// When the linker is ld-like, the arguments are simply appended to the command. When the
|
||||
/// linker is not ld-like such as when using a compiler as a linker, the arguments are joined by
|
||||
/// commas to form an argument that is then prepended with `-Wl`. In this situation, only a
|
||||
/// single argument is appended to the command to ensure that the order of the arguments is
|
||||
/// preserved by the compiler.
|
||||
fn linker_args(&mut self, args: &[impl AsRef<OsStr>]) -> &mut Self {
|
||||
if self.is_ld {
|
||||
args.into_iter().for_each(|a| {
|
||||
self.cmd.arg(a);
|
||||
});
|
||||
} else {
|
||||
if !args.is_empty() {
|
||||
let mut s = OsString::from("-Wl");
|
||||
for a in args {
|
||||
s.push(",");
|
||||
s.push(a);
|
||||
}
|
||||
self.cmd.arg(s);
|
||||
}
|
||||
}
|
||||
self
|
||||
fn linker_args(&mut self, args: &[impl AsRef<OsStr>]) {
|
||||
let args_vec: Vec<&OsStr> = args.iter().map(|x| x.as_ref()).collect();
|
||||
Linker::linker_args(self, &args_vec, false);
|
||||
}
|
||||
|
||||
fn takes_hints(&self) -> bool {
|
||||
@ -361,6 +343,30 @@ impl<'a> GccLinker<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Linker for GccLinker<'a> {
|
||||
/// Passes a series of arguments directly to the linker.
|
||||
///
|
||||
/// When the linker is ld-like, the arguments are simply appended to the command. When the
|
||||
/// linker is not ld-like such as when using a compiler as a linker, the arguments are joined by
|
||||
/// commas to form an argument that is then prepended with `-Wl`. In this situation, only a
|
||||
/// single argument is appended to the command to ensure that the order of the arguments is
|
||||
/// preserved by the compiler.
|
||||
fn linker_args(&mut self, args: &[&OsStr], verbatim: bool) {
|
||||
if self.is_ld || verbatim {
|
||||
args.into_iter().for_each(|a| {
|
||||
self.cmd.arg(a);
|
||||
});
|
||||
} else {
|
||||
if !args.is_empty() {
|
||||
let mut s = OsString::from("-Wl");
|
||||
for a in args {
|
||||
s.push(",");
|
||||
s.push(a);
|
||||
}
|
||||
self.cmd.arg(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn cmd(&mut self) -> &mut Command {
|
||||
&mut self.cmd
|
||||
}
|
||||
@ -531,7 +537,7 @@ impl<'a> Linker for GccLinker<'a> {
|
||||
self.linker_arg("-force_load");
|
||||
self.linker_arg(&lib);
|
||||
} else {
|
||||
self.linker_arg("--whole-archive").cmd.arg(lib);
|
||||
self.linker_args(&[OsString::from("--whole-archive"), lib.into()]);
|
||||
self.linker_arg("--no-whole-archive");
|
||||
}
|
||||
}
|
||||
|
8
tests/run-make/pass-linker-flags-flavor/Makefile
Normal file
8
tests/run-make/pass-linker-flags-flavor/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# only-linux
|
||||
|
||||
include ../tools.mk
|
||||
|
||||
all:
|
||||
$(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'
|
||||
$(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'
|
||||
$(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"'
|
1
tests/run-make/pass-linker-flags-flavor/rs.rs
Normal file
1
tests/run-make/pass-linker-flags-flavor/rs.rs
Normal file
@ -0,0 +1 @@
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user