【发布时间】:2013-09-06 12:48:23
【问题描述】:
我有一个程序版本变量
set(MY_PROGRAM_VERSION "2.5.1")
我想保存 2,5,1 到 3 个不同的变量,比如
MY_PROGRAM_VERSION_MAJOR=2
MY_PROGRAM_VERSION_MINOR=5
MY_PROGRAM_VERSION_PATCH=1
但我真的不知道如何访问 CMake 列表中的单个元素。有什么想法吗?
【问题讨论】:
我有一个程序版本变量
set(MY_PROGRAM_VERSION "2.5.1")
我想保存 2,5,1 到 3 个不同的变量,比如
MY_PROGRAM_VERSION_MAJOR=2
MY_PROGRAM_VERSION_MINOR=5
MY_PROGRAM_VERSION_PATCH=1
但我真的不知道如何访问 CMake 列表中的单个元素。有什么想法吗?
【问题讨论】:
根据this 和this,我猜您需要将字符串转换为类似列表文字的内容并在新列表上使用GET:
cmake_minimum_required(VERSION 2.8)
set(MY_PROGRAM_VERSION "2.5.1")
string(REPLACE "." ";" VERSION_LIST ${MY_PROGRAM_VERSION})
list(GET VERSION_LIST 0 MY_PROGRAM_VERSION_MAJOR)
list(GET VERSION_LIST 1 MY_PROGRAM_VERSION_MINOR)
list(GET VERSION_LIST 2 MY_PROGRAM_VERSION_PATCH)
【讨论】:
您可以使用以下辅助函数自动设置版本组件变量:
macro (setup_package_version_variables _packageName)
if (DEFINED ${_packageName}_VERSION)
string (REGEX MATCHALL "[0-9]+" _versionComponents "${${_packageName}_VERSION}")
list (LENGTH _versionComponents _len)
if (${_len} GREATER 0)
list(GET _versionComponents 0 ${_packageName}_VERSION_MAJOR)
endif()
if (${_len} GREATER 1)
list(GET _versionComponents 1 ${_packageName}_VERSION_MINOR)
endif()
if (${_len} GREATER 2)
list(GET _versionComponents 2 ${_packageName}_VERSION_PATCH)
endif()
if (${_len} GREATER 3)
list(GET _versionComponents 3 ${_packageName}_VERSION_TWEAK)
endif()
set (${_packageName}_VERSION_COUNT ${_len})
else()
set (${_packageName}_VERSION_COUNT 0)
set (${_packageName}_VERSION "")
endif()
endmacro()
可以通过以下方式调用宏:
set(MY_PROGRAM_VERSION "2.5.1")
setup_package_version_variables(MY_PROGRAM)
该宏还将MY_PROGRAM_VERSION_COUNT 设置为版本组件的数量,如果版本号有4 个组件(例如,“2.5.1.0”),则设置MY_PROGRAM_VERSION_TWEAK
【讨论】:
CMake 的string 命令是通往这里的路。
如果您自己设置变量的值而不是从某些第三方来源获取它,您可能希望改用这种方法:
function(SetVersionNumber PREFIX VERSION_MAJOR VERSION_MINOR VERSION_PATCH)
set(${PREFIX}_VERSION_MAJOR ${VERSION_MAJOR} PARENT_SCOPE)
set(${PREFIX}_VERSION_MINOR ${VERSION_MINOR} PARENT_SCOPE)
set(${PREFIX}_VERSION_PATCH ${VERSION_PATCH} PARENT_SCOPE)
set(${PREFIX}_VERSION
"${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}"
PARENT_SCOPE)
endfunction()
[...]
SetVersionNumber(MY_PROGRAM 2 5 1)
message(${MY_PROGRAM_VERSION_MAJOR})
message(${MY_PROGRAM_VERSION_MINOR})
message(${MY_PROGRAM_VERSION_PATCH})
message(${MY_PROGRAM_VERSION})
使您不必做正则表达式巫术;)
【讨论】:
我使用这个函数来获取包名和版本。
补丁级别之后的文本被跳过。 (libA-v1.2.3-THIS_IS_SKIPPED)
function(get_versions versionstring libname major minor patch)
string(REGEX REPLACE "([A-Za-z0-9_]*)-[vV].*" "\\1" locallibname ${versionstring} )
set(libname ${locallibname} PARENT_SCOPE)
string(REGEX REPLACE "^([A-Za-z0-9_]*-[vV])([0-9]*)([.][0-9]*[.][0-9]*-?.*)$" "\\2" numbers ${versionstring} )
set(major ${numbers} PARENT_SCOPE)
string(REGEX REPLACE "^([A-Za-z0-9_]*-[vV][0-9]*[.])([0-9]*)([.][0-9]*-?.*)$" "\\2" numbers ${versionstring} )
set(minor ${numbers} PARENT_SCOPE)
string(REGEX REPLACE "^([A-Za-z0-9_]*-[vV][0-9]*[.][0-9]*[.])([0-9]*)(-?.*)$" "\\2" numbers ${versionstring} )
set(patch ${numbers} PARENT_SCOPE)
endfunction()
用法:
get_versions("TTN9Lib-V0.1.18" libname major minor patch)
【讨论】:
这里还有一个非常干净的选项:
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)"
MY_PROGRAM_VERSION_MATCH ${MY_PROGRAM_VERSION})
set(MY_PROGRAM_VERSION_MAJOR ${CMAKE_MATCH_1})
set(MY_PROGRAM_VERSION_MINOR ${CMAKE_MATCH_2})
set(MY_PROGRAM_VERSION_PATCH ${CMAKE_MATCH_3})
请注意,MY_PROGRAM_VERSION_MATCH 是完全匹配 (CMAKE_MATCH_0),您可以忽略它,因为您不需要它。
【讨论】: