Ninja

关注
义项:构建系统
Ninja

Ninja 是一个专注于速度的小型构建系统,由 Google 工程师埃文·马丁(Evan Martin)在参与 Chromium 浏览器项目时开发[1]。它与其他构建系统有两点显著区别:其输入文件被设计为由更高级的构建系统生成,并且被设计成尽可能快地执行构建[2]。Ninja 通常作为 CMake、Meson、GN 等元构建系统的后端执行引擎使用,被 Chromium、LLVM、Android 等大型项目采用[3]。

百科 图文
目录
  1. 定义
  2. 原理
  3. 发展历程
  4. 应用
  5. 局限
  6. 参见

定义

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 带来的速度差异通常难以察觉,此时另加一个生成器步骤反而会增加不必要的复杂度。

参见

  • CMake —— 常用的元构建系统,可将项目配置生成为 Ninja 构建文件。

  • Meson —— 以 Ninja 作为默认后端的构建系统。

  • Make —— 与 Ninja 定位最接近的传统构建工具,Ninja 常被视为其替代方案。

  • Chromium —— Ninja 最初为该项目开发,也是其最主要的使用者。

  • LLVM —— 通过 CMake 使用 Ninja 的大型编译器项目。

参考资料

  1. Ninja (构建系统) [引用日期2026-10-14]
  2. Ninja [引用日期2026-10-14]
  3. Ninja (build system) [引用日期2026-10-14]
  4. github.com 上的网页 [引用日期2026-10-14]
  5. eklektix.com 上的网页 [引用日期2026-10-14]
词条评价
词条统计

浏览次数:2 次

阅读量:0 次 · 阅读完成量:0 次

最近更新:2026-10-13T22:16:51Z

历史版本

本条目引用的词条
CMake Meson Chromium Google Chrome Make LLVM