Skip to content

Commit 3c81a15

Browse files
committed
Add cpp_library_set_version for git-based versioning
Introduces the cpp_library_set_version() function to set project version variables from git tags after project() is called, enabling git-based versioning for custom setups. Updates documentation with usage instructions and refactors cpp_library_setup() to use the new function for version management.
1 parent e94509a commit 3c81a15

File tree

3 files changed

+94
-21
lines changed

3 files changed

+94
-21
lines changed

README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,56 @@ Your documentation will be automatically built and deployed to `https://your-org
258258

259259
## API Reference
260260

261+
### `cpp_library_set_version`
262+
263+
```cmake
264+
cpp_library_set_version()
265+
```
266+
267+
Updates the project version from git tags after `project()` has been called. This is useful for projects that need custom setup and can't use `cpp_library_setup()` but still want automatic git-based versioning.
268+
269+
**Usage:**
270+
271+
```cmake
272+
project(my-library) # No VERSION specified
273+
cpp_library_set_version()
274+
# Now PROJECT_VERSION, PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR,
275+
# and PROJECT_VERSION_PATCH are set from git tags
276+
```
277+
278+
The function:
279+
- Queries git tags using `git describe --tags --abbrev=0`
280+
- Strips the 'v' prefix if present (e.g., `v1.2.3``1.2.3`)
281+
- Respects `CPP_LIBRARY_VERSION` cache variable if set (for package managers)
282+
- Falls back to `0.0.0` if no tag found
283+
- Updates all `PROJECT_VERSION*` variables in parent scope
284+
285+
**When to use:**
286+
- You have a custom library setup that doesn't use `cpp_library_setup()`
287+
- You want to remove hardcoded versions from your `project()` declaration
288+
- You're migrating to cpp-library incrementally
289+
290+
**Example for stlab/libraries:**
291+
292+
```cmake
293+
cmake_minimum_required(VERSION 3.24)
294+
include(cmake/CPM.cmake)
295+
296+
CPMAddPackage("gh:stlab/[email protected]")
297+
include(${cpp-library_SOURCE_DIR}/cpp-library.cmake)
298+
299+
cpp_library_enable_dependency_tracking()
300+
301+
project(stlab LANGUAGES CXX) # No hardcoded version
302+
303+
# Set version from git tags
304+
cpp_library_set_version()
305+
306+
# Custom library setup continues...
307+
add_library(stlab)
308+
# ... rest of CMakeLists.txt
309+
```
310+
261311
### `cpp_library_setup`
262312

263313
```cmake

cmake/cpp-library-install.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ function(_cpp_library_setup_install)
482482
CALL _cpp_library_setup_install_validation)
483483

484484
# Register config generation second so it runs first (LIFO) and sets properties
485-
cmake_language(DEFER DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
485+
cmake_language(DEFER DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
486486
CALL _cpp_library_deferred_generate_config)
487487

488488
endfunction()

cpp-library.cmake

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,42 @@
88
# Determine the directory where this file is located
99
get_filename_component(CPP_LIBRARY_ROOT "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)
1010

11+
# Public function to update project version from git tags after project() has been called.
12+
# This is useful for projects that need custom setup and can't use cpp_library_setup()
13+
# but still want automatic git-based versioning.
14+
#
15+
# Usage:
16+
# project(my-library) # No VERSION specified
17+
# cpp_library_set_version()
18+
# # Now PROJECT_VERSION and related variables are set from git tags
19+
#
20+
# The function respects CPP_LIBRARY_VERSION if set (e.g., by package managers),
21+
# otherwise queries git tags, stripping the 'v' prefix if present.
22+
function(cpp_library_set_version)
23+
# Get version from git tags (respects CPP_LIBRARY_VERSION override)
24+
_cpp_library_get_git_version(GIT_VERSION)
25+
26+
# Parse version components
27+
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)" VERSION_MATCH "${GIT_VERSION}")
28+
if(VERSION_MATCH)
29+
set(VERSION_MAJOR ${CMAKE_MATCH_1})
30+
set(VERSION_MINOR ${CMAKE_MATCH_2})
31+
set(VERSION_PATCH ${CMAKE_MATCH_3})
32+
else()
33+
set(VERSION_MAJOR 0)
34+
set(VERSION_MINOR 0)
35+
set(VERSION_PATCH 0)
36+
endif()
37+
38+
# Update project version in parent scope
39+
set(PROJECT_VERSION ${GIT_VERSION} PARENT_SCOPE)
40+
set(PROJECT_VERSION_MAJOR ${VERSION_MAJOR} PARENT_SCOPE)
41+
set(PROJECT_VERSION_MINOR ${VERSION_MINOR} PARENT_SCOPE)
42+
set(PROJECT_VERSION_PATCH ${VERSION_PATCH} PARENT_SCOPE)
43+
44+
message(STATUS "cpp-library: Set project version to ${GIT_VERSION} from git tags")
45+
endfunction()
46+
1147
# Enable dependency tracking for accurate find_dependency() generation
1248
# This function should be called BEFORE project() to install the dependency provider.
1349
# Requires CMake 3.24+.
@@ -197,27 +233,14 @@ function(cpp_library_setup)
197233
set(ARG_REQUIRES_CPP_VERSION 17)
198234
endif()
199235

200-
# Get version from git tags
201-
_cpp_library_get_git_version(GIT_VERSION)
202-
set(ARG_VERSION "${GIT_VERSION}")
203-
204-
# Parse version components
205-
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)" VERSION_MATCH "${ARG_VERSION}")
206-
if(VERSION_MATCH)
207-
set(ARG_VERSION_MAJOR ${CMAKE_MATCH_1})
208-
set(ARG_VERSION_MINOR ${CMAKE_MATCH_2})
209-
set(ARG_VERSION_PATCH ${CMAKE_MATCH_3})
210-
else()
211-
set(ARG_VERSION_MAJOR 0)
212-
set(ARG_VERSION_MINOR 0)
213-
set(ARG_VERSION_PATCH 0)
214-
endif()
236+
# Get version from git tags and update project version variables
237+
cpp_library_set_version()
215238

216-
# Update project version
217-
set(PROJECT_VERSION ${ARG_VERSION} PARENT_SCOPE)
218-
set(PROJECT_VERSION_MAJOR ${ARG_VERSION_MAJOR} PARENT_SCOPE)
219-
set(PROJECT_VERSION_MINOR ${ARG_VERSION_MINOR} PARENT_SCOPE)
220-
set(PROJECT_VERSION_PATCH ${ARG_VERSION_PATCH} PARENT_SCOPE)
239+
# Retrieve the version that was just set
240+
set(ARG_VERSION "${PROJECT_VERSION}")
241+
set(ARG_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
242+
set(ARG_VERSION_MINOR ${PROJECT_VERSION_MINOR})
243+
set(ARG_VERSION_PATCH ${PROJECT_VERSION_PATCH})
221244

222245
# Generate full paths for HEADERS and SOURCES based on conventions
223246
set(GENERATED_HEADERS "")

0 commit comments

Comments
 (0)