windows下设置文件的版本需要通过VERSIONINFO接口,详情参考VERSIONINFO resource。这里我们根据模板做了一定的修改。
1 VERSIONINFO
FILEVERSION ${GIT_VERSION} //文件版本号,必填。以,分隔,输出以.分隔。这里是取CMakeLists里的GIT_VERSION变量
PRODUCTVERSION ${GIT_VERSION} //产品版本号,必填。以,分隔。虽然没起作用,见下面的"ProductVersion"
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x0L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "MyLibrary Binary" //文件说明
VALUE "FileVersion", "1.1.1" //文件版本,好像没啥用,只与FILEVERSION相关
VALUE "InternalName", "" //
VALUE "LegalCopyright", "Copyright (C) 2019"
VALUE "OriginalFilename", ""
VALUE "ProductName", "1234" //产品名称
VALUE "ProductVersion", "1.3.4.5.6" //产品版本,与PRODUCTVERSION无关,直接输出 //${PROJECT_VERSION_MAJOR},${PROJECT_VERSION_MINOR},${PROJECT_VERSION_PATCH},${PROJECT_VERSION_TWEAK}
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
前面已经准备号了versioninfo.接下来需要在CMakeLists中接入versioninfo。
set(GIT_VERSION 1,2,0,4)
if(MSVC)
set(VERSIONINFO_RC "${CMAKE_BINARY_DIR}/versioninfo.rc")
configure_file("${CMAKE_SOURCE_DIR}/versioninfo.rc"
"${VERSIONINFO_RC}")
endif()
add_executable(${PROJECT_NAME} ${SOURCES} ${VERSIONINFO_RC})
这里采用的是cmake的execute_process运行git命令获取版本,并对结果进行截取组合达到我们想要的内容。
execute_process表示运行命令,可以与git其他命令结合获取其他信息。
#######################
####获取git版本#########
#######################
#设置默认版本
set(GIT_VERSION 1.0.0)
#通过git命令获取版本
execute_process(COMMAND git describe --tags
OUTPUT_VARIABLE GIT_DESCRIBE)
# set(GIT_DESCRIBE "${GIT_DESCRIBE}-8-")
#查找版本
string(REGEX MATCH "[0-9]\\.[0-9]\\.[0-9]" GIT_DESCRIBE_VERSION ${GIT_DESCRIBE})
message(STATUS "GIT_DESCRIBE_VERSION=${GIT_DESCRIBE_VERSION}")
if(NOT ${GIT_DESCRIBE_VERSION} EQUAL "")
set(GIT_VERSION "${GIT_DESCRIBE_VERSION}")
endif()
#查找提交次数
string(REGEX MATCHALL "-([0-9]+)-" MATCH_COMMIT_RET ${GIT_DESCRIBE})
message(STATUS "MATCH_COMMIT_RET=${MATCH_COMMIT_RET}")
list(LENGTH MATCH_COMMIT_RET MATCH_COMMIT_RET_LEN)
message(STATUS "MATCH_COMMIT_RET_LEN=${MATCH_COMMIT_RET_LEN}")
if(${MATCH_COMMIT_RET_LEN} GREATER 0)
#拿到最后一个匹配项
math(EXPR MATCH_COMMIT_RET_LEN "${MATCH_COMMIT_RET_LEN} - 1")
message(STATUS "MATCH_COMMIT_RET_LEN=${MATCH_COMMIT_RET_LEN}")
list(GET MATCH_COMMIT_RET ${MATCH_COMMIT_RET_LEN} MATCH_LAST)
#获取
string(REGEX REPLACE "-(.+)-" "\\1" GIT_COMMIT_COUNT ${MATCH_LAST})
set(GIT_VERSION "${GIT_VERSION}.${GIT_COMMIT_COUNT}")
else()#没有则默认写0
set(GIT_VERSION "${GIT_VERSION}.0")
endif()
string(REPLACE "." "," GIT_VERSION ${GIT_VERSION})
# set(GIT_VERSION 1,2,0)
# message(STATUS "final version is ${GIT_VERSION}")
##################################END#######################################
这里因为是按照我们设想的git tag版本格式(x.x.x),并根据git describe会自动返回"version-提交次数-g当前提交hash"内容所写的。目的就是提炼成"version.提交次数",也就是x.x.x.x形式。所以这就要求在打tag的时候需要注意一定的格式否则这个代码将不起作用。
此外,git describe对于轻量标签不起作用,只有附注标签生效。
cmake_minimum_required(VERSION 3.10)
project(gitversion)
#######################
####获取git版本#########
#######################
#设置默认版本
set(GIT_VERSION 1.0.0)
#通过git命令获取版本
execute_process(COMMAND git describe --tags
OUTPUT_VARIABLE GIT_DESCRIBE)
# set(GIT_DESCRIBE "${GIT_DESCRIBE}-8-")
#查找版本
string(REGEX MATCH "[0-9]\\.[0-9]\\.[0-9]" GIT_DESCRIBE_VERSION ${GIT_DESCRIBE})
message(STATUS "GIT_DESCRIBE_VERSION=${GIT_DESCRIBE_VERSION}")
if(NOT ${GIT_DESCRIBE_VERSION} EQUAL "")
set(GIT_VERSION "${GIT_DESCRIBE_VERSION}")
endif()
#查找提交次数
string(REGEX MATCHALL "-([0-9]+)-" MATCH_COMMIT_RET ${GIT_DESCRIBE})
message(STATUS "MATCH_COMMIT_RET=${MATCH_COMMIT_RET}")
list(LENGTH MATCH_COMMIT_RET MATCH_COMMIT_RET_LEN)
message(STATUS "MATCH_COMMIT_RET_LEN=${MATCH_COMMIT_RET_LEN}")
if(${MATCH_COMMIT_RET_LEN} GREATER 0)
#拿到最后一个匹配项
math(EXPR MATCH_COMMIT_RET_LEN "${MATCH_COMMIT_RET_LEN} - 1")
message(STATUS "MATCH_COMMIT_RET_LEN=${MATCH_COMMIT_RET_LEN}")
list(GET MATCH_COMMIT_RET ${MATCH_COMMIT_RET_LEN} MATCH_LAST)
#获取
string(REGEX REPLACE "-(.+)-" "\\1" GIT_COMMIT_COUNT ${MATCH_LAST})
set(GIT_VERSION "${GIT_VERSION}.${GIT_COMMIT_COUNT}")
else()#没有则默认写0
set(GIT_VERSION "${GIT_VERSION}.0")
endif()
string(REPLACE "." "," GIT_VERSION ${GIT_VERSION})
# set(GIT_VERSION 1,2,0)
# message(STATUS "final version is ${GIT_VERSION}")
##################################END#######################################
#这里需要注意按顺序
if(MSVC)
set(VERSIONINFO_RC "${CMAKE_BINARY_DIR}/versioninfo.rc")
configure_file("${CMAKE_SOURCE_DIR}/versioninfo.rc"
"${VERSIONINFO_RC}")
endif()
file(GLOB SOURCES "*.cpp")
add_executable(${PROJECT_NAME} ${SOURCES} ${VERSIONINFO_RC})
target_include_directories(${PROJECT_NAME}
PRIVATE
${CMAKE_SOURCE_DIR})
另一种方式是通过cmake的PROJECT_VERSION,PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR, PROJECT_VERSION_PATCH, PROJECT_VERSION_TWEAK来获取,但是无法动态调整版本号,需要手动修改。
代码如下:
cmake_minimum_required(VERSION 3.10)
project(cmakeversion VERSION 1.2.5.8)
#这里需要注意按顺序
if(MSVC)
set(VERSIONINFO_RC "${CMAKE_BINARY_DIR}/versioninfo.rc")
configure_file("${CMAKE_SOURCE_DIR}/versioninfo.rc"
"${VERSIONINFO_RC}")
endif()
file(GLOB SOURCES "*.cpp")
add_executable(${PROJECT_NAME} ${SOURCES} ${VERSIONINFO_RC})
target_include_directories(${PROJECT_NAME}
PRIVATE
${CMAKE_SOURCE_DIR})
include(CMakePackageConfigHelpers)
configure_package_config_file(Config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
INSTALL_DESTINATION lib/cmake/${PROJECT_NAME})
write_basic_package_version_file(${PROJECT_NAME}ConfigVersion.cmake
VERSION ${PACKAGE_VERSION} COMPATIBILITY AnyNewerVersion )
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
DESTINATION lib/cmake/${PROJECT_NAME} )
message(status "version=${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}.${PROJECT_VERSION_TWEAK}")
此外需要引用Config.cmake.in
@PACKAGE_INIT@
set_and_check(CMAKEVERSION_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
set_and_check(CMAKEVERSION_SYSCONFIG_DIR "@PACKAGE_SYSCONFIG_INSTALL_DIR@")
check_required_components(Cmakeversion)