cmake生成的头文件导致二次构建



一个非常简单的场景-我需要生成头,包括它,如果生成的头在cmake构建时更新,所有依赖的cpp单元也必须重建。

一个简化的例子:

add_custom_command(
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/test.h
COMMAND ...
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/test.in"
add_custom_target(test_target DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/test.h)
add_executable(test_exe
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
)
add_dependencies(test_exe test_target)

main.cpp=

#include "test.h"
int main()
{
return 0;
}

当我做一个完整的重建,一切都很好。但是当我改变test.in时,只运行cmake.exe --build . --target all,只有test.h再生,但main.cpp没有重新编译。但是当我再次运行cmake.exe --build . --target all(第二次)时,main.cpp被重新编译,test_exe被重新链接。

我做错了什么?

注:如果我显式地使用OBJECT_DEPENDS,没有问题,重建工作很好,但文档说不再需要了- https://cmake.org/cmake/help/v3.20/prop_sf/OBJECT_DEPENDS.html

更新:我使用Windows 10, CMake 3.19.2和Ninja 1.10.2

解决方案:在项目目录中使用构建目录,那么就没有问题了。但是如果构建目录在我们的项目目录之外,那么就有问题了。

张贴作为一个答案,能够显示完整的例子

CMakeLists.txt

cmake_minimum_required(VERSION 3.15)
project(example)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/test.h
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/test.in" ${CMAKE_CURRENT_SOURCE_DIR}/test.h
DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/test.in")
add_custom_target(test_target DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/test.h)
add_executable(test_exe
${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
)
add_dependencies(test_exe test_target)

main.cpp

#include "stdio.h"
#include "test.h"
int main()
{
printf("The value is %dn", FOO);
return 0;
}

test.in

#define FOO 4

这适用于windows与CMake 3.19.2和忍者1.10.2,一个人可以改变FOO定义在test.in在初始构建后,看到结果可执行文件被重建,并看到它的值改变。

用于测试

的命令
$ cmake -B build -G Ninja
-- The C compiler identification is Clang 11.0.0 with GNU-like command-line
-- The CXX compiler identification is Clang 11.0.0 with GNU-like command-line
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files/LLVM/bin/clang.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files/LLVM/bin/clang++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done                            
-- Build files have been written to: <some_path>

$ cmake --build build                                 
[3/3] Linking CXX executable test_exe.exe             

$ ./build/test_exe.exe                                
The value is 4                                        

$ echo "#define FOO 3" > test.in                      

$ cmake --build build                                 
[3/3] Linking CXX executable test_exe.exe             

$ ./build/test_exe.exe                                
The value is 3    

最新更新