Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,56 @@ Your documentation will be automatically built and deployed to `https://your-org

## API Reference

### `cpp_library_set_version`

```cmake
cpp_library_set_version()
```

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.

**Usage:**

```cmake
project(my-library) # No VERSION specified
cpp_library_set_version()
# Now PROJECT_VERSION, PROJECT_VERSION_MAJOR, PROJECT_VERSION_MINOR,
# and PROJECT_VERSION_PATCH are set from git tags
```

The function:
- Queries git tags using `git describe --tags --abbrev=0`
- Strips the 'v' prefix if present (e.g., `v1.2.3` → `1.2.3`)
- Respects `CPP_LIBRARY_VERSION` cache variable if set (for package managers)
- Falls back to `0.0.0` if no tag found
- Updates all `PROJECT_VERSION*` variables in parent scope

**When to use:**
- You have a custom library setup that doesn't use `cpp_library_setup()`
- You want to remove hardcoded versions from your `project()` declaration
- You're migrating to cpp-library incrementally

**Example for stlab/libraries:**

```cmake
cmake_minimum_required(VERSION 3.24)
include(cmake/CPM.cmake)

CPMAddPackage("gh:stlab/cpp-library@5.1.1")
include(${cpp-library_SOURCE_DIR}/cpp-library.cmake)

cpp_library_enable_dependency_tracking()

project(stlab LANGUAGES CXX) # No hardcoded version

# Set version from git tags
cpp_library_set_version()

# Custom library setup continues...
add_library(stlab)
# ... rest of CMakeLists.txt
```

### `cpp_library_setup`

```cmake
Expand Down
2 changes: 1 addition & 1 deletion cmake/cpp-library-install.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ function(_cpp_library_setup_install)
CALL _cpp_library_setup_install_validation)

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

endfunction()
Expand Down
59 changes: 44 additions & 15 deletions cpp-library.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,42 @@
# Determine the directory where this file is located
get_filename_component(CPP_LIBRARY_ROOT "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY)

# Public function to update 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.
#
# Usage:
# project(my-library) # No VERSION specified
# cpp_library_set_version()
# # Now PROJECT_VERSION and related variables are set from git tags
#
# The function respects CPP_LIBRARY_VERSION if set (e.g., by package managers),
# otherwise queries git tags, stripping the 'v' prefix if present.
function(cpp_library_set_version)
# Get version from git tags (respects CPP_LIBRARY_VERSION override)
_cpp_library_get_git_version(GIT_VERSION)

# Parse version components
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)" VERSION_MATCH "${GIT_VERSION}")
if(VERSION_MATCH)
set(VERSION_MAJOR ${CMAKE_MATCH_1})
set(VERSION_MINOR ${CMAKE_MATCH_2})
set(VERSION_PATCH ${CMAKE_MATCH_3})
else()
set(VERSION_MAJOR 0)
set(VERSION_MINOR 0)
set(VERSION_PATCH 0)
endif()

# Update project version in parent scope
set(PROJECT_VERSION ${GIT_VERSION} PARENT_SCOPE)
set(PROJECT_VERSION_MAJOR ${VERSION_MAJOR} PARENT_SCOPE)
set(PROJECT_VERSION_MINOR ${VERSION_MINOR} PARENT_SCOPE)
set(PROJECT_VERSION_PATCH ${VERSION_PATCH} PARENT_SCOPE)

message(STATUS "cpp-library: Set project version to ${GIT_VERSION} from git tags")
endfunction()

# Enable dependency tracking for accurate find_dependency() generation
# This function should be called BEFORE project() to install the dependency provider.
# Requires CMake 3.24+.
Expand Down Expand Up @@ -197,23 +233,16 @@ function(cpp_library_setup)
set(ARG_REQUIRES_CPP_VERSION 17)
endif()

# Get version from git tags
_cpp_library_get_git_version(GIT_VERSION)
set(ARG_VERSION "${GIT_VERSION}")
# Get version from git tags and update project version variables
cpp_library_set_version()

# Parse version components
string(REGEX MATCH "^([0-9]+)\\.([0-9]+)\\.([0-9]+)" VERSION_MATCH "${ARG_VERSION}")
if(VERSION_MATCH)
set(ARG_VERSION_MAJOR ${CMAKE_MATCH_1})
set(ARG_VERSION_MINOR ${CMAKE_MATCH_2})
set(ARG_VERSION_PATCH ${CMAKE_MATCH_3})
else()
set(ARG_VERSION_MAJOR 0)
set(ARG_VERSION_MINOR 0)
set(ARG_VERSION_PATCH 0)
endif()
# Retrieve the version that was just set
set(ARG_VERSION "${PROJECT_VERSION}")
set(ARG_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(ARG_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(ARG_VERSION_PATCH ${PROJECT_VERSION_PATCH})

# Update project version
# Propagate project version to caller's scope (backward compatibility)
set(PROJECT_VERSION ${ARG_VERSION} PARENT_SCOPE)
set(PROJECT_VERSION_MAJOR ${ARG_VERSION_MAJOR} PARENT_SCOPE)
set(PROJECT_VERSION_MINOR ${ARG_VERSION_MINOR} PARENT_SCOPE)
Expand Down