毫无疑问,一些核心通用库的API(头文件)的更改应该触发几乎整个系统的重编译。但通常只有实现的更改,只编译修改的.cxx文件,并且理论上只需要链接修改的库-由于动态链接,不需要重新链接其他任何内容。但是CMake仍然会这样做:在重新链接库之后,它会重新链接所有与该库相关联的单元测试。然后它会重新链接该库依赖树中的所有库及其单元测试。最后,它会重新链接生产可执行文件。由于项目规模大,这需要很多宝贵的时间。
我使用基于此最小示例(为简洁起见已删除注释并将库更改为共享)的简单项目重现了这种行为。我的系统是Ubuntu 16,Intel PC,我的CMake版本为3.5.1。
从空目录开始,创建这些文件:
CMakeLists.txt
cmake_minimum_required (VERSION 2.8.11)
project (HELLO)
add_subdirectory (Hello)
add_subdirectory (Demo)
Demo/CMakeLists.txt
add_executable (helloDemo demo.cxx)
target_link_libraries (helloDemo LINK_PUBLIC Hello)
Demo/demo.cxx
#include "hello.h"
int main() { hello(); }
Hello/CMakeLists.txt
add_library (Hello SHARED hello.cxx)
target_include_directories (Hello PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
Hello/hello.h
void hello();
Hello/hello.cxx
#include <stdio.h>
void hello() { printf("hello!\n"); }
现在运行以下命令:
mkdir build
cd build
cmake ../
make
您现在可以执行 Demo/helloDemo
命令并查看 hello!
。
现在,使用 touch
命令编辑 Hello/hello.cxx 文件并再次使用 make
命令。您将看到 helloDemo
可执行文件被重新链接 ("Linking CXX executable helloDemo
")。即使修改 hello.cxx 以打印不同的字符串,重新链接的可执行文件仍然是二进制相同的,因此重新链接是不必要的。
有没有一种方法可以防止这些冗余的构建操作呢?