定义
Ninja 是一个小型构建系统,以速度为核心目标[2]。它接收文件之间的相互依赖关系(通常为源代码与输出的可执行文件),并快速调度它们的构建过程。
在实际定位上,Ninja 往往不直接由人手工编写配置,而是作为 CMake、Meson、GN 等更高级别构建系统的执行后端[3]。它自身功能极为精简,只保留描述任意依赖图所必需的最小能力。
原理
Ninja 的工作方式建立在一个文件级的有向无环图之上。构建文件(默认名为 build.ninja)由一组规则(rule)和一组构建语句(build)组成:构建语句描述项目文件的依赖关系,规则描述沿图中某条边生成文件所用的命令。
判断某个输出是否需要重建时,Ninja 主要比较文件修改时间,并检查命令行是否发生变化[4]。若输出文件缺失、其时间戳早于最新输入,或记录在 .ninja_log 中的命令哈希与当前命令不一致,该边就会被重新执行[4]。
依赖图的遍历顺序由关键路径权重决定:Ninja 自底向上为每条边累加权重,优先派发处于最长依赖链上的就绪任务[4]。构建默认按 CPU 核数并行执行,也可以通过池(pool)为某类开销较大的规则单独限制并发数。
对于 C/C++ 头文件依赖,Ninja 支持通过 depfile 属性读取编译器输出的 Makefile 格式依赖信息,也支持 deps = gcc 或 deps = msvc 的方式在命令结束后立即处理依赖,并把压缩后的结果存入内部的 .ninja_deps 数据库。
发展历程
Ninja 由 Google 工程师埃文·马丁开发,诞生的直接背景是 Chromium 项目的构建速度问题[1]。该项目的旧构建系统在只改动一个文件后,启动构建需要约 10 秒,而 Ninja 可以把这个时间压到 1 秒以内。
维基百科记载 Ninja 由埃文·马丁于 2010 年在 Chrome 团队工作时开发,当时他在 Linux 上先后尝试将 SCons 和 make 作为 GYP 的目标构建系统,都因速度问题不满意[1]。改用 Ninja 后,修改文件后的 Chrome 增量构建时间降到约 6 秒[1]。
埃文·马丁于 2014 年 4 月将维护者职责移交给同样来自 Chrome 团队的尼科·韦伯(Nico Weber)[5]。Ninja 以 Apache 2.0 许可证发布,代码使用 C++ 编写[5]。
2025 年,Ninja 1.13 版本加入了作为 GNU Make 作业服务器(jobserver)客户端的能力,使嵌套构建可以共享同一个作业配额[4]。目前最新的稳定版本之一为 1.13.2[3]。
应用
Ninja 被用于构建 Google Chrome、Android 的部分组件以及 LLVM,同时借助 CMake 的 Ninja 后端可以用于许多其他项目[2]。Chromium 是 Ninja 最主要的使用者和最初的开发动机[3]。
生成 Ninja 构建文件的工具包括 GYP、CMake、Meson 和 GN,其中 GN 是 Google Chrome 及相关项目(如 V8、Node.js 与 Google Fuchsia)所使用的元构建系统。此外,许多项目使用专有脚本来生成构建文件[1]。
Ninja 在主流 Linux 发行版中一般以 ninja-build 为包名提供,因为构建 Chromium 需要用到它[5]。它支持类 Unix 系统与 Windows,在 Linux 上测试最充分、性能也最好。
局限
Ninja 的构建文件被刻意设计为不适合手工书写,其语法缺少条件判断、循环、函数和通配等能力,因此实际使用中几乎必须配合一个生成器程序。开箱即用时,Ninja 自身不包含编译 C 代码之类的内置规则。
Ninja 不具备依赖管理能力,没有版本、注册表或锁文件的概念,所有参与构建的输入文件都必须已经存在于磁盘上,或由另一条构建边生成[4]。它也没有内建的构建缓存、远程缓存和远程执行能力,跨机器复用结果需要在命令层面借助外部工具包装编译器,或改用其他执行器[4]。
由于默认以修改时间而非文件内容哈希来判断变化,被触碰但内容未变的文件也会触发重建[4]。此外,Ninja 不提供沙箱隔离,未声明的文件读取不会被察觉,正确性依赖于生成器的规范编写与 missingdeps 等诊断工具的检查[4]。
对于规模较小的项目,Ninja 带来的速度差异通常难以察觉,此时另加一个生成器步骤反而会增加不必要的复杂度。
参见
参考资料
- Ninja (构建系统) [引用日期2026-10-14]
- Ninja [引用日期2026-10-14]
- Ninja (build system) [引用日期2026-10-14]
- github.com 上的网页 [引用日期2026-10-14]
- eklektix.com 上的网页 [引用日期2026-10-14]