Skip to content

Commit 4ab61a7

Browse files
[CMake] Update versioning
Properly set version based on our git tags. For CMake's sake we use major.minor.patch For Windows dll metadata we use major.minor.build.revision and additional variables. Print the dll's metadata in CI, to check correctness.
1 parent 4f82a6c commit 4ab61a7

File tree

8 files changed

+207
-80
lines changed

8 files changed

+207
-80
lines changed

.github/workflows/fast.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,11 @@ jobs:
135135
if: matrix.os == 'windows-latest'
136136
run: ${{github.workspace}}/.github/scripts/check_dll_flags.ps1 ${{github.workspace}}/build/src/proxy_lib/Release/umf_proxy.dll
137137
shell: pwsh
138+
139+
# TODO: We could add some script to verify metadata of dll's (selected fields, perhaps)
140+
# ref. https://superuser.com/questions/381276/what-are-some-nice-command-line-ways-to-inspect-dll-exe-details
141+
- name: Print metadata of our dll's
142+
if: matrix.os == 'windows-latest'
143+
run: |
144+
get-command ${{github.workspace}}/build/bin/Release/umf.dll | format-list
145+
get-command ${{github.workspace}}/build/src/proxy_lib/Release/umf_proxy.dll | format-list

CMakeLists.txt

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,43 @@
33
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
44

