【问题标题】:cmake force parallel .C.o compilation before linkingcmake 在链接之前强制并行 .C.o 编译
【发布时间】:2014-07-03 06:07:03
【问题描述】:

我有一个项目,其中包含 5 个库,每个库来自 10 个 C++ 源文件,然后是 10 个依赖于库的可执行文件。每个库还依赖于前一个库。在 48 核 Ubuntu 机器上使用 CMake,然后使用“make -j 50”,我首先必须等待每个库在 10 个或更少的内核上构建(大多数情况下更少,因为一个 .C 文件需要几分钟才能编译),然后我的可执行文件是并行构建的。

我想首先在所有 .C 源文件上并行运行所有 .Co 编译(我知道如何将该列表放入 CMake 变量中),然后按依赖项指定的顺序仅运行链接器。

有没有办法用 CMake 做到这一点,例如通过设置虚假目标或类似的东西? (我只想重新编译修改过的.C文件)。

【问题讨论】:

  • 如果您使用的是 GCC,我建议您尝试一下 clang,因为它往往具有更快的编译时间。此外,如果 CMake 正在生成 Makefile,那么我建议您尝试使用 Ninja generator/build system。从 2.8.9 版开始的 CMake 内置了 Ninja 生成器。有关更多信息,请参阅this
  • 您是否尝试过分别运行每个库目标?像for lib in lib1 lib2...; do make -j10 $lib & done; wait 这样的东西。另外,为什么您的 .C 文件需要这么长时间才能编译?
  • @SchighSchagh 是的,我听说过 Ninja,可能会尝试,但我认为它不会解决我的问题(库和可执行文件之间存在依赖关系等)。
  • @Jason 不起作用(我猜是因为第二个库取决于第一个等)。大量模板代码需要较长的编译时间(在这种情况下,通用图像之间的运算符可以有 15 种左右不同的像素类型(使用 boost::variant),因此 operator+、operator+= 等的 15^2 实例化必须被编译)
  • 最好将单独的库滚动到一个库中,因为它们都依次相互依赖。或者可能为目标文件编写一个具有通用规则的自定义 Makefile。如果我错了,我希望有人纠正我,但我不确定 CMake 是否会跟踪跨目标源依赖关系。在一个稍微不相关的注释中,extern 模板可能有助于缩短编译时间。

标签: c++ linux makefile cmake


【解决方案1】:

一种方法是添加一个虚假目标,该目标由 CMake 中每个库目标的所有源组成。一个示例 CMakeLists.txt 可能是...

set(ONE_SRC one/a.c one/b.c)
set(TWO_SRC two/a.c two/b.c)

# pre-compile
add_library(all ${ONE_SRC} ${TWO_SRC})

add_library(one ${ONE_SRC})
add_library(two ${TWO_SRC})

add_dependencies(one all)
add_dependencies(two one)

liball.so 目标将编译所有其他库所需的所有源,它应该打破 libone.so 的源文件和libtwo.so 当您运行 makeninja 等时...它将最大限度地提高跨目标的编译并行性。

CMake 可能不够聪明,只能编译一次 ${ONE_SRC} ${TWO_SRC} 文件。但是,这可以使用ccache 修复,它将缓存预处理文件。它具有减少任何相同的重新编译时间的额外好处。

一个简单的 ccache 配置是将符号链接添加到本地 $PATH 中的 ccache 二进制文件。

jason@io ~ $ ll ~/bin/ccache
total 0
lrwxrwxrwx 1 jason jason 15 May 12  2013 c++ -> /usr/bin/ccache*
lrwxrwxrwx 1 jason jason 15 May 12  2013 cc -> /usr/bin/ccache*
lrwxrwxrwx 1 jason jason 15 Apr 27 21:38 clang -> /usr/bin/ccache*
lrwxrwxrwx 1 jason jason 15 Apr 27 21:38 clang++ -> /usr/bin/ccache*
lrwxrwxrwx 1 jason jason 15 May 12  2013 g++ -> /usr/bin/ccache*
lrwxrwxrwx 1 jason jason 15 Oct  6  2013 gcc -> /usr/bin/ccache*
lrwxrwxrwx 1 jason jason 15 May 12  2013 x86_64-pc-linux-gnu-c++ -> /usr/bin/ccache*
lrwxrwxrwx 1 jason jason 15 May 12  2013 x86_64-pc-linux-gnu-g++ -> /usr/bin/ccache*
lrwxrwxrwx 1 jason jason 15 May 12  2013 x86_64-pc-linux-gnu-gcc -> /usr/bin/ccache*

ccache 环境变量比较简单。

# ccache

export CCACHE_DIR="/var/ccache/${USER}"
export CCACHE_SIZE="4G"
export CCACHE_COMPRESS="1"

【讨论】:

    【解决方案2】:

    在 linux 上使用 ninja build generator 为我解决了这个问题(在 2021 年):

    > cmake -G Ninja <path-to-source>
    > ninja
    

    好像makefile生成器添加的依赖太多了……

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-06
      • 1970-01-01
      • 1970-01-01
      • 2011-03-23
      • 2021-09-07
      • 1970-01-01
      相关资源
      最近更新 更多