-
-
Notifications
You must be signed in to change notification settings - Fork 1k
/
VersionInfo.cmake
125 lines (115 loc) · 4.75 KB
/
VersionInfo.cmake
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
FIND_PACKAGE(Git)
IF(GIT_FOUND AND NOT FORCE_VERSION)
SET(MAJOR_VERSION 0)
SET(MINOR_VERSION 0)
SET(PATCH_VERSION 0)
# If this is a GitHub Actions pull request build, get the pull request
# number from the environment and add it to the build metadata
if("$ENV{GITHUB_REF}" MATCHES "refs/pull/([0-9]+)/merge")
list(APPEND BUILD_METADATA "pr${CMAKE_MATCH_1}")
endif()
# Look for git tag information (e.g. Tagged: "v1.0.0", Untagged: "v1.0.0-123-a1b2c3d")
# Untagged format: [latest tag]-[number of commits]-[latest commit hash]
EXECUTE_PROCESS(
COMMAND "${GIT_EXECUTABLE}" describe --tags --match v[0-9].[0-9].[0-9]*
OUTPUT_VARIABLE GIT_TAG
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
TIMEOUT 10
OUTPUT_STRIP_TRAILING_WHITESPACE)
# Read: TAG_LIST = GIT_TAG.split("-")
STRING(REPLACE "-" ";" TAG_LIST "${GIT_TAG}")
# Read: TAG_LIST_LENGTH = TAG_LIST.length()
LIST(LENGTH TAG_LIST TAG_LIST_LENGTH)
# Untagged versions contain at least 2 dashes, giving 3 strings on split.
# Hence, for untagged versions TAG_LIST_LENGTH = [dashes in latest tag] + 3.
# Corollary: if TAG_LIST_LENGTH <= 2, the version must be tagged.
IF(TAG_LIST_LENGTH GREATER 0)
# Set FORCE_VERSION to TAG_LIST[0], strip any 'v's to get MAJ.MIN.PAT
LIST(GET TAG_LIST 0 FORCE_VERSION)
STRING(REPLACE "v" "" FORCE_VERSION "${FORCE_VERSION}")
# Split FORCE_VERSION on '.' and populate MAJOR/MINOR/PATCH_VERSION
STRING(REPLACE "." ";" MAJ_MIN_PAT "${FORCE_VERSION}")
LIST(GET MAJ_MIN_PAT 0 MAJOR_VERSION)
LIST(GET MAJ_MIN_PAT 1 MINOR_VERSION)
LIST(GET MAJ_MIN_PAT 2 PATCH_VERSION)
ENDIF()
# 1 dash total: Dash in latest tag, no additional commits => pre-release
IF(TAG_LIST_LENGTH EQUAL 2)
# Get the pre-release stage
LIST(GET TAG_LIST 1 VERSION_STAGE)
list(APPEND PRERELEASE_DATA "${VERSION_STAGE}")
# 2 dashes: Assume untagged with no dashes in latest tag name => stable + commits
ELSEIF(TAG_LIST_LENGTH EQUAL 3)
# Get the number of commits and latest commit hash
LIST(GET TAG_LIST 1 EXTRA_COMMITS)
LIST(GET TAG_LIST 2 COMMIT_HASH)
list(APPEND PRERELEASE_DATA "${EXTRA_COMMITS}")
list(APPEND BUILD_METADATA "${COMMIT_HASH}")
# Bump the patch version, since a pre-release (as specified by the extra
# commits) compares lower than the main version alone
MATH(EXPR PATCH_VERSION "${PATCH_VERSION}+1")
# Reassemble the main version using the new patch version
set(FORCE_VERSION "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}")
# 3 dashes: Assume untagged with 1 dash in latest tag name => pre-release + commits
ELSEIF(TAG_LIST_LENGTH EQUAL 4)
# Get the pre-release stage, number of commits, and latest commit hash
LIST(GET TAG_LIST 1 VERSION_STAGE)
LIST(GET TAG_LIST 2 EXTRA_COMMITS)
LIST(GET TAG_LIST 3 COMMIT_HASH)
list(APPEND PRERELEASE_DATA "${VERSION_STAGE}")
list(APPEND PRERELEASE_DATA "${EXTRA_COMMITS}")
list(APPEND BUILD_METADATA "${COMMIT_HASH}")
ENDIF()
# If there is any pre-release data, append it after a hyphen
if(PRERELEASE_DATA)
string(REPLACE ";" "." PRERELEASE_DATA "${PRERELEASE_DATA}")
set(FORCE_VERSION "${FORCE_VERSION}-${PRERELEASE_DATA}")
endif()
# If there is any build metadata, append it after a plus
if(BUILD_METADATA)
string(REPLACE ";" "." BUILD_METADATA "${BUILD_METADATA}")
set(FORCE_VERSION "${FORCE_VERSION}+${BUILD_METADATA}")
endif()
ENDIF()
IF(FORCE_VERSION STREQUAL "internal")
# Use release info from /CMakeLists.txt
ELSEIF(FORCE_VERSION)
STRING(REPLACE "." ";" VERSION_LIST "${FORCE_VERSION}")
LIST(LENGTH VERSION_LIST VERSION_LENGTH)
LIST(GET VERSION_LIST 0 VERSION_MAJOR)
LIST(GET VERSION_LIST 1 VERSION_MINOR)
LIST(GET VERSION_LIST 2 VERSION_RELEASE)
SET(VERSION_STAGE "")
SET(VERSION_BUILD 0)
IF(VERSION_LENGTH GREATER 3)
LIST(GET VERSION_LIST 3 VERSION_BUILD)
ENDIF()
STRING(REPLACE "-" ";" VERSION_LIST "${VERSION_RELEASE}")
LIST(LENGTH VERSION_LIST VERSION_LENGTH)
IF(VERSION_LENGTH GREATER 1)
LIST(GET VERSION_LIST 0 VERSION_RELEASE)
LIST(GET VERSION_LIST 1 VERSION_STAGE)
ENDIF()
SET(VERSION "${FORCE_VERSION}")
ELSEIF(GIT_FOUND)
MESSAGE(
"Could not get project version. Using release info from /CMakeLists.txt"
)
ELSE()
MESSAGE("Git not found. Using release info from /CMakeLists.txt")
ENDIF()
MESSAGE("\n"
"Configuring ${PROJECT_NAME_UCASE}\n"
"--------------------------\n"
"* Project version : ${VERSION}\n"
"* Major version : ${VERSION_MAJOR}\n"
"* Minor version : ${VERSION_MINOR}\n"
"* Release version : ${VERSION_RELEASE}\n"
"* Stage version : ${VERSION_STAGE}\n"
"* Build version : ${VERSION_BUILD}\n"
"*\n\n"
"Optional Version Usage:\n"
"--------------------------\n"
"* Override version: -DFORCE_VERSION=x.x.x-x\n"
"* Ignore Git information: -DFORCE_VERSION=internal\n"
)