我想启动一些命令并将其输出存储到某个变量中。然后重新配置依赖于此变量的输入文件。
例如,我想通过运行hg id -i
获得当前的mercurial修订版。可以在构建之间更改此命令的输出。因此,我必须每次都运行此命令并将输出存储到某个变量中。
因此,因为我必须在每次构建时运行此命令,所以execute_process
不适合我。但是add_custom_command
也不合适,因为它无法将命令的输出保存到变量中。
假设我可以(以某种方式)获得hg id -i
的输出并将其存储到REVISION
变量中。然后我想用版本:
configure_file(version.cpp.in version.cpp)
version.cpp.in
volatile const char* revision = "Revision: ${REVISION}";
作为一种解决方法,我可以定义REVISION
,但我希望在源文件中包含修订号。
P.S。这里的Mercurial和版本号只是一个例子。所以,请不要建议Mercurial的keyword
扩展等等。
答案 0 :(得分:2)
您可以在cmake
命令中以脚本模式调用add_custom_target
:
<强> configure_version.cmake 强>:
execute_process(COMMAND hg id -i
OUTPUT_VARIABLE REVISION)
configure_file(${input_file} ${output_file})
<强>的CMakeLists.txt 强>:
add_custom_target(version_target
COMMAND ${CMAKE_COMMAND}
-Dinput_file=${CMAKE_CURRENT_SOURCE_DIR}/version.cpp.in
-Doutput_file=${CMAKE_CURRENT_BINARY_DIR}/version.cpp
-P ${CMAKE_CURRENT_SOURCE_DIR}/configure_version.cmake
)
脚本不会在add_custom_command
内调用,因为每次构建都需要调用它。因此,您应该在add_dependencies
文件的使用者和脚本的目标之间添加目标级依赖(version.cpp
){{{ 1}})。
需要在脚本中传递version_target
的输入和输出文件路径,因为脚本不知道configure_file
个变量。或者,您可以自行配置脚本文件。
答案 1 :(得分:0)
最后我使用以下解决方案:
在 CMakeLists.txt :
...
# Versioning
# Try to find hg executable, retrive revision if found and generate version.cpp from template
set(VERSIONING_FILES src/versioning.cmake src/version.cpp.in)
find_program(HG hg DOC "Mercurial executable file")
# invalidate template
add_custom_target(versioning ALL COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_SOURCE_DIR}/src/version.cpp.in
SOURCES ${VERSIONING_FILES})
add_custom_command(OUTPUT ${CMAKE_SOURCE_DIR}/src/version.cpp
COMMAND ${CMAKE_COMMAND} -DVERSION_INPUT=${CMAKE_SOURCE_DIR}/src/version.cpp.in -DVERSION_OUTPUT=${CMAKE_SOURCE_DIR}/src/version.cpp -DHG=${HG} -P ${CMAKE_SOURCE_DIR}/src/versioning.cmake
DEPENDS ${CMAKE_SOURCE_DIR}/src/version.cpp.in)
...
<强>的src / versioning.cmake 强>:
if (HG)
execute_process(COMMAND ${HG} id OUTPUT_VARIABLE REVISION OUTPUT_STRIP_TRAILING_WHITESPACE)
else ()
set(REVISION "<undefined>")
endif ()
configure_file(${VERSION_INPUT} ${VERSION_OUTPUT})
execute_process(COMMAND ${CMAKE_COMMAND} -E touch ${VERSION_OUTPUT}) # invalidate output to force rebuild this source file even if it was not changed.
# vim: set ts=4 sw=4 ai tw=0 et syntax=cmake :
src / version.cpp.in 的内容:
volatile const char* REVISION = "$ Build revision: ${REVISION} $";
volatile const char* ROOT_DIRECTORY = "$ Build directory: ${CMAKE_BINARY_DIR} $";
volatile const char* BUILD_DATE = "$ Build date: " __DATE__ " " __TIME__ " $";