Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 37 additions & 11 deletions cargo-auditable/src/rustc_arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,29 @@ impl RustcArgs {
}
result
}

/// Normally `rustc` uses a C compiler such as `cc` or `clang` as linker,
/// and arguments to the actual linker need to be passed prefixed with `-Wl,`.
/// But it is possible to configure Cargo and rustc to call a linker directly,
/// and the breakage it causes is subtle enough that people just roll with it
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😂

/// and complain when cargo-auditable doesn't support this configuration:
/// <https://github.com/rust-secure-code/cargo-auditable/issues/202>
///
/// This function can tell you if a bare linker is in use
/// and whether you need to prepend `-Wl,` or not.
///
/// Such setups are exceptionally rare and frankly it's a misconfiguration
/// that will break more than just `cargo auditable`, but I am feeling generous.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🙏

pub fn bare_linker(&self) -> bool {
let linker_flag = self.codegen.iter().find(|s| s.starts_with("linker="));
if let Some(linker_flag) = linker_flag {
let linker = linker_flag.strip_prefix("linker=").unwrap();
if linker.ends_with("ld") {
return true;
}
}
false
}
}

impl RustcArgs {
Expand Down Expand Up @@ -149,11 +172,7 @@ mod tests {

#[test]
fn multiple_emit_values() {
let raw_rustc_args = vec![
"--emit=dep-info,link",
"--emit",
"llvm-bc",
];
let raw_rustc_args = vec!["--emit=dep-info,link", "--emit", "llvm-bc"];
let raw_rustc_args: Vec<OsString> = raw_rustc_args.into_iter().map(|s| s.into()).collect();
let mut args = RustcArgs::from_vec(raw_rustc_args).unwrap();

Expand All @@ -166,13 +185,18 @@ mod tests {
assert_eq!(args.emit, expected)
}

#[test]
fn detect_bare_linker() {
let raw_rustc_args = vec!["-C", "linker=rust-lld"];
let raw_rustc_args: Vec<OsString> = raw_rustc_args.into_iter().map(|s| s.into()).collect();
let mut args = RustcArgs::from_vec(raw_rustc_args).unwrap();

assert!(args.bare_linker());
}

#[test]
fn multiple_codegen_options() {
let raw_rustc_args = vec![
"-Clinker=clang",
"-C",
"link-arg=-fuse-ld=/usr/bin/mold",
];
let raw_rustc_args = vec!["-Clinker=clang", "-C", "link-arg=-fuse-ld=/usr/bin/mold"];
let raw_rustc_args: Vec<OsString> = raw_rustc_args.into_iter().map(|s| s.into()).collect();
let mut args = RustcArgs::from_vec(raw_rustc_args).unwrap();

Expand All @@ -182,6 +206,8 @@ mod tests {
args.codegen.sort();
expected.sort();

assert_eq!(args.codegen, expected)
assert_eq!(args.codegen, expected);

assert!(!args.bare_linker());
}
}