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 static library cmake_git_version_tracking
:
include(FetchContent)
FetchContent_Declare(cmake_git_version_tracking
GIT_REPOSITORY https://github.com/andrew-hardin/cmake-git-version-tracking.git
GIT_TAG 904dbda1336ba4b9a1415a68d5f203f576b696bb
)
FetchContent_MakeAvailable(cmake_git_version_tracking)
target_link_libraries(your_target
cmake_git_version_tracking
)
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.