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

exc*_*ipy 6 cmake

我有一个由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)
Run Code Online (Sandbox Code Playgroud)

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

void f1() {}
Run Code Online (Sandbox Code Playgroud)

当我打字时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
Run Code Online (Sandbox Code Playgroud)

即使我已经指定-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
Run Code Online (Sandbox Code Playgroud)

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

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

sak*_*kra 2

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

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

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)
Run Code Online (Sandbox Code Playgroud)

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

如果摆脱链接依赖关系不是一个选择,您可以应用“计算机科学中的任何问题都可以通过另一层间接解决”原则:

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)
Run Code Online (Sandbox Code Playgroud)

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