20 comments

[ 3.8 ms ] story [ 39.7 ms ] thread
All the main build tools (cmake, meson/ninja and GNU configure) have different benefits. For instance, I expect "--help" to work, but only really GNU configure supports it as-is. I could list more advantages and disadvantages in general here, but by and large I prefer meson/ninja. To me it feels by far the fastest and I also have the fewest issues usually (excluding python breaking its pip stack but that's not the fault of meson as such). ninja can be used via cmake too but most uses I see are from meson.
The absolute best thing about coding agents is not having to waste time on build systems. I had Claude code port my autotools scripts to meson (which uses ninja) and it’s been a huge quality of life improvement.
I can remember having to uninstall ninja temporarily because it messed with building packages. I only use it because other packages need it.
Postgres uses Meson+Ninja in their builds. That seems like a pretty big endorsement.
Similar to make, it does mtime chronological comparison of dependencies with target to determinate if dependencies changed. This is just so flawed and simple to fool by operations on filesystem that do not change mtime (move, rename):

1) pick a source file and make a copy of it for for later 2) edit selected source file and rebuild 3) move the copy to it's original location 4) try to rebuild, nothing happens

Good point. I think it would be fixable by using the Change Time instead of the Modify Time, because that changes when moving the copy over the original.
I used ninja only a few years ago when contributing to KDE software (Dolphin, Kate, KTextEditor, etc.). I had no prior experience with it and it was easy to apprehend, so a rather good experience.
Ninja is one of the best tools I have used. It is extremely simple and always works flawlessly.

Some blog posts from the creator of ninja:

https://neugierig.org/software/blog/2018/07/options.html

https://neugierig.org/software/blog/2011/04/complexity.html

Also there was a post about why just generating ninja using python can be a good option. I do this in my project and it has been very productive so far. I couldn’t find this post now but it was saying to use ninja_syntax.py from ninja codebase and just doing something minimal for a project

An under noticed ninja feature I adore, which was implemented relatively recently, is the ability to configure how its build progress is printed. In my fish config, I have the `NINJA_STATUS` envvar:

    set -x NINJA_STATUS "STEP: %f/%t  
    [%p / %P] 
    [%w + %W]
    "
Which prints the time elapsed and projected in a readable multi-line format.
Serious question: how can a build tool be fast or slow? From my understanding all it does is delegate the build steps to other tools, so wouldn't those be the bottleneck? Is it the resolution of order of build steps that takes so much time that a different build system can make a difference?
In my observations ninja more consistently uses multiple CPUs than GNU make. e. g. make -j40 will run up to 40 parallel processes (of clang/gcc) but a significant fraction of the time it will less than 40. With ninja average CPU utilization AFAIR was higher reducing build time. Not sure if it's specific to the project I was building (and how cmake generates makefiles) or would work for other projects too.
Ninja is possibly the best example of the "Do one thing and do it well" philosophy. All it does is execute commands based on a static build graph.

It's syntax is simple enough that it's trivial to e.g. write a shell script to generate the build items if you need dynamic dependencies.

Ninja is great and feels natural coming from Make. What it lacks in features it makes up for with speed, which is what ultimately matters.

Also worth mentioning is samurai[1], a pure C implementation of Ninja that's almost as fast yet easier to bootstrap needing only a C compiler.

[1] https://github.com/michaelforney/samurai