如何在macOS/FreeBSD上编译运行2005年发布的首个Git版本
Git首个版本于2005年正式发布,对应初始提交哈希为e83c5163316f89bfbde7d9ab23ca2e25604af290。该版本源码文件总量极少,理论编译可行性高,以下整理了实际编译过程中的踩坑记录与可直接落地的分步操作方案,无需深厚C语言基础即可完成编译。
前期编译尝试与报错记录
尝试1:macOS Big Sur环境
操作步骤:
- 修改
Makefile文件,将install $(PROG) $(HOME)/bin/替换为install $(PROG) ./bin/,将编译生成的二进制文件存放在本地目录 - 在
cache.h文件中添加#include <string.h>与#include <unistd.h>两行头文件引入代码 - 执行
brew install openssl安装openssl依赖 - 执行
ln -s ../opt/openssl/include/openssl .创建软链接 - 执行
make install执行编译安装流程
运行结果:编译失败,出现大量错误与警告,典型报错包括"no member named 'st_ctim' in 'struct stat'"、"no member named 'st_mtim' in 'struct stat'"。
尝试2:FreeBSD 12环境
操作步骤:
- 修改
Makefile文件,将install $(PROG) $(HOME)/bin/替换为install $(PROG) ./bin/,将二进制文件输出到本地目录 - 在
cache.h文件中添加#include <string.h>与#include <unistd.h>两行头文件引入代码 - 执行
make install执行编译安装流程
运行结果:出现链接器错误,错误日志如下:
/usr/local/bin/ld: read-cache.o:cache.h:64: multiple definition of `sha1_file_directory'; update-cache.o:cache.h:64: first defined here /usr/local/bin/ld: read-cache.o:cache.h:65: multiple definition of `active_cache'; update-cache.o:cache.h:65: first defined here /usr/local/bin/ld: read-cache.o:cache.h:66: multiple definition of `active_nr'; update-cache.o:cache.h:66: first defined here /usr/local/bin/ld: read-cache.o:cache.h:66: multiple definition of `active_alloc'; update-cache.o:cache.h:66: first defined here /usr/local/bin/ld: update-cache.o: undefined reference to symbol 'SHA1_Init@@OPENSSL_1_1_0' /usr/local/bin/ld: /lib/libcrypto.so.111: error adding symbols: DSO missing from command line collect2: error: ld returned 1 exit status *** Error code 1
分步编译操作(macOS优先支持)
编译失败的核心原因共三点:一是macOS系统struct stat的时间字段命名与2005年Linux环境的命名规则不兼容;二是头文件中直接定义全局变量,导致多目标文件链接时出现重复定义错误;三是链接阶段未正确引入OpenSSL的crypto链接库。按以下步骤操作即可解决所有问题:
1. 环境准备与依赖安装
- 拉取对应提交版本的Git源码,切换到目标提交节点
- macOS环境执行
brew install openssl安装OpenSSL依赖;FreeBSD环境执行pkg install openssl安装对应依赖 - 进入源码根目录,执行
mkdir -p bin创建本地二进制存放目录
2. 源码兼容性修正
修正全局变量重复定义问题
打开cache.h文件,找到第64-66行的全局变量定义代码块:
char *sha1_file_directory; struct cache_entry **active_cache; unsigned int active_nr, active_alloc;
为三行代码前添加extern关键字,将定义改为声明:
extern char *sha1_file_directory; extern struct cache_entry **active_cache; extern unsigned int active_nr, active_alloc;
随后打开read-cache.c文件,在头部头文件引入区域的下方,添加上述三个全局变量的实际定义(即不带extern的原始三行代码)。
修正macOS系统stat结构兼容问题
本步骤仅macOS环境需要操作,FreeBSD环境可跳过
打开cache.h文件,在之前添加的#include <unistd.h>行下方,添加两行兼容宏定义:
#define st_ctim st_ctimespec #define st_mtim st_mtimespec
补全缺失头文件
确认cache.h中已经引入<string.h>和<unistd.h>头文件,若缺失直接补充即可。
3. Makefile配置修改
- 调整安装路径:确认
install $(PROG) $(HOME)/bin/已替换为install $(PROG) ./bin/ - 补充链接库:找到
LIBS=配置行,在末尾追加-lcrypto参数,确保链接阶段可找到OpenSSL的加密库 - macOS环境额外配置:在
CFLAGS变量末尾追加-I$(brew --prefix openssl)/include,在LDFLAGS变量末尾追加-L$(brew --prefix openssl)/lib,无需手动创建OpenSSL头文件软链接
4. 执行编译
- 先执行
make clean清理之前编译产生的中间目标文件 - 执行
make install启动编译流程,无报错的情况下,所有编译生成的初版Git二进制文件会存放在当前目录的bin文件夹下,可直接运行测试功能。
内容的提问来源于stack exchange,提问作者Michael

