Skip to content

Commit 17c805a

Browse files
fix: include wrapper args. in stdout family heuristics
This can be particularly significant for compilers that can dynamically change what options they accept based on arguments, like `clang --driver-mode=cl`.
1 parent 50a3f70 commit 17c805a

File tree

1 file changed

+22
-12
lines changed

1 file changed

+22
-12
lines changed

src/tool.rs

+22-12
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::{
1616
Error, ErrorKind, OutputKind,
1717
};
1818

19-
pub(crate) type CompilerFamilyLookupCache = HashMap<Box<Path>, ToolFamily>;
19+
pub(crate) type CompilerFamilyLookupCache = HashMap<Box<[OsString]>, ToolFamily>;
2020

2121
/// Configuration used to represent an invocation of a C compiler.
2222
///
@@ -116,21 +116,25 @@ impl Tool {
116116
fn guess_family_from_stdout(
117117
stdout: &str,
118118
path: &Path,
119+
args: &[String],
119120
cargo_output: &CargoOutput,
120121
) -> Result<ToolFamily, Error> {
121122
cargo_output.print_debug(&stdout);
122123

123124
// https://gitlab.kitware.com/cmake/cmake/-/blob/69a2eeb9dff5b60f2f1e5b425002a0fd45b7cadb/Modules/CMakeDetermineCompilerId.cmake#L267-271
124125
// stdin is set to null to ensure that the help output is never paginated.
125-
let accepts_cl_style_flags =
126-
run(Command::new(path).arg("-?").stdin(Stdio::null()), path, &{
126+
let accepts_cl_style_flags = run(
127+
Command::new(path).args(args).arg("-?").stdin(Stdio::null()),
128+
path,
129+
&{
127130
// the errors are not errors!
128131
let mut cargo_output = cargo_output.clone();
129132
cargo_output.warnings = cargo_output.debug;
130133
cargo_output.output = OutputKind::Discard;
131134
cargo_output
132-
})
133-
.is_ok();
135+
},
136+
)
137+
.is_ok();
134138

135139
let clang = stdout.contains(r#""clang""#);
136140
let gcc = stdout.contains(r#""gcc""#);
@@ -155,6 +159,7 @@ impl Tool {
155159

156160
fn detect_family_inner(
157161
path: &Path,
162+
args: &[String],
158163
cargo_output: &CargoOutput,
159164
out_dir: Option<&Path>,
160165
) -> Result<ToolFamily, Error> {
@@ -209,25 +214,30 @@ impl Tool {
209214
&compiler_detect_output,
210215
)?;
211216
let stdout = String::from_utf8_lossy(&stdout);
212-
guess_family_from_stdout(&stdout, path, cargo_output)
217+
guess_family_from_stdout(&stdout, path, args, cargo_output)
213218
} else {
214-
guess_family_from_stdout(&stdout, path, cargo_output)
219+
guess_family_from_stdout(&stdout, path, args, cargo_output)
215220
}
216221
}
217-
let detect_family = |path: &Path| -> Result<ToolFamily, Error> {
218-
if let Some(family) = cached_compiler_family.read().unwrap().get(path) {
222+
let detect_family = |path: &Path, args: &[String]| -> Result<ToolFamily, Error> {
223+
let cache_key = [path]
224+
.iter()
225+
.map(|p| p.as_os_str().to_owned())
226+
.chain(args.iter().map(|a| OsStr::new(a).to_owned()))
227+
.collect();
228+
if let Some(family) = cached_compiler_family.read().unwrap().get(&cache_key) {
219229
return Ok(*family);
220230
}
221231

222-
let family = detect_family_inner(path, cargo_output, out_dir)?;
232+
let family = { detect_family_inner(path, args, cargo_output, out_dir)? };
223233
cached_compiler_family
224234
.write()
225235
.unwrap()
226-
.insert(path.into(), family);
236+
.insert(cache_key, family);
227237
Ok(family)
228238
};
229239

230-
let family = detect_family(&path).unwrap_or_else(|e| {
240+
let family = detect_family(&path, &args).unwrap_or_else(|e| {
231241
cargo_output.print_warning(&format_args!(
232242
"Compiler family detection failed due to error: {}",
233243
e

0 commit comments

Comments
 (0)