我希望在命令输出发生变化时触发CMake配置;具体来说,我正在尝试在git describe --always --dirty
的输出与之前配置CMake时发生变化时尝试进行CMake配置。
大多数此问题都可以通过观看HEAD
文件并将symref解析为refs/heads/[branch]
并将其与configure_file(...)
相关联来解决,但是这种情况在树时无法解决处于脏状态(IE有未提交的修改时)。在这种情况下,git describe --always --dirty
会将-dirty
后缀附加到输出。
当发生这种情况时,git文件没有变化,只有git注意到存储状态的差异所以我不能configure_file(...)
这里的任何文件让cmake注意到更改并重新配置。< / p>
所以我想找到一种方法让cmake运行git命令注意输出的差异并触发重新配置,几乎需要类似于预重新配置检查阶段。
如果有人知道如何能够实现这种行为,那么不确定这是否可行?
答案 0 :(得分:1)
问题
这里的问题是&#34;预重新配置检查阶段&#34;由您的构建环境处理。 CMake仅在其某些输入文件被更改时被调用(因为CMake已为您的构建环境生成规则以跟踪这些文件是否被更改)。
对于这个讨论,我们假设你有类似的东西:
execute_process(
COMMAND ${GIT_EXECUTABLE} describe --always --dirty
OUTPUT_VARIABLE _git_file_list
OUTPUT_STRIP_TRAILING_WHITESPACE
)
configure_file(version.h.in version.h)
外部命令输出更改时没有内置重新配置
我不认为&#34;将外部命令的输出检查为预重新配置步骤&#34;没有您参与构建过程的其他脚本是可能的。
您可以强制CMake每次重新配置,例如在实际构建之前调用make rebuild_cache
或添加例如add_custom_command(TARGET MyExe POST_BUILD ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/version.h)
,但每次调用配置过程都是非常耗时的事情。
<强>解决方案强>
在我的项目中,我将上面的代码移到了自己的WriteVersionInfo.cmake
脚本中:
set(_version_cpp_full_path "${CMAKE_CURRENT_BINARY_DIR}/version.cpp")
set(_version_obj_full_path "${_version_cpp_full_path}${CMAKE_CXX_OUTPUT_EXTENSION}")
string(REPLACE " " ";" _compiler_flags_list ${CMAKE_CXX_FLAGS})
# Create a dummy output to satisfy dependency check
if (NOT EXISTS ${_version_obj_full_path})
file(WRITE ${_version_obj_full_path} "")
endif()
add_custom_command(
TARGET MyExe
PRE_LINK
COMMAND ${CMAKE_COMMAND} -D GIT_EXECUTABLE=${GIT_EXECUTABLE}
-D _version_cpp_name=${_version_cpp_full_path}
-P ${CMAKE_CURRENT_SOURCE_DIR}/WriteVersionInfo.cmake
COMMAND ${CMAKE_CXX_COMPILER} ${_compiler_flags_list}
-o ${_version_obj_full_path}
-c ${_version_cpp_full_path}
VERBATIM
)
target_link_libraries(
MyExe
${_version_obj_full_path}
)
我直接写入.cpp
文件并直接将其作为PRE_LINK
步骤传递给编译器。请注意,上述方法不适用于库目标(因为没有预链接步骤)。
<强>参考强>