命令输出更改时如何触发CMake重新配置 [英] How to trigger a CMake reconfigure when the output of a command changes

查看:152
本文介绍了命令输出更改时如何触发CMake重新配置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望在命令输出更改时触发CMake配置;具体来说,我正在尝试尝试使 git的输出描述--always --dirty 的输出与上次配置CMake的时间有所更改时,使CMake进行配置。

I'm looking to trigger a CMake configure to occur when the output of a command changes; Specifically I am looking at trying to make CMake configure when the output of git describe --always --dirty has change from the previous time CMake was configured.

大部分问题可以通过查看 HEAD 文件并将其中的symref解析为 refs / heads来解决。 / [分支] 并将它们与 configure_file(...)链接,但是当树处于脏状态时这不会继续(即有未提交的修改的IE)。在这种情况下, git describe --always --dirty 会将 -dirty 后缀附加到输出中。

Most of this problem can be solved by watching the HEAD file and resolving the symref inside to refs/heads/[branch] and linking these with configure_file(...) however this doesn't pick up on when the tree is in a dirty state (I.E. when there are uncommitted modifications). In this instance git describe --always --dirty will append the -dirty suffix to the output.

当这种情况发生时,git文件没有任何变化,只有git注意到与存储状态的不同,所以我不能 configure_file(... )在此处的任何文件上,以使cmake注意到更改并重新配置。

When this occurs there are no changes to the git files, only that git has noticed differences from the stored state so I can't configure_file(...) on any files here to get cmake to notice the change and reconfigure.

所以我正在寻找是否有办法让cmake运行git命令,注意输出的差异并触发重新配置,几乎需要类似于预重新配置检查阶段的东西。

So I'm looking to find if there is a way to get cmake to run the git command notice the difference in output and trigger a reconfigure, almost need something akin to a pre-reconfigure-check stage.

不确定

推荐答案

问题

这里的问题是预配置检查阶段由您的构建环境处理。仅在更改某些输入文件时调用CMake(因为CMake已为您的构建环境生成了规则,以跟踪这些文件是否被更改)。

The problem here is that the "pre-reconfigure-check stage" is handled by your build environment. CMake is only called when some of its input files are changed (because CMake has generated rules for your build environment to keep track if those files being changed).

假设您有类似的东西:

execute_process(
    COMMAND ${GIT_EXECUTABLE} describe --always --dirty
    OUTPUT_VARIABLE _git_file_list
    OUTPUT_STRIP_TRAILING_WHITESPACE
)

configure_file(version.h.in version.h)

外部命令输出更改时,没有内置重新配置

我不认为无需在构建过程中加入额外的脚本,就可以实现检查外部命令作为预配置步骤的输出之类的操作。

I don't think something like "checking the output of external command as pre-reconfigure step" is possible without an additional script that you make part of your build process.

例如,您可以强制CMake每次重新配置。在实际构建之前调用 make rebuild_cache 或添加例如 add_custom_command(TARGET MyExe POST_BUILD $ {CMAKE_COMMAND} -E删除$ {CMAKE_CURRENT_BINARY_DIR} /version.h),但是每次调用配置过程都是非常耗时的事情。

You could force CMake to reconfigure every time e.g. by calling make rebuild_cache before your actual build or by adding e.g. add_custom_command(TARGET MyExe POST_BUILD ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/version.h), but calling the configuration process every time is very time consuming thing to do.

解决方案

在我的项目中,我将上面的代码移入了它是自己的 WriteVersionInfo.cmake 脚本:

In my projects I have moved something like the code above into it's own WriteVersionInfo.cmake script:

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 步骤传递给编译器。请注意,上述方法不适用于库目标(因为没有预链接步骤)。

Here I'm directly writing to a .cpp file and directly pass it to the compiler as a PRE_LINK step. Please note that the above approach is not working for library targets (because there is no pre-link step).

参考

  • CMake: Building a Version Header

这篇关于命令输出更改时如何触发CMake重新配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