how to include git commit-number into a c++ executable?

C++GitMakefile

C++ Problem Overview


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)

C++ Solutions


Solution 1 - C++

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.

Solution 2 - C++

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.

Solution 3 - C++

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.

Solution 4 - C++

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.)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionkirill_igumView Question on Stackoverflow
Solution 1 - C++bdonlanView Answer on Stackoverflow
Solution 2 - C++NasztaView Answer on Stackoverflow
Solution 3 - C++gautehView Answer on Stackoverflow
Solution 4 - C++Jack DeethView Answer on Stackoverflow