fix: honor Build::env overrides in flag support probes - #1866
Conversation
`is_flag_supported_inner` built its probe from a fresh `Build`, dropping
`Build::env` along with the out dir and the caches. The probe therefore
resolved a bare compiler name such as `cc` through the ambient `PATH`
rather than the one the compile commands run in, and answered a question
about a different compiler than the one being built with. Compiler
family detection had the same gap at four more spawns: they applied no
environment at all, and `Tool::with_features` was never handed one.
Both now run in the environment `Build::env` sets up, and the family
lookup cache is keyed on that environment as well as the path and
arguments, so two builds that differ only in it cannot share an answer.
Reaching the right compiler means the probes now reach the test shim,
where they would have taken `out{i}` slots and shifted the numbering
every assertion depends on. Two variables opt one class of probe in by
name instead: `CC_SHIM_OUT_FILES_FOR_FAMILY_DETECTION` and
`CC_SHIM_OUT_FILES_FOR_FLAG_SUPPORT_CHECK`. cc renames the one matching
the probe it is about to spawn to `CC_SHIM_OUT_FILES`, rather than
copying `Build::env` over blindly, so a probe no test asked about
records nothing at all. That replaces the `-c` sniffing the shim did to
guess whether it was looking at a flag probe, and the panic on a missing
`CC_SHIM_OUT_DIR` that family detection relied on to keep failing.
`gnu_flag_if_supported` no longer skips Windows. It needed the probe to
reject a flag and got that from whatever compiler the machine happened
to have installed; it now says so with `CC_SHIM_FAIL_IF_ARG`.
Refs rust-lang#1859
NobodyXu
left a comment
There was a problem hiding this comment.
Thank you so much!
Just some feedback on code but should be quite to settle
Yeah that indeed worth a separate PR, thank you for this PR! |
Four things from the review, no behaviour change. The shim collected argv twice. `split_first` gives the program and the rest in one step, and `record` now takes `&[String]` rather than `&[&String]`. The probe `Build` copies the env with `clone_from` instead of replaying it key by key. `ProbeKind` and `set_probe_env` are private again, behind a `CommandExt` trait with `set_family_detection_env` and `set_flag_supported_env`, so a caller names the probe class instead of passing an enum. The test harness gained `collect_family_detection_probes` and `collect_flag_supported_probes` with matching getters, so a test opts a class in by name and `CC_SHIM_OUT_FILES_FOR_*` stays inside the harness. The getters take an index because `clang_cl_scope_all` records two flag support probes in one build, so a single file per class was not enough.
|
All four done in 94eca3a. Thanks, the The extra collect. Gone.
The harness helper. One deviation from your sketch, and it is the only place I did not follow it exactly. The getters take an index: pub fn get_flag_supported_probes(&self, i: usize) -> Execution
Verified on Windows 11,
One honest note on the test run. And agreed on |
NobodyXu
left a comment
There was a problem hiding this comment.
Thanks, just two final nits, and it'd be ready for merge
| fn probe<'cmd>(cmd: &'cmd mut Command, env: &BuildEnv) -> &'cmd mut Command { | ||
| cmd.set_family_detection_env(env); |
There was a problem hiding this comment.
Do we still need this function? I think we can remove it?
| /// them by name with [`Test::probe_out_files`], so this numbering covers | ||
| /// the compile and archive commands only. | ||
| pub fn cmd(&self, i: u32) -> Execution { | ||
| self.execution(self.td.path().join(format!("out{}", i))) |
There was a problem hiding this comment.
Can we use
| self.execution(self.td.path().join(format!("out{}", i))) | |
| self.execution(self.probe_slot("out", i)) |
|
Both done in f028de4. The Command::new(path).arg("--version").set_family_detection_env(env)
Verified on Windows 11, One piece of sequencing, since you mentioned merging this one first. #1867 still points at the pre-nit commit, because it was already approved and I did not want to force-push a rebase under the approval. If this lands as a squash, #1867's branch will carry the old versions of |
NobodyXu
left a comment
There was a problem hiding this comment.
Thank you, LGTM! Will wait for rebase on the follow-up PR
Implements the design settled in #1859.
is_flag_supported_innerbuilds its probeBuildwithout copyingself.env, soBuild::envoverrides are ignored by flag probes: the probe resolves a bareccthrough the ambientPATHand answers about a different compiler than the one being built with. Since #1845 made-mno-omit-leaf-frame-pointerconditional onis_flag_supported, that silently changes flags. Family detection insrc/tool.rshad the same gap at four more spawns, which applied no environment at all.Copying
self.envalone shifts the shim'sout{N}indices, so this addsCC_SHIM_OUT_FILES_FOR_FAMILY_DETECTIONandCC_SHIM_OUT_FILES_FOR_FLAG_SUPPORT_CHECK. cc renames the class-appropriate one toCC_SHIM_OUT_FILESbefore spawning that probe; when it is absent the probe records nothing, per your call in #1859.cached_compiler_familyis now keyed on the probe environment too, so two builds differing only inBuild::envcannot share a family answer.Baseline
caf7609vs this branch,cargo nextest run --no-fail-fast --workspace, x86_64-pc-windows-msvc:gnu_debug_fpgnu_debug_fp_autoclang_androidprobe_env_overridesDoc tests 28 to 28, no regressions.
clippy --no-deps --workspace --all-targets -- -D warningsclean,fmt --checkclean, andcargo check -p ccpasses on 1.65.0.Three things worth your attention:
Once detection runs under
Build::envit reaches the shim, which emitted no family macros but exited 0 on-?, so everyTest::gnu()compiler classified as MSVC. Previously detection failed only because the shim panicked on a missingCC_SHIM_OUT_DIR. The shim now declines-Eexplicitly rather than learning to preprocess. Family answers match baseline for every shim name in the suite.clang_androidis the same root cause at a third site —src/lib.rs:3723probesllvm-arwith a bareCommand::new, bypassingBuild::env'sPATH. I left it out: fixing it needs a third recording class, which expands a design you settled at two, and it needs its own test since your CI runners ship a realllvm-ar. Happy to send it separately.Everything above is Windows-only. I audited the
cfg(not(windows))tests for dependence on a real compiler and converted the one that needed a probe rejection, but your CI settles Unix.#851 and #1632 touch the same region of
src/lib.rs; neither implements this design and this does not subsume them.LLM usage, per the Rust policy: this change was developed with AI assistance (Claude). Adding this retroactively, since it should have been disclosed when the PR was opened.