Как включить git commit-number в исполняемый файл С++?

Я использую git в качестве трекера для моего проекта С++.

иногда мне нужно повторить вычисление, и я хотел бы знать, какую версию программы я использовал.

что было бы хорошим способом поставить # коммита в основной исполняемый файл? другими словами. я хотел бы, чтобы программа сообщила мне # текущего коммита во вводном сообщении, когда я запускаю программу.

В один прекрасный момент я могу подумать о том, чтобы сделать программу c + + "обед" git log "из оболочки и извлечь коммит #, но я не уверен, как это сделать во время make.

(я использую linux)

Ответ 1

Вероятно, самый простой способ сделать это - добавить в ваш makefile правило для генерации файла .c с текущим идентификатором фиксации git:

gitversion.c: .git/HEAD .git/index
    echo "const char *gitversion = \"$(shell git rev-parse HEAD)\";" > [email protected]

Теперь просто добавьте gitversion.c к вашему процессу сборки как обычно. Обязательно удалите его на make clean и добавьте его в .gitignore, чтобы он не был добавлен в репозиторий git случайно. Добавьте extern const char *gitversion; в заголовок где-нибудь, и вы можете получить к нему доступ таким образом.

Ответ 2

Я делаю следующее в 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)

Итак, вывод git rev-parse --short HEAD хорош для сборки в двоичном формате.

Ответ 3

Я использую git describe, чтобы получить версию, которая либо использует тег, либо номер фиксации. Обычно это дает хорошие версии, такие как: v0.1-1-g787c667, если кончик ветки имеет дополнительные коммиты над тегом 'v0.1'.

Команда git, которую я использую: git describe --tags --always. Обычно я использую его с системой сборки SCons и определяю ее как константу, соответствующие части 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 (....)

В программе C или С++ я могу теперь получить доступ к GIT_DESC как константу строки:

# include <iostream>

using namespace std;

int main (int argc, char ** argv) {
  cout << "Version: " << GIT_DESC << endl;
  return 42;
}

Примечание: аргумент --abbrev=N для git describe может быть полезен для обеспечения согласованного вывода версии независимо от конфигурации git пользователей.