Ninja Build System

Ninja is a bare-metal build system, conceptually similar to Make. It is intended to be generate by a meta-build system (think of assembly code generated by a compiler from a high-level language).

  • Ninja evaluates a dependency graph among files (similar to Make).
  • Ninja is designed to be very fast.
  • Almost all build-time decisions (compiler flags, release vs debug mode, etc.) are made by the meta-build system.

A .ninja file has variables, rules, build statements, etc.

# Variables are bindings; they can only be shadowed.
cflags = -Wall

# Rules declare a short name (e.g., cc) for a command line,
# followed by a rule block, which is an indented set of
#   variable = value
# lines.
rule cc
  command = gcc $cflags -c $in -o $out

# Build statements declare dependencies among files of the form:
#   build outputs: rule inputs.
#     optional build block
build foo.o: cc foo.c

# And some other stuff.

Notes:

  • You may shadow variables in a build block.
  • Ninja has a special variable depfile explicitly support C/C++ header dependencies.
  • '\t' and '\r' are currently disallowed.
  • You may specify the top-level .ninja file as an output of any build statement (and Ninja will rebuild and reload it before building the requested targets).
  • Create alias or dummy targets with the phony rule.
  • Ninja tracks commands used to build stuff in a Ninja log (e.g., .ninja_log) and rebuilds stuff whenever commands are changed.
  • Pools (restricting parallelism) and the console pool.

Three types of dependencies:

  • Explicit dependencies: These are available as the $in variable.
  • Implicit dependencies: | deps and depfile. They are the same as the explicit dependencies except that they don’t show up in $in.
  • Order-only dependencies: || deps. They trigger a rebuild only when they are rebuilt (not when they are out of date).
Creative Commons License
This blog by Che-Liang Chiou is licensed under a Creative Commons Attribution 4.0 International License.