Skip to content

Commit 9eefc45

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 56f1bdb commit 9eefc45

File tree

3 files changed

+26
-15
lines changed

3 files changed

+26
-15
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [Unreleased]
88

9+
- Include compiler wrapper arguments (i.e., `CC=compiler arg1 arg2`) in the classification of compilers' tool family. This fixes cases like `clang --driver-mode=cl` being incorrectly detected as needing `clang`-like arguments, rather than `cl`-like arguments. [#????](https://github.com/rust-lang/cc-rs/????).
10+
911
## [1.2.10](https://github.com/rust-lang/cc-rs/compare/cc-v1.2.9...cc-v1.2.10) - 2025-01-17
1012

1113
### Other

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ struct BuildCache {
277277
env_cache: RwLock<HashMap<Box<str>, Env>>,
278278
apple_sdk_root_cache: RwLock<HashMap<Box<str>, Arc<OsStr>>>,
279279
apple_versions_cache: RwLock<HashMap<Box<str>, Arc<str>>>,
280-
cached_compiler_family: RwLock<HashMap<Box<Path>, ToolFamily>>,
280+
cached_compiler_family: RwLock<HashMap<(Box<Path>, Vec<String>), ToolFamily>>,
281281
known_flag_support_status_cache: RwLock<HashMap<CompilerFlag, bool>>,
282282
target_info_parser: target::TargetInfoParser,
283283
}

src/tool.rs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ pub struct Tool {
4040
impl Tool {
4141
pub(crate) fn new(
4242
path: PathBuf,
43-
cached_compiler_family: &RwLock<HashMap<Box<Path>, ToolFamily>>,
43+
cached_compiler_family: &RwLock<HashMap<(Box<Path>, Vec<String>), ToolFamily>>,
4444
cargo_output: &CargoOutput,
4545
out_dir: Option<&Path>,
4646
) -> Self {
@@ -57,7 +57,7 @@ impl Tool {
5757
pub(crate) fn with_args(
5858
path: PathBuf,
5959
args: Vec<String>,
60-
cached_compiler_family: &RwLock<HashMap<Box<Path>, ToolFamily>>,
60+
cached_compiler_family: &RwLock<HashMap<(Box<Path>, Vec<String>), ToolFamily>>,
6161
cargo_output: &CargoOutput,
6262
out_dir: Option<&Path>,
6363
) -> Self {
@@ -90,7 +90,7 @@ impl Tool {
9090
path: PathBuf,
9191
args: Vec<String>,
9292
cuda: bool,
93-
cached_compiler_family: &RwLock<HashMap<Box<Path>, ToolFamily>>,
93+
cached_compiler_family: &RwLock<HashMap<(Box<Path>, Vec<String>), ToolFamily>>,
9494
cargo_output: &CargoOutput,
9595
out_dir: Option<&Path>,
9696
) -> Self {
@@ -114,21 +114,25 @@ impl Tool {
114114
fn guess_family_from_stdout(
115115
stdout: &str,
116116
path: &Path,
117+
args: &[String],
117118
cargo_output: &CargoOutput,
118119
) -> Result<ToolFamily, Error> {
119120
cargo_output.print_debug(&stdout);
120121

121122
// https://gitlab.kitware.com/cmake/cmake/-/blob/69a2eeb9dff5b60f2f1e5b425002a0fd45b7cadb/Modules/CMakeDetermineCompilerId.cmake#L267-271
122123
// stdin is set to null to ensure that the help output is never paginated.
123-
let accepts_cl_style_flags =
124-
run(Command::new(path).arg("-?").stdin(Stdio::null()), path, &{
124+
let accepts_cl_style_flags = run(
125+
Command::new(path).args(args).arg("-?").stdin(Stdio::null()),
126+
path,
127+
&{
125128
// the errors are not errors!
126129
let mut cargo_output = cargo_output.clone();
127130
cargo_output.warnings = cargo_output.debug;
128131
cargo_output.output = OutputKind::Discard;
129132
cargo_output
130-
})
131-
.is_ok();
133+
},
134+
)
135+
.is_ok();
132136

133137
let clang = stdout.contains(r#""clang""#);
134138
let gcc = stdout.contains(r#""gcc""#);
@@ -153,6 +157,7 @@ impl Tool {
153157

154158
fn detect_family_inner(
155159
path: &Path,
160+
args: &[String],
156161
cargo_output: &CargoOutput,
157162
out_dir: Option<&Path>,
158163
) -> Result<ToolFamily, Error> {
@@ -207,25 +212,29 @@ impl Tool {
207212
&compiler_detect_output,
208213
)?;
209214
let stdout = String::from_utf8_lossy(&stdout);
210-
guess_family_from_stdout(&stdout, path, cargo_output)
215+
guess_family_from_stdout(&stdout, path, args, cargo_output)
211216
} else {
212-
guess_family_from_stdout(&stdout, path, cargo_output)
217+
guess_family_from_stdout(&stdout, path, args, cargo_output)
213218
}
214219
}
215-
let detect_family = |path: &Path| -> Result<ToolFamily, Error> {
216-
if let Some(family) = cached_compiler_family.read().unwrap().get(path) {
220+
let detect_family = |path: &Path, args: &[String]| -> Result<ToolFamily, Error> {
221+
let cache_key = (Box::from(path), args.to_vec());
222+
if let Some(family) = cached_compiler_family.read().unwrap().get(&cache_key) {
217223
return Ok(*family);
218224
}
219225

220-
let family = detect_family_inner(path, cargo_output, out_dir)?;
226+
let family = {
227+
let (path, args) = &cache_key;
228+
detect_family_inner(path, args, cargo_output, out_dir)?
229+
};
221230
cached_compiler_family
222231
.write()
223232
.unwrap()
224-
.insert(path.into(), family);
233+
.insert(cache_key, family);
225234
Ok(family)
226235
};
227236

228-
let family = detect_family(&path).unwrap_or_else(|e| {
237+
let family = detect_family(&path, &args).unwrap_or_else(|e| {
229238
cargo_output.print_warning(&format_args!(
230239
"Compiler family detection failed due to error: {}",
231240
e

0 commit comments

Comments
 (0)