Derive header prerequisites with -MMD -MP instead of listing them by hand
#1741
Replies: 2 comments 2 replies
|
Yes, this is a direction I want, and a prototype PR is welcome. Your numbers hold on I checked the one-command case with GCC 13 and it behaves as you describe, including a test that includes
What I'd ask of the PR:
On timing: this touches every engine rule, so it will conflict once with every open PR that edits the Makefile. Right after 1.12.1 is the cheapest moment for that, so whenever you are ready. |
|
This looks cleaner than maintaining another dependency list by hand. The one thing I'd test in the real Makefile before switching is the compile+link-in-one-command case, because dependency-file naming gets awkward when there isn't a normal per-source object target. If the generated dependency path is deterministic for every engine and clean.py removes it, -MMD -MP seems like a better source of truth than the long prerequisite lines. I'd also keep one regression test that touches a header and verifies the engine rebuilds. |
Uh oh!
There was an error while loading. Please reload this page.
In #1284 you asked for the engine list in
test_makefile_deps.pyto be derived from the Makefile rather than kept by hand, so that "there is no list to keep in sync". This proposes the same idea one level down: let the compiler derive each engine's header prerequisites.Why it matters. Each engine rule in
c/Makefilelists its headers on one hand-written line. Anyone adding a header edits that line, and #1284 showed what happens when someone doesn't:makereports success and leaves a stale binary. Its test now catches the drift, but the line itself keeps moving. Ondevover the last 30 days, 30 of the 132 commits touchingc/Makefilechanged an engine prerequisite line, by 17 different authors. Every open PR that touches the same rule conflicts on it. My own #1261 resolved that same line in 9 of its 20 merges fromdev.None of this is hard, but all of it takes attention. Each conflict needs someone to stop, reconcile two versions of one long line and wait for CI again, and each forgotten header is a bug nobody sees until a stale binary misbehaves. That cost lands on contributors and on the maintainer reviewing their merges, over and over, for work that is purely mechanical. Once the prerequisites are generated, the line no longer exists, so there is nothing to conflict on and nothing to forget.
The change. Add
-MMD -MPto the compile flags and-includethe generated.dfiles. The engine rules then only name their sources, objects and.build-config. The compiler records every header actually included,-MPkeepsmakefrom failing when a header is deleted, and the.dfiles joinclean.py.Checked with the project's MinGW gcc on a minimal copy of the patterns used here:
colibri$(EXE).dwritten with the right headers#includes../engine.cmakerebuildsmakestill succeeds, thanks to-MPNot checked, and where I'd expect friction: the nvcc and MSVC-hosted CUDA builds; Clang on macOS, which supports the flags, but I haven't run it;
Makefile.deepseek-v4.units; and whattest_makefile_deps.pyshould become. It might check that the.dfiles exist and cover each engine's sources, rather than compare two hand lists.If this is a direction you'd want, I'm happy to prototype it as a PR. If the hand lists are deliberate for a reason I'm not seeing, that's useful to know too.
All reactions