CMake + Ninja 构建不会跨库并行化

CMake + Ninja build does not parallelize across libraries

我们有一个 (C++) 程序,它被设置为一系列具有嵌套层次结构的共享库。也就是说,libB.so 使用来自 libA.so 的函数并链接到 libA.so,libC.so 使用来自 libB.so 和 libA.so 的函数并链接到 libA.so,等等

对于我们当前的 CMake+Ninja 构建系统,我注意到并行构建似乎不会跨库发生。也就是说,虽然 Ninja 通常会使用 12 个核心来构建,但如果我触及了 libA 中的单个源文件但在 libC 中触及了多个源文件,则 ninja 将仅使用单个处理器来构建 libA 源文件,直到 libA.so链接,此时它将使用 12 个处理器来编译 libC 源文件。 - 如果 libA 源代码编译出错,它甚至不会尝试将 libC 文件编译成目标文件,即使我将 -k 传递给 ninja。

当然,libC.so 的链接需要延迟到 libA.so 被链接,但是将源文件编译为 libC 源的目标文件不需要延迟libA 的链接。

关于设置 CMake 文件以表达库之间依赖关系的最佳方式,我是否遗漏了什么?或者这是 Ninja 工作方式无法克服的限制?

这是最近在 CMake 邮件列表上提出的问题。其中一位开发者的 response 确认您报告的行为是故意的:

This is unfortunately necessary to get correct builds for CMake projects in general because we support cases where add_custom_command is used in library "foo" to generate a header file that is included during compilation in library "bar" that links to "foo", but we have no good way to express this dependency besides the ordering dependency of bar on foo.

虽然在某些情况下可能会改进 CMake 以放宽该约束,但这似乎尚未完成(从 CMake 3.6 开始)。在 Kitware 问题跟踪器中已经有一个 open ticket

更新: 这似乎是 fixed in CMake 3.9.0, although that change led to a regression which was then subsequently fixed in 3.12.0, or possibly 3.11.2