On Fri, Feb 28, 2025 at 13:54:45 -0500, Paul Smith wrote: > On Fri, 2025-02-28 at 19:26 +0100, Ben Boeckel via Gcc wrote: > > > In POSIX make, including GNU Make, if a command doesn't modify the > > > modification time of the target then that target is not considered > > > updated, and other targets which list it as a prerequisite are not > > > invoked: > > > > Hmm. My understanding was that if a recipe is run, its outputs are > > assumed to have been updated. I forget where I saw that, but it > > sticks in my mind for some reason. Experimenting with GNU Make indeed > > does exhibit `restat = 1` behavior out-of-the-box. That's good to > > know :). I'll update my priors. > > There is one issue related to this: I don't know if Ninja addresses > this or not: maybe this is what people were thinking of? > > Because the modification time of the target is not updated, the recipe > for the the target will always be run (but targets that depend on it > will not be run).
Ah! Yes, that is a difference. Ninja records the "last run" mtime as a "shadow mtime" for the rule in its `.ninja_log` file. This is the mtime used when deciding to rerun the rule or not. Another difference is that this also encodes the command line last used for the output(s), so if *that* changes, it is also considered out-of-date. CMake has command line change detection, but it is much coarser: there's a file with information about all command lines in a given target and if that file changes, all commands in the target rerun. > This is the best that make can do, because it relies solely on the > filesystem as its database of "build state" and doesn't preserve any > build state of its own. Since "two"'s timestamp was not modified make > has no way to know that its recipe was actually run previously. > > If the recipe to build "two" is expensive, it's probably better to just > bite the bullet and allow "two" to be updated whenever its > prerequisites change. Yes, this is reminding me of details I had eventually compressed to "restat behavior isn't supported in make": it *works*, but is not *useful* because it never results in a "do nothing" build. > The only way for make to do better would be for it to keep its own > database of up-to-date notations, alongside or in addition to the > filesystem's modification time. That would be a major structural > change, of course. If it does happen, it would be *wonderful* to reuse `ninja`'s `.ninja_log` format. That would allow the usage of tools like `ninjatracing`[1] to get performance graphs of arbitrary `make` builds. Note that there is one fairly annoying thing with this in `ninja`: when using `sudo ninja`, the log file is written using the elevated permissions which makes further non-`sudo` usages…fail. See this issue: https://github.com/ninja-build/ninja/issues/1302 --Ben [1] https://github.com/nico/ninjatracing