【问题标题】:CMake + Ninja build does not parallelize across librariesCMake + Ninja 构建不会跨库并行化
【发布时间】:2016-07-09 21:51:44
【问题描述】:

我们有一个 (C++) 程序,它被设置为一系列具有嵌套层次结构的共享库。也就是说,libB.so 使用函数 from 并因此链接 libA.so,libC.so 使用函数 from 并链接 libB.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 工作方式的一个不可逾越的限制?

【问题讨论】:

  • 我注意到了同样的@R.M.在此期间您找到解决方案了吗?起初我想也许 ninja 不确定 libA 的编译是否会生成 libC 需要的东西(可能是头文件)。但我认为这仅在完全重建的情况下是正确的(当生成的头文件还不存在时)。无论如何,libC 需要根据生成头文件的 libA 中的目标来解决这种情况。所以我不认为这是原因,但我想不出任何合适的解释

标签: c++ build cmake ninja


【解决方案1】:

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

不幸的是,这对于获得 CMake 项目的正确构建是必要的 一般来说,因为我们支持使用 add_custom_command 的情况 在库“foo”中生成一个头文件,该文件包含在 在链接到“foo”的库“bar”中编译,但我们没有好的 除了 bar 的排序依赖关系之外,表达这种依赖关系的方法 在 foo 上。

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

更新:这似乎是 fixed in CMake 3.9.0,尽管这种变化导致了回归,随后是 fixed in 3.12.0possibly 3.11.2

【讨论】:

  • 看起来这个问题已经修复了。
  • 你知道是什么版本吗?谢谢!
  • @mystery_doctor 答案已更新,详细说明何时修复
  • 我在使用 CMake 3.18 时遇到了类似的问题。原来这仅适用于 ninja-build (gitlab.kitware.com/cmake/cmake/-/issues/20361)。此外,它在使用 Qt 和 CMAKE_AUTOMOC/RCC/UIC ON 时会中断)。我的项目中不需要这些工具,所以我只是删除了该设置并开始工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-25
  • 2018-03-15
  • 2019-03-16
  • 1970-01-01
  • 2020-12-05
  • 2015-05-07
  • 1970-01-01
相关资源
最近更新 更多