c++ - 强制 CMake 在每次构建时生成 configure_file 目标

标签 c++ cmake

我的 CMakeLists.txt 文件中有以下命令

configure_file([...]/Version.h.in [...]/Version.h @ONLY)

如何让它在每次构建时都运行,而不仅仅是在 Version.h.in 更改时运行?我需要它,因为 Version.h 中有 __DATE__ 宏,实际上每个构建都应该被视为新的,即使它保持不变也是如此。

Version.h.in 看起来像

static const char VERSION[] = "Bla-bla-bla " @FOOBAR@ " built on " __DATE__;

最佳答案

我将我的版本字符串生成转移到它自己的 CMake 脚本中,我在 add_custom_command()/ 中使用 ${CMAKE_COMMAND} -P ... 调用该脚本add_custom_target() 并使我使用它的目标依赖于它。

在您的情况下,假设您有一个像这样的 DateToVersionH.cmake 脚本:

string(TIMESTAMP _date "%d %m %Y %H:%M")
file(WRITE ${VERSION_FILE_NAME} "#define MY_VERSION \"Bla-bla-bla ${FOOBAR} built on ${_date}\"\n")

你可以这样做:

add_custom_command(
    TARGET MyExe
    PRE_BUILD
    COMMAND ${CMAKE_COMMAND} -DVERSION_FILE_NAME=Version.h -DFOOBAR="${FOOBAR}" -P "${CMAKE_CURRENT_LIST_DIR}/DateToVersionH.cmake"
)

另见 use CMake to get build-time svn revision

如果您的 make 环境在调用必要步骤之前检查所有“需要重建”(例如,在 Ninja 中,仅重新扫描自定义命令的输出;有关更多详细信息,请参阅 Ninja documentation restat 规则变量和 this discussion 导致在 add_custom_command() 中引入 BYPRODUCTS 选项。

因此您可以简单地添加到您的构建 shell 脚本中 - 在调用实际 make 之前 - 删除包含版本信息的目标文件。

或者您在链接之前强制重新编译对象。这将 - 假设你有一个包含 Version.hVersion.c - 看起来像这样:

include_directories(${CMAKE_CURRENT_BINARY_DIR})
execute_process(COMMAND "${CMAKE_COMMAND}" -DVERSION_FILE_NAME=Version.h -DFOOBAR="${FOOBAR}" -P "${CMAKE_CURRENT_LIST_DIR}/DateToVersionH.cmake")
add_library(MyVersionObj OBJECT Version.c)

add_executable(MyExe ... $<TARGET_OBJECTS:MyVersionObj>)

add_custom_command(
    TARGET MyExe
    PRE_LINK 
    COMMAND "${CMAKE_COMMAND}" -DVERSION_FILE_NAME=Version.h -DFOOBAR="${FOOBAR}" -P "${CMAKE_CURRENT_LIST_DIR}/DateToVersionH.cmake"
    COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}" --config $<CONFIG> --target "MyVersionObj"
)

考虑一下,删除目标文件并使用您当前的__DATE__ 解决方案是最简单的解决方案。

另一种“git 版本解决方案”参见CMake: Automatically use git tags as version stringsHow can I pass git SHA1 to compiler as definition using cmake?

关于c++ - 强制 CMake 在每次构建时生成 configure_file 目标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31057208/

相关文章:

c++ - 纠结于计算学校的 C++ 日历代码

c++ - 使用 SWIG 将 C++ char* 转换为 Java 中的 char[] 而不是 String

c++ - 分析核心转储

c++ - cmake + clang_tidy - 禁用 checkin 目录

unit-testing - CTest-使用--test-command选项进行--build-and-test

c++ - 在 Qiana 上构建 opencv 失败

c++ - 尝试实现堆栈时 C++ 中的 undefined reference

c++ - 图形场景Qt中右键单击上下文菜单的响应缓慢

c++ - 如何使用 CMake 强制 C++ 编译器使用不同安装包的版本之一?

gradle - 使用 CMAKE : no dynamic library found error 构建 NDK 可执行文件