c++ - 如何在编译时确定 git 存储库的状态?

标签 c++ git

我正在开发一个用 C++ 编写并由 git 管理的模拟系统。我使用 GNU make 作为构建工具。要使模拟结果可重现,git 非常有用,因为您可以返回到创建结果所使用的模拟程序的确切版本。

目前,git 存储库的状态和 SHA1 是在运行时以编程方式确定的,并与结果一起写入文件。但是,如果自程序编译以来源已更改,我的日志文件中的状态将不会反射(reflect)程序的实际版本。因此,我正在寻找一种在编译时 确定 git 状态的方法。有机会实现吗?

最佳答案

一种解决方案是让您的构建系统提取该值,并让它生成一些包含该值的 C++ header (或源文件)。

例如,如果使用 CMake,您可以使用 FindGit模块做类似的事情:

project(...)

# load module.
find_package(Git)

# create "${GIT_HEAD_HASH}" variable that contains
# the SHA-1 of the current tree.  This assumes that the
# root CMakeLists is in the root of the Git repository.
git_tree_info(${CMAKE_SOURCE_DIR} GIT_HEAD)

# generate a 'version.h' file based on the 'version.h.in'
# file.  replace all @...@ strings with variables in the
# current scope.
configure_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/version.h.in
    ${CMAKE_CURRENT_SOURCE_DIR}/version.h
    @ONLY
)

然后,添加以下version.h.in 文件:

#ifndef _version_h__
#define _version_h__

static const char VERSION[] = "@GIT_HEAD_HASH@";

#endif

CMake 将用 get_tree_info() 提取的值替换 @GIT_HEAD_HASH@ 字符串。

然后,从您的常规代码:

#include "version.h"
#include <cstdlib>
#include <cstring>
#include <iostream>

int main(int argc, char ** argv)
{
    if ((argc == 2) && (std::strcmp(argv[1],"--version") == 0))
    {
        std::cerr
            << VERSION
            << std::endl;
        return (EXIT_FAILURE);
    }

    // ...
}

这是一个简化且绝对未经测试的示例。如果您查看 FindGit CMake 模块的源代码,您会发现它只是在构建时运行一个 execute_process() 命令来提取信息。您可以修改它以根据 Git 命令行界面的调用提取任何内容。

关于c++ - 如何在编译时确定 git 存储库的状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9207741/

相关文章:

git - 是否可以跳过暂存区并(也)将未跟踪的新文件提交给 git?

java - 你如何在 Windows 上 merge GIT?

c++ - 在 C++ Ubuntu 中安装 FTP 客户端(库)

c++ - 获取 GDB 便利变量中保存的值的符号信息

C++ Templates 多态障碍

c++ - 在 Qt 5.x 中使用 GLEW

git-commit - GIT 暂存并仅提交具有特定文件结尾的文件

ios - 创建后将 Git Repository 添加到 XCode 项目

windows - 将 git 描述设置为 shell 变量

c++ - 打印 cvMat channel