Improving Ninja’s “-d explain” output
By David Röthlisberger. Tweet your comments @drothlis.
Published 21 Feb 2022.
Ninja’s “-d explain” command-line option is supposed to explain what caused a build target to be re-built, but it’s next to useless in a large build: It says what’s dirty but it’s hard to relate which dirty input caused which output to be re-built. At the beginning of your build you get pages & pages of “these things are dirty” and then it starts the actual build. Also, this “explain” output is printed before ninja has realised that a lot of those things aren’t actually dirty (thanks to “restat”).
I wrote pull request #2067 to make the explain output more useful. I have been using this for 6 weeks now and it works well. The implementation is dead simple: Instead of printing the explain string immediately, the EXPLAIN macro saves it to a map, and we print it later. So Ninja will use a bit more memory, but only if you use -d explain.
At my day job, a no-op build with -d explain used to print 1,800 lines of explain output alone (we use restat a lot!). With my patch, the entire output for the same no-op build is 93 lines:
|
|
Ninja’s original output on the left (some of it; the total output was 1,800 lines).
On the right, Ninja’s total output with my patch.
Future work
I have an elaborate fantasy where ninja could serialise the build graph to disk (or maybe just the subset of the graph that actually needed rebuilding). This could be augmented with the reason why each rule was run, and possibly even with the command output for each rule. Then the existing ninja tools like “graph”, “browse”, and “query” could load this graph instead of the “build.ninja” file, so that you can inspect interactively what happened the last time you ran Ninja.
You could even use the same “build.ninja” syntax for this serialisation, to avoid adding lots of new code to Ninja.
Realistically I’ll never get around to implementing this, and my current pull request gets me close enough.