忍者语言中是否有比 make 更快的东西?

B.S*_*.S. 7 makefile build ninja

我经常看到有人声称 Ninja 比 Make 更快,更擅长支持增量构建,并且更擅长并行化。这是实现质量问题还是 Ninja 语言中的某些内容可以实现这一点?

我知道 Ninja 和 Make 使用不同的文件格式来描述任务的依赖关系图。我知道 Make 允许使用比 ninja 更高级的功能,例如 globs。如果使用这样的高级功能,那么 Make 执行的任务比 Ninja 更复杂,我们不能指望 Make 更快。这是一种不公平的比较。

但是,假设不使用这种高级功能。没有通配符,没有模式规则,只是一遍又一遍地重复基本的“out_file: in_file1, in_file2\n\tcommand to build”。不使用这种高级功能会使 Make 和 Ninja 之间的竞争环境在他们执行的任务方面保持平衡。

我的理解是,如果我们以这种方式限制 Makefile,那么 Ninja 文件和 Makefile 可以很容易地相互转换。这样对吗?

为什么在有限的 Makefile 上执行的 Make 比 Ninja 慢?或者仅仅是标准 Make 实现没有针对以这种方式构建的 Makefile 进行优化的情况?

And*_*eas 12

简而言之,Ninja 解析速度更快,并且具有减少解析量的内置功能。

忍者手册的哲学概述来看

其他构建系统都是高级语言,而 Ninja 的目标是成为汇编程序。

Ninja 文件通常是从其他 makefile 中“编译”的,这使其成为一个两步过程,而 Make 是一个步骤。两步可能比普通 Make 慢。因为大多数情况下只需要第二步,因此最终效果是速度更快。这有点类似于比较编译和解释的程序。

Ninja 向 Make 添加了多个功能。在 makefile 中实现这些会导致 makefile 更长、更复杂,因此需要更多的解析。

  • Ninja 依赖项支持包括调用 `gcc -M`,就像 Make 一样,然后将 GCC 的输出(即 make 规则)转换为 ninja 规则。换句话说,它解决了如果您没有使用 Ninja,您一开始就不会遇到的问题。 (5认同)
  • 需要注意的是,缓冲输出自 4.0(2013)版本以来就在 GNU make 中可用,当然并行性也从那时起就一直可用。这些默认情况下不启用,但它们是命令行选项(默认情况下可以通过环境变量启用),因此它们不会花费任何 make 构建时间。而且,从 GNU make 4.3 开始,具有显式规则的多个输出的边(具有多个输出的隐式规则已被永久支持)具有内置支持。但是,我并不反对忍者手册该部分中提出的一般观点。 (3认同)
  • 我对忍者并不是很熟悉。我相信 Ninja 提供了某种类型的内置依赖项生成(例如自动找出哪些源文件包含哪些标头),而 GNU make 没有内置(如果您有一个现代的,这可以便宜地完成)像 GCC 或 clang 这样的编译器,但你必须自己做)。此外,如果命令行发生更改,Ninja 会自动重建,而 GNU make 则没有。Ninja 维护着有关上次构建的信息数据库;GNU make 不保留任何先前构建的状态。 (2认同)