我希望在命令输出发生变化时触发CMake配置; 具体来说,我正在尝试在输出git describe --always --dirty从上一次CMake配置发生变化时尝试进行CMake 配置.
大多数问题都可以通过观察HEAD文件并解析内部的symref refs/heads/[branch]并将它们链接起来来解决,configure_file(...)但是当树处于脏状态时(IE存在未提交的修改时,IE不会).在这种情况下,git describe --always --dirty会将-dirty后缀附加到输出.
当发生这种情况时,git文件没有变化,只有git注意到存储状态的差异所以我不能configure_file(...)在这里找到任何文件让cmake注意到更改并重新配置.
所以我想找到是否有办法让cmake运行git命令注意输出的差异并触发重新配置,几乎需要类似于预重新配置检查阶段的东西.
不确定这是否可能,如果有人有任何想法如何可以实现这种行为?
问题
这里的问题是“预重新配置检查阶段”是由您的构建环境处理的。仅当某些输入文件发生更改时才会调用 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)
Run Code Online (Sandbox Code Playgroud)
外部命令输出更改时无内置重新配置
我认为如果没有在构建过程中添加额外的脚本,“检查外部命令的输出作为预重新配置步骤”之类的事情是不可能的。
您可以强制 CMake 每次重新配置,例如通过make rebuild_cache在实际构建之前调用或添加 eg 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}
)
Run Code Online (Sandbox Code Playgroud)
这里我直接写入一个.cpp文件,并将其作为一个步骤直接传递给编译器PRE_LINK。请注意,上述方法不适用于库目标(因为没有预链接步骤)。
参考
| 归档时间: |
|
| 查看次数: |
3793 次 |
| 最近记录: |