ninja: Fast Parallel Builds in CI
ninja reads a build.ninja file and runs the minimal set of commands to bring targets up to date, in parallel by default.
Ninja is designed to be generated, not hand-written: CMake and Meson emit build.ninja for it. It builds faster than Make because it parallelizes aggressively and tracks dependencies precisely.
What it does
ninja executes the build graph in build.ninja, running only the steps whose inputs changed. By default it uses a parallelism of the number of CPUs plus a small margin, so you rarely need to pass -j on a dedicated runner.
Common usage
ninja # build the default target in the cwd
ninja -C build # build in the build/ directory
ninja -C build -j 8 # limit to 8 parallel jobs
ninja -C build installOptions
| Flag | What it does |
|---|---|
| -C <dir> | Change to <dir> before reading build.ninja |
| -j <N> | Run N jobs in parallel (default: CPUs + 2) |
| -t <tool> | Run a subtool: clean, graph, compdb, deps, targets |
| -n | Dry run: show what would build without running |
| -v | Verbose: print full command lines |
| -k <N> | Keep going until N jobs fail (0 = keep going always) |
In CI
Ninja auto-detects core count, so you usually skip -j; set it only to cap memory on RAM-limited runners. ninja -t compdb > compile_commands.json emits a compile database for clang-tidy. Use ninja -C build rather than cd so the step is one line.
Common errors in CI
"ninja: error: loading 'build.ninja': No such file or directory" means the project was never configured (run cmake -G Ninja or meson setup first) or you are in the wrong directory (use -C). "ninja: error: unknown target" means a typo or the target is not in this build. "ninja: build stopped: subcommand failed" is the generic wrapper around a compiler error; scroll up for the real message.