55
cmake_minimum_required(VERSION 3.14.0 FATAL_ERROR)
6-
project(
7-
umf
8-
VERSION 0.1.0
9-
LANGUAGES C)
10-
116
# needed when UMF is used as an external project
127
set(UMF_CMAKE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
138

149
list(APPEND CMAKE_MODULE_PATH "${UMF_CMAKE_SOURCE_DIR}/cmake")
15-
include(${UMF_CMAKE_SOURCE_DIR}/cmake/helpers.cmake)
10+
include(helpers)
11+
12+
# Establish version vars based on the git tag and what 'git describe' reports.
13+
# If there's no git available in the OS, the version will be set to "0.0.0".
14+
# Otherwise we'll use 3-component version: major.minor.patch, just for CMake's
15+
# sake. A few extra variables will be set for Win dll metadata.
16+
#
17+
# For all other usages (beside CMake and Win dll), we'll be using semver aligned
18+
# version "UMF_VERSION", which is in line with our tags (e.g. "1.5.0-rc2").
19+
set_version_variables()
20+
project(
21+
umf
22+
VERSION ${UMF_CMAKE_VERSION}
23+
LANGUAGES C)
24+
# BUGFIX = "true" if Patch version > 0
25+
if(CMAKE_PROJECT_VERSION_PATCH GREATER 0)
26+
set(UMF_VERSION_BUGFIX TRUE)
27+
endif()
28+
29+
message(
30+
STATUS
31+
"UMF CMake version: ${UMF_CMAKE_VERSION} (via CMake: ${CMAKE_PROJECT_VERSION})\n"
32+
"UMF version: ${UMF_VERSION}\n"
33+
"UMF_VERSION_REVISION: ${UMF_VERSION_REVISION}\n"
34+
"UMF_VERSION_PRERELEASE: ${UMF_VERSION_PRERELEASE}\n"
35+
"UMF_VERSION_PRIVATE: ${UMF_VERSION_PRIVATE}\n"
36+
"UMF_VERSION_BUGFIX: ${UMF_VERSION_BUGFIX}")
1637

1738
include(CTest)
1839
include(CMakePackageConfigHelpers)
1940
include(GNUInstallDirs)
2041
find_package(PkgConfig)
2142

22-
# CMAKE_PROJECT_VERSION[_MAJOR|_MINOR|_PATCH] variables are set via 'project'
23-
# command. They cannot contain any "pre-release" part, though. We use custom
24-
# "UMF_SRC_VERSION" to store more accurate (source) version - this var should be
25-
# used, e.g., for creating packages.
26-
set_source_version()
27-
message(
28-
STATUS
29-
"UMF version: ${CMAKE_PROJECT_VERSION} (source version: ${UMF_SRC_VERSION})"
30-
)
31-
3243
# Build Options
3344
option(UMF_BUILD_SHARED_LIBRARY "Build UMF as shared library" OFF)
3445
option(UMF_BUILD_LEVEL_ZERO_PROVIDER "Build Level Zero memory provider" ON)

RELEASE_STEPS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Do changes for a release:
4040
- Add an entry to ChangeLog, remember to change the day of the week in the release date
4141
- For major releases mention API and ABI compatibility with the previous release
4242
- Update project's version in a few places:
43-
- Set the new $VERSION in `project` function in the top-level `CMakeLists.txt`
43+
- For major and minor releases: `UMF_MAKE_VERSION` in `include/umf/base.h` (the API version)
4444
- `release` variable in `scripts/docs_config/conf.py` (for docs)
4545
- `UMF_VERSION` variable in `.github/workflows/basic.yml` (for installation test)
4646
- For major releases update ABI version in `.map` and `.def` files

cmake/helpers.cmake

Lines changed: 137 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,68 +10,156 @@
1010
include(CheckCCompilerFlag)
1111
include(CheckCXXCompilerFlag)
1212

13-
# src version shows the current version, as reported by 'git describe', unless
14-
# 'git' is not available, then fall back to the top-level defined version
15-
function(set_source_version)
13+
# We use semver aligned version, set via git tags. Here, we parse git output to
14+
# establih the version of UMF to be used in CMake, Win dll's, and within the
15+
# code (e.g. in logger). We have 3-component releases (e.g. 1.5.1) plus release
16+
# candidates and git info.
17+
#
18+
# Unfortunately, CMake does not support rc or git information. According to
19+
# semver rules, 1.5.1-rc1 should be less than 1.5.1, but it seems hard to
20+
# achieve such comparison in CMake, though. So, for CMake's sake we only set
21+
# 3-component version in variable "UMF_CMAKE_VERSION", ignoring the rc and git
22+
# information. It's only used to set SOVERSION and creating "umf-config.cmake".
23+
#
24+
# For Windows versioning in dll metadata, we use 4-component version plus a few
25+
# additional variables. REVISION has to be an integer and is calculated as:
26+
# REVISION = rc_no * 1000 + git_commit_no (commits count after the last release)
27+
#
28+
# Example parsing of git output:
29+
# cmake-format: off
30+
# +-----------------------+-------+-------+-------+----------+--------+---------+------------+
31+
# | \ CMake:| Major | Minor | Patch | | | | |
32+
# +-----------------------+-------+-------+-------+----------+--------+---------+------------+
33+
# | git describe \ Win32:| MAJOR | MINOR | BUILD | REVISION | BUGFIX | PRIVATE | PRERELEASE |
34+
# +-----------------------+-------+-------+-------+----------+--------+---------+------------+
35+
# | 1.5.0-rc2-0-gb8f7a32 | 1 | 5 | 0 | 2000 | | | true |
36+
# | 1.5.0-rc2 | 1 | 5 | 0 | 2000 | | | true |
37+
# | 1.5.0-rc3-6-gb8f7a32 | 1 | 5 | 0 | 3006 | | true | true |
38+
# | 1.5.0-0-gb8f7a32 | 1 | 5 | 0 | 0 | | | |
39+
# | 1.5.0 | 1 | 5 | 0 | 0 | | | |
40+
# | 1.5.0-6-123345678 | 1 | 5 | 0 | 6 | | true | |
41+
# | 1.5.2-rc1-0-gb8f7a32 | 1 | 5 | 2 | 1000 | true | | true |
42+
# | 1.5.2-rc4-6-gb8f7a32 | 1 | 5 | 2 | 4006 | true | true | true |
43+
# | 1.5.2-0-gb8f7a32 | 1 | 5 | 2 | 0 | true | | |
44+
# | 1.5.2-6-gb8f7a32 | 1 | 5 | 2 | 6 | true | true | |
45+
# | gb8f7a32 | 0 | 0 | 0 | 0 | | true | |
46+
# | ? (no git) | 0 | 0 | 0 | 0 | | true | |
47+
# +-----------------------+-------+-------+-------+----------+--------+---------+------------+
48+
# cmake-format: on
49+
function(set_version_variables)
50+
# default values
51+
set(UMF_VERSION_PRERELEASE
52+
FALSE
53+
PARENT_SCOPE)
54+
set(UMF_VERSION_PRIVATE
55+
TRUE
56+
PARENT_SCOPE)
57+
set(UMF_VERSION_BUGFIX
58+
FALSE
59+
PARENT_SCOPE)
60+
set(UMF_VERSION_REVISION
61+
0
62+
PARENT_SCOPE)
63+
set(UMF_CMAKE_VERSION
64+
"0.0.0"
65+
PARENT_SCOPE)
66+
set(UMF_VERSION
67+
"0.0.0"
68+
PARENT_SCOPE)
69+
1670
execute_process(
1771
COMMAND git describe --always
1872
OUTPUT_VARIABLE GIT_VERSION
1973
WORKING_DIRECTORY ${UMF_CMAKE_SOURCE_DIR}
2074
OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
2175

22-
if(GIT_VERSION)
23-
# 1.5.0 - we're on a tag
24-
string(REGEX MATCHALL "\^([0-9]+\.[0-9]+\.[0-9]+)\$" MATCHES
25-
${GIT_VERSION})
26-
if(MATCHES)
27-
set(UMF_SRC_VERSION
28-
"${CMAKE_MATCH_1}"
29-
PARENT_SCOPE)
30-
return()
31-
endif()
76+
if(NOT GIT_VERSION)
77+
# no git or it reported no version. Use default ver: "0.0.0"
78+
return()
79+
endif()
3280

33-
# 1.5.0-rc1 - we're on a RC tag
34-
string(REGEX MATCHALL "\^([0-9]+\.[0-9]+\.[0-9]+\-rc[0-9]+)\$" MATCHES
35-
${GIT_VERSION})
36-
if(MATCHES)
37-
set(UMF_SRC_VERSION
38-
"${CMAKE_MATCH_1}"
39-
PARENT_SCOPE)
40-
return()
41-
endif()
81+
message(STATUS "GIT_VERSION: ${GIT_VERSION}")
4282

43-
# 1.5.0-rc1-19-gb8f78a329 -> 1.5.0-rc1.git19.gb8f78a329
44-
string(REGEX MATCHALL "([0-9.]*)-rc([0-9]*)-([0-9]*)-([0-9a-g]*)"
45-
MATCHES ${GIT_VERSION})
46-
if(MATCHES)
47-
set(UMF_SRC_VERSION
48-
"${CMAKE_MATCH_1}-rc${CMAKE_MATCH_2}.git${CMAKE_MATCH_3}.${CMAKE_MATCH_4}"
49-
PARENT_SCOPE)
50-
return()
51-
endif()
83+
# v1.5.0 - we're exactly on a tag -> UMF ver: "1.5.0"
84+
string(REGEX MATCHALL "\^v([0-9]+\.[0-9]+\.[0-9]+)\$" MATCHES
85+
${GIT_VERSION})
86+
if(MATCHES)
87+
set(UMF_VERSION
88+
"${CMAKE_MATCH_1}"
89+
PARENT_SCOPE)
90+
set(UMF_CMAKE_VERSION
91+
"${CMAKE_MATCH_1}"
92+
PARENT_SCOPE)
93+
set(UMF_VERSION_PRIVATE
94+
FALSE
95+
PARENT_SCOPE)
96+
return()
97+
endif()
5298

53-
# 1.5.0-19-gb8f78a329 -> 1.5.0-git19.gb8f78a329
54-
string(REGEX MATCHALL "([0-9.]*)-([0-9]*)-([0-9a-g]*)" MATCHES
55-
${GIT_VERSION})
56-
if(MATCHES)
57-
set(UMF_SRC_VERSION
58-
"${CMAKE_MATCH_1}-git${CMAKE_MATCH_2}.${CMAKE_MATCH_3}"
59-
PARENT_SCOPE)
60-
return()
61-
endif()
99+
# v1.5.0-rc1 - we're on a RC tag -> UMF ver: "1.5.0-rc1"
100+
string(REGEX MATCHALL "\^v([0-9]+\.[0-9]+\.[0-9]+)-rc([0-9]+)\$" MATCHES
101+
${GIT_VERSION})
102+
if(MATCHES)
103+
set(UMF_VERSION
104+
"${CMAKE_MATCH_1}-rc${CMAKE_MATCH_2}"
105+
PARENT_SCOPE)
106+
set(UMF_CMAKE_VERSION
107+
"${CMAKE_MATCH_1}"
108+
PARENT_SCOPE)
109+
math(EXPR revision "${CMAKE_MATCH_2} * 1000")
110+
set(UMF_VERSION_REVISION
111+
${revision}
112+
PARENT_SCOPE)
113+
set(UMF_VERSION_PRERELEASE
114+
TRUE
115+
PARENT_SCOPE)
116+
set(UMF_VERSION_PRIVATE
117+
FALSE
118+
PARENT_SCOPE)
119+
return()
120+
endif()
62121

63-
# no full version is available (e.g. only a hash commit) or a pattern
64-
# was not recognized
65-
set(UMF_SRC_VERSION
66-
"${CMAKE_PROJECT_VERSION}.git.${GIT_VERSION}"
122+
# v1.5.0-rc1-19-gb8f7a32 -> UMF ver: "1.5.0-rc1.git19.gb8f7a32"
123+
string(REGEX MATCHALL "v([0-9.]*)-rc([0-9]*)-([0-9]*)-([0-9a-g]*)" MATCHES
124+
${GIT_VERSION})
125+
if(MATCHES)
126+
set(UMF_VERSION
127+
"${CMAKE_MATCH_1}-rc${CMAKE_MATCH_2}.git${CMAKE_MATCH_3}.${CMAKE_MATCH_4}"
128+
PARENT_SCOPE)
129+
set(UMF_CMAKE_VERSION
130+
"${CMAKE_MATCH_1}"
67131
PARENT_SCOPE)
68-
else()
69-
# git reported no version. Use version set up in the top-level CMake
70-
# with a "devel" suffix
71-
set(UMF_SRC_VERSION
72-
"${CMAKE_PROJECT_VERSION}-devel"
132+
math(EXPR revision "${CMAKE_MATCH_2} * 1000 + ${CMAKE_MATCH_3}")
133+
set(UMF_VERSION_REVISION
134+
${revision}
73135
PARENT_SCOPE)
136+
set(UMF_VERSION_PRERELEASE
137+
TRUE
138+
PARENT_SCOPE)
139+
return()
140+
endif()
141+
142+
# v1.5.0-19-gb8f7a32 -> UMF ver: "1.5.0-git19.gb8f7a32"
143+
string(REGEX MATCHALL "v([0-9.]*)-([0-9]*)-([0-9a-g]*)" MATCHES
144+
${GIT_VERSION})
145+
if(MATCHES)
146+
set(UMF_VERSION
147+
"${CMAKE_MATCH_1}-git${CMAKE_MATCH_2}.${CMAKE_MATCH_3}"
148+
PARENT_SCOPE)
149+
set(UMF_CMAKE_VERSION
150+
"${CMAKE_MATCH_1}"
151+
PARENT_SCOPE)
152+
set(UMF_VERSION_REVISION
153+
${CMAKE_MATCH_2}
154+
PARENT_SCOPE)
155+
return()
74156
endif()
157+
158+
# no full version is available (e.g. only a hash commit) or a pattern was
159+
# not recognized -> UMF ver: "0.0.0.git.<hash>"
160+
set(UMF_VERSION
161+
"0.0.0.git.${GIT_VERSION}"
162+
PARENT_SCOPE)
75163
endfunction()
76164

77165
# Sets ${ret} to version of program specified by ${name} in major.minor format

src/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ set(UMF_SOURCES_WINDOWS libumf_windows.c)
8181
# Compile definitions for UMF library.
8282
#
8383
# TODO: Cleanup the compile definitions across all the CMake files
84-
set(UMF_PRIVATE_COMPILE_DEFINITIONS UMF_SRC_VERSION=${UMF_SRC_VERSION})
84+
set(UMF_PRIVATE_COMPILE_DEFINITIONS UMF_VERSION=${UMF_VERSION})
8585

8686
set(UMF_SOURCES_COMMON_LINUX_MACOSX
8787
provider/provider_os_memory.c

src/libumf.rc.in

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,38 @@
88

99
#include "umf/base.h"
1010

11-
#define UMF_VERNUMBERS @CMAKE_PROJECT_VERSION_MAJOR@,@CMAKE_PROJECT_VERSION_MINOR@,@CMAKE_PROJECT_VERSION_PATCH@,0
11+
#define UMF_VERNUMBERS @CMAKE_PROJECT_VERSION_MAJOR@,@CMAKE_PROJECT_VERSION_MINOR@,@CMAKE_PROJECT_VERSION_PATCH@,@UMF_VERSION_REVISION@
1212
#define UMF_VERSION "@CMAKE_PROJECT_VERSION_MAJOR@.@CMAKE_PROJECT_VERSION_MINOR@"
1313

14+
#ifdef _DEBUG
15+
#define VERSION_DEBUG VS_FF_DEBUG
16+
#else
17+
#define VERSION_DEBUG 0
18+
#endif
19+
20+
#if @UMF_VERSION_PRERELEASE@
21+
#define VERSION_PRERELEASE VS_FF_PRERELEASE
22+
#else
23+
#define VERSION_PRERELEASE 0
24+
#endif
25+
26+
#if @UMF_VERSION_PRIVATE@
27+
#define VERSION_PRIVATE VS_FF_PRIVATEBUILD
28+
#else
29+
#define VERSION_PRIVATE 0
30+
#endif
31+
32+
#if @UMF_VERSION_BUGFIX@
33+
#define VERSION_PATCHED VS_FF_PATCHED
34+
#else
35+
#define VERSION_PATCHED 0
36+
#endif
37+
1438
VS_VERSION_INFO VERSIONINFO
1539
FILEVERSION UMF_VERNUMBERS
1640
PRODUCTVERSION UMF_VERNUMBERS
1741
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
18-
#ifdef _DEBUG
19-
FILEFLAGS VS_FF_DEBUG
20-
#else
21-
FILEFLAGS 0
22-
#endif
42+
FILEFLAGS (VERSION_DEBUG | VERSION_PRIVATE | VERSION_PRERELEASE | VERSION_PATCHED)
2343
FILEOS VOS__WINDOWS32
2444
FILETYPE VFT_DLL
2545
FILESUBTYPE 0

src/proxy_lib/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ add_library(${PROJECT_NAME}::proxy ALIAS umf_proxy)
3939

4040
target_link_directories(umf_proxy PRIVATE ${LIBHWLOC_LIBRARY_DIRS})
4141

42-
target_compile_definitions(umf_proxy PRIVATE UMF_SRC_VERSION=${UMF_SRC_VERSION})
42+
target_compile_definitions(umf_proxy PRIVATE UMF_VERSION=${UMF_VERSION})
4343

4444
if(PROXY_LIB_USES_SCALABLE_POOL)
4545
target_compile_definitions(umf_proxy PRIVATE PROXY_LIB_USES_SCALABLE_POOL=1)

src/utils/utils_log.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -305,18 +305,18 @@ void util_log_init(void) {
305305
loggerConfig.flushLevel = LOG_FATAL;
306306
}
307307

308-
#ifdef UMF_SRC_VERSION
308+
#ifdef UMF_VERSION
309309
// convert a define to a C string
310310
#define STR_(X) #X
311311
#define STR(X) STR_(X)
312-
#define STR_UMF_SRC_VERSION "src version: " STR(UMF_SRC_VERSION) ", "
313-
#else /* !UMF_SRC_VERSION */
314-
#define STR_UMF_SRC_VERSION ""
315-
#endif /* !UMF_SRC_VERSION */
312+
#define STR_UMF_VERSION "UMF version: " STR(UMF_VERSION) ", "
313+
#else /* !UMF_VERSION */
314+
#define STR_UMF_VERSION ""
315+
#endif /* !UMF_VERSION */
316316

317317
int umf_ver = umfGetCurrentVersion();
318318
LOG_INFO(
319-
"Logger enabled (umf version: %i.%i, " STR_UMF_SRC_VERSION
319+
"Logger enabled (umf version: %i.%i, " STR_UMF_VERSION
320320
"level: %s, flush: %s, pid: %s, timestamp: %s)",
321321
UMF_MAJOR_VERSION(umf_ver), UMF_MINOR_VERSION(umf_ver),
322322
level_to_str(loggerConfig.level), level_to_str(loggerConfig.flushLevel),

0 commit comments

Comments
 (0)