English | δΈζ
GitVersion.cmake
A lightweight CMake module that extracts version information from Git tags following the Semantic Versioning 2.0.0 specification. This module provides a straightforward way to integrate Git-based versioning into your CMake build process.
- Version Extraction - Reliably extract version information from Git tags with SemVer 2.0.0 format support
- Fallback Mechanism - Graceful handling when Git is unavailable with customizable default versions
- Auto Reconfiguration - CMake automatically reconfigures when Git HEAD changes
- Cross-Platform - Works reliably on Windows, macOS, and Linux
GitVersion.cmake is useful for:
- Automating version management in CMake projects
- Maintaining consistent version information across build artifacts
- Generating version-specific resource files and headers
- Integrating with package systems that require semantic versioning
- CMake 3.12+
- Git
Add GitVersion.cmake to your project with a single command:
# Create cmake directory if it doesn't exist
mkdir -p cmake
# Download the latest version
curl -o cmake/GitVersion.cmake https://github.com/tayne3/GitVersion.cmake/releases/latest/download/GitVersion.cmake
cmake_minimum_required(VERSION 3.12)
include(cmake/GitVersion.cmake)
gitversion_extract(VERSION PROJECT_VERSION)
project(MyProject VERSION ${PROJECT_VERSION})
cmake_minimum_required(VERSION 3.12)
include(cmake/GitVersion.cmake)
# Use only the parameters you need
gitversion_extract(
VERSION MY_VERSION
MAJOR MY_VERSION_MAJOR
)
message(STATUS "Version: ${MY_VERSION}")
message(STATUS "Major version: ${MY_VERSION_MAJOR}")
cmake_minimum_required(VERSION 3.12)
include(cmake/GitVersion.cmake)
gitversion_extract(
VERSION PROJECT_VERSION # Short version output like "1.2.3"
FULL_VERSION PROJECT_FULL_VERSION # Full version output like "1.2.3-dev.5+abc1234"
MAJOR PROJECT_VERSION_MAJOR
MINOR PROJECT_VERSION_MINOR
PATCH PROJECT_VERSION_PATCH
DEFAULT_VERSION "1.0.0" # Custom default version
SOURCE_DIR "${CMAKE_SOURCE_DIR}/lib" # Custom Git repository directory
HASH_LENGTH 7 # Truncate commit hash to 7 characters
FAIL_ON_MISMATCH # Fail if versions don't match
)
version.h.in:
#ifndef VERSION_H
#define VERSION_H
#define PROJECT_VERSION "@PROJECT_VERSION@"
#define PROJECT_FULL_VERSION "@PROJECT_FULL_VERSION@"
#define PROJECT_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
#define PROJECT_VERSION_MINOR @PROJECT_VERSION_MINOR@
#define PROJECT_VERSION_PATCH @PROJECT_VERSION_PATCH@
#endif // VERSION_H
CMakeLists.txt:
cmake_minimum_required(VERSION 3.12)
include(cmake/GitVersion.cmake)
gitversion_extract(
VERSION PROJECT_VERSION
FULL_VERSION PROJECT_FULL_VERSION
MAJOR PROJECT_VERSION_MAJOR
MINOR PROJECT_VERSION_MINOR
PATCH PROJECT_VERSION_PATCH
)
project(MyProject VERSION ${PROJECT_VERSION})
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/include/version.h.in
${CMAKE_CURRENT_BINARY_DIR}/include/version.h
)
add_executable(my_app src/main.cpp)
target_include_directories(my_app PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/include)
GitVersion.cmake operates through a simple workflow:
- Check if Git is available
- If Git is available, run
git describe
to get tag information - Parse the output according to SemVer 2.0.0 format
- Extract major, minor, and patch version components
- Fall back to default version if Git is unavailable
- Set up dependency on
.git/HEAD
for automatic reconfiguration
For optimal use with GitVersion.cmake, we recommend adopting Conventional Commits for your commit messages. This structured commit format enhances your versioning workflow by:
- Clear Version Bumping: Commits with
fix:
prefix trigger patch versions,feat:
trigger minor versions, andBREAKING CHANGE:
trigger major versions - Automated Changelogs: Generate comprehensive changelogs automatically based on structured commit messages
- Better Collaboration: Make your repository history more readable and organized for team members
- CI/CD Integration: Simplify automated release pipelines with predictable version increments
Example commit messages:
feat: add new authentication feature
fix: resolve memory leak in file processing
feat!: redesign API with breaking changes
docs: update README with Conventional Commits information
Using Conventional Commits alongside GitVersion.cmake creates a powerful, automated versioning system that follows semantic versioning principles consistently.
GitVersion.cmake produces the following types of version strings (FULL_VERSION):
- Exact Tag:
1.2.3
(when HEAD is exactly at a tag) - Development Version:
1.2.3-dev.5+abc1234
(5 commits after tag 1.2.3, at commit abc1234) - No Tag:
0.0.0+abc1234
(only commit hash is available)
Parameter | Type | Description | Required | Default |
---|---|---|---|---|
VERSION | Variable | Output variable for short version string (like 1.2.3) | No | - |
FULL_VERSION | Variable | Output variable for full semantic version string (like 1.2.3-dev.5+abc1234) | No | - |
MAJOR | Variable | Output variable for major version number | No | - |
MINOR | Variable | Output variable for minor version number | No | - |
PATCH | Variable | Output variable for patch version number | No | - |
DEFAULT_VERSION | String | Default version used when Git is unavailable | No | "0.0.0" |
SOURCE_DIR | Path | Git repository directory | No | CMAKE_CURRENT_SOURCE_DIR |
HASH_LENGTH | Integer | Length of the git commit hash to include in full version (valid range: 1-40) | No | 7 |
FAIL_ON_MISMATCH | Boolean | Fail if Git tag doesn't match default version | No | False |
Note:
- At least one output parameter (VERSION, FULL_VERSION, MAJOR, MINOR, or PATCH) must be specified.
- If HASH_LENGTH is less than 0 or greater than 40, it will be capped at 40 characters.
- Git information not detected: Make sure the repository has at least one commit and the
.git
directory is accessible. - Version not updating: Check that the
.git/HEAD
file is accessible and that your build system reruns CMake. - Unexpected version format: Ensure your tag format follows SemVer.
Q: Can I use this without Git?
A: Yes, the module falls back to the specified DEFAULT_VERSION when Git is unavailable.
Q: Does this work with CI/CD pipelines?
A: Yes, it works in most CI/CD environments that have Git installed.
Q: Is there a performance impact?
A: The module only runs during CMake configuration, so it has minimal impact on build performance.
Q: How does this work with Conventional Commits?
A: GitVersion.cmake extracts version information from Git tags, which can be created based on Conventional Commits. While it doesn't directly parse commit messages, it integrates perfectly with CI/CD systems that use Conventional Commits to create semantic version tags automatically.
Q: Can I use this for non-SemVer versioning?
A: This module is specifically designed for SemVer 2.0.0 compatibility. Customization would be needed for other schemes.
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a pull request.
- Fork the repository
- Create a feature branch
- Submit a pull request
Please update tests as appropriate for any changes.