一个非常简单的场景-我需要生成头,包括它,如果生成的头在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