CMake在.o和.a文件之间添加了不必要的依赖关系

我有一个由CMake管理的项目,它有多个库,它们之间有链接时间依赖关系,但是每个库都可以相互独立地编译.我如何向CMake表达这一点,以便我可以同时构建所有库?

例如,我尝试了这个CMakeLists.txt:

cmake_minimum_required(VERSION 2.6)
project (test)
add_library(lib1 STATIC lib1.cpp)
add_library(lib2 STATIC lib2.cpp)
add_library(lib3 STATIC lib3.cpp)
add_executable(main main.cpp)
target_link_libraries(lib2 lib1)
target_link_libraries(lib3 lib2)
target_link_libraries(main lib3)

每个文件只定义一个不同的空函数,如:

void f1() {}

当我键入cmake. &安培;&安培; make -j4,我看到了这个:

[ 25%] Building CXX object CMakeFiles/lib1.dir/lib1.cpp.o
Linking CXX static library liblib1.a
[ 25%] Built target lib1
[ 50%] Building CXX object CMakeFiles/lib2.dir/lib2.cpp.o
Linking CXX static library liblib2.a
[ 50%] Built target lib2
[ 75%] Building CXX object CMakeFiles/lib3.dir/lib3.cpp.o
Linking CXX static library liblib3.a
[ 75%] Built target lib3
[100%] Building CXX object CMakeFiles/main.dir/main.cpp.o
Linking CXX executable main
[100%] Built target main

即使我已经指定了-j4并且编译每个.cpp文件也不应该依赖于任何.a文件,它正在等待上一次编译和链接以完成下一个.我宁愿看到类似的东西:

Building CXX object CMakeFiles/lib1.dir/lib1.cpp.o
Building CXX object CMakeFiles/lib2.dir/lib2.cpp.o
Building CXX object CMakeFiles/lib3.dir/lib3.cpp.o
Building CXX object CMakeFiles/main.dir/main.cpp.o
Linking CXX static library liblib1.a
Built target lib1
Linking CXX static library liblib2.a
Built target lib2
Linking CXX static library liblib3.a
Built target lib3
Linking CXX executable main
Built target main

有可能告诉CMake它可以同时构建所有.o文件吗?

实际上,我在一个百万行的项目中这样做,我可以使用大约20个cpu内核(使用distcc),所以这是我构建时间的巨大瓶颈.

顺序执行可能是静态库lib1,lib2和lib3之间建立的链接依赖性的结果.

一种解决方法是摆脱这些静态库链接依赖性.由于您无论如何都要构建静态库,因此删除依赖项不会阻止它们成功链接.可执行文件主要需要依赖于所有库:

cmake_minimum_required(VERSION 2.6)
project (test)
add_library(lib1 STATIC lib1.cpp)
add_library(lib2 STATIC lib2.cpp)
add_library(lib3 STATIC lib3.cpp)
add_executable(main main.cpp)
target_link_libraries(main lib1 lib2 lib3)

以这种方式组织make -j并行构建库.

如果不能选择删除链接依赖项,则可以应用原则“Any problem in computer science can be solved with another layer of indirection”

cmake_minimum_required(VERSION 2.6)
project (test)
add_library(lib1_objects STATIC lib1.cpp)
add_library(lib2_objects STATIC lib2.cpp)
add_library(lib3_objects STATIC lib3.cpp)
add_executable(main main.cpp)

add_library(lib1 STATIC empty.cpp)
add_library(lib2 STATIC empty.cpp)
add_library(lib3 STATIC empty.cpp)

target_link_libraries(lib1 lib1_objects)
target_link_libraries(lib2 lib2_objects lib1)
target_link_libraries(lib3 lib3_objects lib2)
target_link_libraries(main lib3)

这设置了辅助库(例如,lib1_objects),它们没有依赖关系,因此可以并行构建.原始库链接到这些帮助程序库,并且还设置了所需的链接依赖项. empty.cpp只是一个空的虚拟CPP源文件.

相关文章

迭代器模式(Iterator)迭代器模式(Iterator)[Cursor]意图...
高性能IO模型浅析服务器端编程经常需要构造高性能的IO模型,...
策略模式(Strategy)策略模式(Strategy)[Policy]意图:定...
访问者模式(Visitor)访问者模式(Visitor)意图:表示一个...
命令模式(Command)命令模式(Command)[Action/Transactio...
生成器模式(Builder)生成器模式(Builder)意图:将一个对...