Evan Martin (evmar) started Ninja when he was working on Chrome at Google:
https://neugierig.org/software/chromium/notes/2011/02/ninja....
Hence, it's used in a lot of Google projects.
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.
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.If someone sees this: The ninja package on PyPI [0] currently stays at version 1.13.0 . There is an issue in 1.13.0 preventing it building projects on Windows. The issue is already fixed in 1.13.1 almost a year ago, but the PyPI package hasn't got an update, see [1], and many downstream projects have to stay at 1.11 . I hope it could update soon.
[0] https://pypi.org/project/ninja/
[1] https://github.com/scikit-build/ninja-python-distributions/i...
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.
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
Postgres uses Meson+Ninja in their builds. That seems like a pretty big endorsement.
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?
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.
My teammate has a great time reimplementing Ninja (slop-free) in Go here https://github.com/buildbuddy-io/reninja to make it even faster with Remote Build Execution.
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.
Ninja religions following of treating timestamps (mtime) as 'modified' marker makes it useless with Git and large projects.
You switched some branches back and forward? Enjoy your 20 minutes rebuild.
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.
[dead]
[dead]
I can remember having to uninstall ninja temporarily because it messed with building packages. I only use it because other packages need it.
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