This project embeds up-to-date git metadata in a standalone C/C++ static library via CMake. It's written responsibly to only trigger rebuilds if git metadata changes (e.g. a new commit is added). The core capability is baked into single self-contained script.
- CMake >= 3.2
- C Compiler (with C99 standard support)
- Git
You can use CMake's FetchContent
module to build the object library cmake_git_version_tracking
:
include(FetchContent)
FetchContent_Declare(
cmake_git_version_tracking
GIT_REPOSITORY https://github.com/Seclous/cmake-git-version-tracking.git
GIT_TAG 35cfafd13e69c721c88eed29216f204cdb11ccbe)
FetchContent_MakeAvailable(cmake_git_version_tracking)
target_sources(your_target PRIVATE
$<TARGET_OBJECTS:cmake_git_version_tracking>)
target_include_directories(your_target
PRIVATE
$<TARGET_PROPERTY:cmake_git_version_tracking,INTERFACE_INCLUDE_DIRECTORIES>)
Then #include git.h
and use the provided functions to retrieve git metadata.
You're continuously shipping prebuilt binaries for an application. A user discovers a bug and files a bug report. By embedding up-to-date versioning information, the user can include this information in their report, e.g.:
Commit SHA1: 46a396e (46a396e6c1eb3d)
Dirty: false (there were no uncommitted changes at time of build)
This allows you to investigate the precise version of the application that the bug was reported in.
Fork the project and modify git_watcher.cmake
to track new additional fields (e.g. kernel version or build hostname).
Sections that need to be modified are marked with >>>
.
It depends on your specific requirements. Before writing this, I found two categories of existing solutions:
-
Write the commit ID to the header at configure time (e.g.
cmake <source_dir>
). This works well for automated build processes (e.g. check-in code and build artifacts). However, any changes made after runningcmake
(e.g.git commit -am "Changed X"
) aren't reflected in the header. -
Every time a build is started (e.g.
make
), write the commit ID to a header. The major drawback of this method is that any object file that includes the new header will be recompiled -- even if the state of the git repo hasn't changed.
We check Git every time a build is started (e.g. make
) to see if anything has changed,
like a new commit to the current branch. If nothing has changed, then we don't
touch anything- no recompiling or linking is triggered. If something has changed, then we
reconfigure the header and CMake rebuilds any downstream dependencies.