C++ 如何将git提交编号包含到c++;可执行文件?

C++ 如何将git提交编号包含到c++;可执行文件?,c++,git,makefile,C++,Git,Makefile,我使用git作为C++项目的版本跟踪器。 有时我需要重复计算,我想知道我使用的是哪个版本的程序 在主可执行文件中放入一个提交文件的好方法是什么?换句话说。我希望程序在运行程序时在介绍性消息中告诉我当前提交的# 我可以想到的是,让C++程序从shell中提取“Git日志”,并提取Sturny*,但我不知道如何在Sub中进行。 (我使用linux)最简单的方法可能是在makefile中添加一条规则,以生成一个具有当前git提交ID的.c文件: gitversion.c: .git/HEAD .git

我使用git作为C++项目的版本跟踪器。 有时我需要重复计算,我想知道我使用的是哪个版本的程序

在主可执行文件中放入一个提交文件的好方法是什么?换句话说。我希望程序在运行程序时在介绍性消息中告诉我当前提交的#

我可以想到的是,让C++程序从shell中提取“Git日志”,并提取Sturny*,但我不知道如何在Sub中进行。


(我使用linux)

最简单的方法可能是在makefile中添加一条规则,以生成一个具有当前git提交ID的.c文件:

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

现在只需像往常一样将
gitversion.c
添加到构建过程中。确保在
makeclean
上删除它,并将其添加到
.gitignore
,这样它就不会意外添加到git存储库中。添加一个
extern const char*gitversion到某个标题,您可以这样访问它。

我在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
的输出适合在二进制文件中构建。

我使用
git descripe
获得一个使用标记或提交号的版本。如果分支的顶端在“v0.1”标记上方有额外的提交,则通常会提供类似于:
v0.1-1-g787c667
的好版本

我使用的git命令是:
git descripe--tags--always
。我通常将其与SCons构建系统一起使用,并将其定义为SConstruct的一个常量相关部分:

导入操作系统,系统 从子流程导入* def getGitDesc(): 返回Popen('git descripe--tags--always',stdout=PIPE,shell=True)。stdout.read().strip() GIT_DESC=getGitDesc() 打印“Building”+getGitDesc()+” env=环境() #建立环境 Append(cppfefines={'GIT\u DESC':('\\\%s\\''%GIT\u DESC)}) #建立你的程序 环境计划(……)
<>在C或C++程序中,我现在可以访问<代码> GITYDESC作为字符串常量:

#包括
使用名称空间std;
int main(int argc,字符**argv){

cout如果您使用的是Qt,请将其放入项目的.pro文件中:

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)\\"'
然后在您的代码中使用
GIT\u REVISION
,就像在其他答案中一样-它的行为类似于
const char*


(感谢Alexander Barthel,我从他那里窃取了这条信息。)

1)我对make或git不太熟悉。我尝试了快速搜索,但仍然无法理解该部分“.git/HEAD.git/index”。在
gitversion.c:
之后列出的文件是它所依赖的文件。
.git
是一个隐藏目录;
HEAD
是其中的一个文件。因此,当
.git/HEAD
.git/index
更改时,将使用下一行的命令重建
gitversion.c:
。是的;请注意,这还不完全完成;最好同时引用.git/packed refs和.git/refs下的所有文件……2)我想我误解了smtn。我的做法如下:1.将这两行放在main.o规则之后的Makefile中。2.包括“extern const char*gitversion”一行在main.cc.3.put中,您是否需要像引用任何其他.c文件一样从链接规则中实际引用gitversion.c。这种方法假设您为每次提交手动运行cmake。要使其正常工作,您需要定义如下内容:
#define GIT_REVISION“@kml2map_BUILD_VERSION@
kml2mapsVersion.h.in
中的
这篇文章“CMake:Use Git Branch&Commit Details in Project”更详细地解释了CMake机制:非常类似于手动将
-D
标志添加到编译器标志列表中更容易:
QMAKE\u cxflags+=-DGIT\u Commit=\”$(shell git descripe--abbrev=4--dirty--always--tags)\“