使用CMake,我可以使用Subversion_WC_INFO.但是,这仅在配置时发生 - 每个后续make都将使用此缓存的修订版.
我想在构建时获得svn修订版(即每次Make运行时).我怎样才能做到这一点?
ric*_*chq 32
这比你需要做的更痛苦.您可以在构建时运行程序以从subversion中提取版本信息.CMake本身可以使用其脚本语言作为此程序使用.您可以使用-P命令行标志运行任何CMake脚本.执行此操作的代码段(将被放入文件中getsvn.cmake):
# the FindSubversion.cmake module is part of the standard distribution
include(FindSubversion)
# extract working copy information for SOURCE_DIR into MY_XXX variables
Subversion_WC_INFO(${SOURCE_DIR} MY)
# write a file with the SVNVERSION define
file(WRITE svnversion.h.txt "#define SVNVERSION ${MY_WC_REVISION}\n")
# copy the file to the final header only if the version changes
# reduces needless rebuilds
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
svnversion.h.txt svnversion.h)
Run Code Online (Sandbox Code Playgroud)
这将提取subversion修订信息并将其写入头文件.此头文件仅在需要时更新,以避免一直重新编译.在您的程序中,您将包含该头文件以获取SVNVERSION定义.
CMakeLists.txt运行脚本所需的文件将是这样的:
# boilerplate
cmake_minimum_required(VERSION 2.8)
project(testsvn)
# the test executable
add_executable(test main.c ${CMAKE_CURRENT_BINARY_DIR}/svnversion.h)
# include the output directory, where the svnversion.h file is generated
include_directories(${CMAKE_CURRENT_BINARY_DIR})
# a custom target that is always built
add_custom_target(svnheader ALL
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/svnheader.h)
# creates svnheader.h using cmake script
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/svnheader.h
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/getsvn.cmake)
# svnversion.h is a generated file
set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/svnversion.h
PROPERTIES GENERATED TRUE
HEADER_FILE_ONLY TRUE)
# explicitly say that the executable depends on the svnheader
add_dependencies(test svnheader)
Run Code Online (Sandbox Code Playgroud)
您需要使用add_custom_target并且add_custom_command因为svnheader.h文件没有输入,所以它"从无处出现"到cmake.我已经在getsvn.cmake文件中处理了不必要的重建问题,所以如果subversion版本没有改变,重建"svnheader"目标基本上是无操作.
最后,一个示例main.c文件:
#include "svnversion.h"
int main(int argc, const char *argv[])
{
printf("%d\n", SVNVERSION);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我相信我发现问题@ janitor048有@ richq的答案.不幸的是,我没有足够的声誉评论他的答案 - 也许其他人可以复制和粘贴.
@richq使用自定义命令和自定义目标.自定义命令必须说服CMake创建标头,否则CMake脚本可以作为自定义目标的命令执行.虽然将始终执行自定义目标,但如果其输出文件已存在,则不会执行自定义命令.
解决方法是向自定义目标添加虚假依赖项(虚构文件),并告诉CMake自定义命令创建该文件.这足以确保始终执行自定义命令.幸运的是,CMake实际上并没有检查是否创建了该文件.
richq有:
# a custom target that is always built
add_custom_target(svnheader ALL
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/svnheader.h)
# creates svnheader.h using cmake script
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/svnheader.h
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/getsvn.cmake)
Run Code Online (Sandbox Code Playgroud)
这对我有用:
# a custom target that is always built
add_custom_target(svnheader ALL
DEPENDS svn_header ) # svn_header is nothing more than a unique string
# creates svnheader.h using cmake script
add_custom_command(OUTPUT svn_header ${CMAKE_CURRENT_BINARY_DIR}/svnheader.h
COMMAND ${CMAKE_COMMAND} -DSOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/getsvn.cmake)
Run Code Online (Sandbox Code Playgroud)
此外,如果有人想使用Git,请将其用于CMake脚本:
#create a pretty commit id using git
#uses 'git describe --tags', so tags are required in the repo
#create a tag with 'git tag <name>' and 'git push --tags'
find_package(Git)
if(GIT_FOUND)
execute_process(COMMAND ${GIT_EXECUTABLE} describe --tags RESULT_VARIABLE res_var OUTPUT_VARIABLE GIT_COM_ID )
if( NOT ${res_var} EQUAL 0 )
set( GIT_COMMIT_ID "git commit id unknown")
message( WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info." )
endif()
string( REPLACE "\n" "" GIT_COMMIT_ID ${GIT_COM_ID} )
else()
set( GIT_COMMIT_ID "unknown (git not found!)")
message( WARNING "Git not found. Build will not contain git revision info." )
endif()
set( vstring "//version_string.hpp - written by cmake. changes will be lost!\n"
"const char * VERSION_STRING = \"${GIT_COMMIT_ID}\"\;\n")
file(WRITE version_string.hpp.txt ${vstring} )
# copy the file to the final header only if the version changes
# reduces needless rebuilds
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
version_string.hpp.txt ${CMAKE_CURRENT_BINARY_DIR}/version_string.hpp)
Run Code Online (Sandbox Code Playgroud)