how to include git commit-number into a c++ executable?
i use git as a version tracker for my c++ project.
sometimes i need to repeat a calculation and i would like to know which version of the program i used.
what would be a good way to put a # of the commit into the main executable? in other words. i'd like the program to tell me the # of the current commit in an introductory message as i run the program.
one way i can think of is to make the c++ program lunch "git log" from shell and extract the commit # but i'm not sure how to do it during make.
(I use linux)
Probably the easiest way to do this would be to add to your makefile a rule to generate a .c file with the current git commit ID:
gitversion.c: .git/HEAD .git/index
echo "const char *gitversion = \"$(shell git rev-parse HEAD)\";" > $@
Now simply add gitversion.c
to your build process as normal. Make sure to remove it on make clean
, and add it to .gitignore
so it's not added to the git repository accidentally. Add an extern const char *gitversion;
to a header somewhere, and you can access it like that.
I do the following in CMakeLists.txt:
IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
FIND_PACKAGE(Git)
IF(GIT_FOUND)
EXECUTE_PROCESS(
COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE "kml2maps_BUILD_VERSION"
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
MESSAGE( STATUS "Git version: ${kml2maps_BUILD_VERSION}" )
ELSE(GIT_FOUND)
SET(kml2maps_BUILD_VERSION 0)
ENDIF(GIT_FOUND)
ENDIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/kml2mapsVersion.h.in ${CMAKE_CURRENT_BINARY_DIR}/kml2mapsVersion.h @ONLY)
So the git rev-parse --short HEAD
's output is good to build in the binary.
I use git describe
to get a version which either uses a tag or commit number. This usually gives nice versions like: v0.1-1-g787c667
if the tip of the branch has additional commits above the 'v0.1' tag.
The git command I use is: git describe --tags --always
. I usually use it with the SCons build system and define it as a constant, relevant parts of the SConstruct:
import os, sys
from subprocess import *
def getGitDesc():
return Popen('git describe --tags --always', stdout=PIPE, shell=True).stdout.read ().strip ()
GIT_DESC = getGitDesc ()
print "Building " + getGitDesc () + ".."
env = Environment ()
# set up environment
env.Append (CPPDEFINES = { 'GIT_DESC' : ('\\"%s\\"' % GIT_DESC) } )
# build your program
env.Program (....)
In the C or C++ program I can now access GIT_DESC
as a string-constant:
# include <iostream>
using namespace std;
int main (int argc, char ** argv) {
cout << "Version: " << GIT_DESC << endl;
return 42;
}
note: the --abbrev=N
argument to git describe
might be useful to achieve consistent version output independent of a users git configuration.
If you're using Qt, put this in your project's .pro file:
win32:DEFINES += GIT_BIN='C:\\Git\\bin\\git'
# or 'C:\\Progra~1\\Git\\bin\\git' - ymmv with putting spaces in here
win32:DEFINES += GIT_REVISION='\\"$$system($${GIT_BIN} rev-parse --short HEAD)\\"'
unix:DEFINES += GIT_REVISION='\\"$$system(git rev-parse --short HEAD)\\"'
Then use GIT_REVISION
in your code as in the other answers - it behaves as const char *
.
(Thanks to Alexander Barthel, who I plundered this tip from.)