Skip to content

Commit 45791dd

Browse files
committed
Support linker arguments that contain commas
1 parent a475551 commit 45791dd

File tree

2 files changed

+67
-9
lines changed

2 files changed

+67
-9
lines changed

compiler/rustc_codegen_ssa/src/back/linker.rs

+42-9
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ use super::command::Command;
2424
use super::symbol_export;
2525
use crate::errors;
2626

27+
#[cfg(test)]
28+
mod tests;
29+
2730
/// Disables non-English messages from localized linkers.
2831
/// Such messages may cause issues with text encoding on Windows (#35785)
2932
/// and prevent inspection of linker output in case of errors, which we occasionally do.
@@ -178,23 +181,53 @@ fn verbatim_args<L: Linker + ?Sized>(
178181
}
179182
l
180183
}
184+
/// Add underlying linker arguments to C compiler command, by wrapping them in
185+
/// `-Wl` or `-Xlinker`.
186+
fn convert_link_args_to_cc_args(
187+
cmd: &mut Command,
188+
args: impl IntoIterator<Item: AsRef<OsStr>, IntoIter: ExactSizeIterator>,
189+
) {
190+
let args = args.into_iter();
191+
if args.len() == 0 {
192+
return;
193+
}
194+
195+
let mut combined_arg = OsString::from("-Wl");
196+
for arg in args {
197+
// If the argument itself contains a comma, we need to emit it
198+
// as `-Xlinker`, otherwise we can use `-Wl`.
199+
if arg.as_ref().as_encoded_bytes().contains(&b',') {
200+
// Emit current `-Wl` argument, if any has been built.
201+
if combined_arg != OsStr::new("-Wl") {
202+
cmd.arg(combined_arg);
203+
// Begin next `-Wl` argument.
204+
combined_arg = OsString::from("-Wl");
205+
}
206+
207+
// Emit `-Xlinker` argument.
208+
cmd.arg("-Xlinker");
209+
cmd.arg(arg);
210+
} else {
211+
// Append to `-Wl` argument.
212+
combined_arg.push(",");
213+
combined_arg.push(arg);
214+
}
215+
}
216+
// Emit final `-Wl` argument.
217+
if combined_arg != OsStr::new("-Wl") {
218+
cmd.arg(combined_arg);
219+
}
220+
}
181221
/// Arguments for the underlying linker.
182222
/// Add options to pass them through cc wrapper if `Linker` is a cc wrapper.
183223
fn link_args<L: Linker + ?Sized>(
184224
l: &mut L,
185225
args: impl IntoIterator<Item: AsRef<OsStr>, IntoIter: ExactSizeIterator>,
186226
) -> &mut L {
187-
let args = args.into_iter();
188227
if !l.is_cc() {
189228
verbatim_args(l, args);
190-
} else if args.len() != 0 {
191-
// FIXME: Support arguments with commas, see `rpaths_to_flags` for the example.
192-
let mut combined_arg = OsString::from("-Wl");
193-
for arg in args {
194-
combined_arg.push(",");
195-
combined_arg.push(arg);
196-
}
197-
l.cmd().arg(combined_arg);
229+
} else {
230+
convert_link_args_to_cc_args(l.cmd(), args);
198231
}
199232
l
200233
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
use super::*;
2+
3+
#[test]
4+
fn test_xlinker() {
5+
let mut cmd = Command::new("foo");
6+
convert_link_args_to_cc_args(&mut cmd, &[
7+
"arg1",
8+
"arg2",
9+
"arg3,with,comma",
10+
"arg4,with,comma",
11+
"arg5",
12+
"arg6,with,comma",
13+
]);
14+
15+
assert_eq!(cmd.get_args(), [
16+
OsStr::new("-Wl,arg1,arg2"),
17+
OsStr::new("-Xlinker"),
18+
OsStr::new("arg3,with,comma"),
19+
OsStr::new("-Xlinker"),
20+
OsStr::new("arg4,with,comma"),
21+
OsStr::new("-Wl,arg5"),
22+
OsStr::new("-Xlinker"),
23+
OsStr::new("arg6,with,comma"),
24+
]);
25+
}

0 commit comments

Comments
 (0)