如何解决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
解决方案: 在您的项目目录中使用 build 目录,则没有问题。但是如果构建目录在我们的项目目录之外,那就有问题了。
解决方法
作为答案发布以显示完整示例
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 %d\n",FOO);
return 0;
}
test.in
#define FOO 4
这适用于具有 CMake 3.19.2 和 Ninja 1.10.2 的 Windows,您可以在初始构建后更改 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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。