使力平行.0链接前编译

cmake force parallel .C.o compilation before linking

本文关键字:链接 编译      更新时间:2023-10-16

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

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

是否有一种方法可以做到这一点与CMake,例如通过设置一个虚假的目标或类似的东西?(我只想重新编译被修改过的。c文件)

这样做的一种方法是添加一个由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。因此, target将编译所有其他库所需的所有源代码,并且它应该打破libone的源文件之间的错误依赖关系。所以libtwo。所以当你运行make, ninja,等等…它将最大化跨目标的编译并行性。

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"

在linux上使用ninja构建生成器为我解决了这个问题(在2021年):

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

似乎makefile生成器添加了太多的依赖项…