Rebuild when an #included header changes #31
No reviewers
Labels
No labels
bug
claude:blocked
claude:done
claude:failed
claude:in-progress
claude:ready
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Catcrafts/Crafter.Build!31
Loading…
Reference in a new issue
No description provided.
Delete branch "claude/issue-30"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The incremental check compared each artifact against its own source and its module imports. Headers were in neither set — the scanner reads
importlines, and a.cppm/.cppkeeps its mtime when a header it includes is edited — so a header-only edit reported nothing to do and left objects compiled against the previous contents. Silent, and the same mixed-layout failure shape as #27, reached through#includeinstead ofimport.What changed
-MD -MF <artifact>.d, so the compiler reports what it actually opened.NewestPrerequisite(Platform) reads that file back and returns the newest prerequisite mtime; eachCheckfolds it into the comparison against the artifact. A missing depfile (an object from a crafter-build that wrote none) or a prerequisite that no longer exists returnsfile_time_type::max()— rebuild once, since neither state is evidence of freshness.:is a rule target (which also keeps WindowsC:\...paths intact)..crecompiled its object and then linked nothing. Found by the new test, where a rebuiltcounter.cproduced a binary still printing the old value..cu-mtime only — nvcc's-MD/-MFare untested here, noted in place.Tests
New
tests/IncrementalHeaderChange: one header per pass, asserting both directions (the objects that include it recompile, the ones that don't are untouched), then running the binary — "was recompiled" only matters if the program agrees with itself. Covers the module interface (a macro in its global module fragment decides an exported class's layout), the implementation unit, a C source, an idle rebuild that must recompile nothing, and an object whose depfile is gone. The implementation unit's header has a space in its name so the depfile spells it escaped.With the depfile lookup stubbed out, 9 of its assertions fail; with it, all pass. Full suite: 20 passed, 0 failed.
Also verified by hand on this repo:
touch lib/DirStackFileIncluder.hnow recompiles exactlyCrafter.Build-Shader.cppand relinks (previously: nothing), and a no-change rebuild still compiles nothing.Resolves #30
🤖 Generated with Claude Code