You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编译器自举场景下,如何在Makefile中声明不同Git提交的依赖?

问题描述

我正在自动化编译器从版本n到n+1的自举流程。这个编译器部分用自身编译的语言编写,所以它既是自身构建的依赖,修改源代码还会同时改变语言语法(进而影响源代码自身语法)和生成代码的语义——这两者在版本n升级到n+1时都可能变化。

我采用的自举方案是:

  • 基于已有的版本n编译器二进制文件(版本0为手动生成)
  • 编写版本n.5编译器:用版本n的语法/语义,但能解析版本n+1的语法,并遵循n+1的语义
  • 用版本n编译器编译n.5代码,得到n.5编译器
  • 编写版本n+1编译器:采用自身定义的语法与语义
  • 用n.5编译器编译n+1代码,得到最终的n+1编译器

为了避免n.5版本的隐性bug影响后续版本,我从版本n的Git提交创建两个独立分支:一个用于n.5,一个用于n+1,各自迭代后再合并得到n+1版本。

现在的问题是:如何让Make识别部分依赖来自当前提交之外的其他分支?具体来说,版本n+1的编译器依赖n.5的编译器,但n.5的源代码在另一个Git分支,这种跨分支依赖是否可行?

解决方案

完全可以实现跨Git分支的依赖管理,核心思路是把其他分支的源代码显式导出到本地独立目录,再让Make将其作为构建依赖。以下是具体实现方式:

1. 导出目标分支的源代码到独立目录

用git archive命令把n.5分支(或指定提交)的代码导出到专门的bootstrap目录,避免和当前分支代码冲突。比如:

git archive refs/heads/n.5 | tar -x -C ./bootstrap/n.5/

在Makefile中可以把这个导出动作定义为一个目标,确保只有当n.5分支的提交哈希变化时,才重新导出代码。

2. 在Makefile中声明跨分支依赖链

显式定义各个构建目标的依赖关系:n.5编译器依赖导出的n.5源代码和n版本编译器;n+1编译器依赖n.5编译器和当前分支的n+1源代码。

示例Makefile片段:

# 配置参数
N5_BRANCH := refs/heads/n.5
# 获取n.5分支的最新提交哈希
N5_COMMIT := $(shell git rev-parse $(N5_BRANCH))
# 存储n.5源代码的目录
N5_SOURCE_DIR := ./bootstrap/n.5
# 记录n.5提交哈希的文件,用于判断是否需要重新导出
N5_HASH_FILE := $(N5_SOURCE_DIR)/commit-hash
# n.5编译器的输出路径
N5_COMPILER := $(N5_SOURCE_DIR)/bin/compiler-n.5
# n+1编译器的输出路径
N1_COMPILER := ./bin/compiler-n+1
# 预先存在的n版本编译器
N_COMPILER := ./bin/compiler-n

# 导出n.5分支源代码的目标
$(N5_SOURCE_DIR): $(N5_HASH_FILE)
	git archive $(N5_COMMIT) | tar -x -C $(dir $@)
	echo $(N5_COMMIT) > $(N5_HASH_FILE)

# 生成哈希记录文件
$(N5_HASH_FILE):
	@mkdir -p $(dir $@)
	@echo $(N5_COMMIT) > $@

# 构建n.5编译器
$(N5_COMPILER): $(N5_SOURCE_DIR) $(N_COMPILER)
	cd $(N5_SOURCE_DIR) && $(N_COMPILER) build --output $@

# 构建n+1编译器
$(N1_COMPILER): $(N5_COMPILER) $(wildcard src/**/*)
	$(N5_COMPILER) build src --output $@

# 清理bootstrap目录的目标
.PHONY: clean-bootstrap
clean-bootstrap:
	rm -rf ./bootstrap

3. 用提交哈希确保依赖一致性

通过记录n.5分支的提交哈希,Make可以自动检测分支是否有更新:如果当前n.5分支的哈希和本地记录的不一致,就会重新导出源代码并重新构建n.5编译器,保证依赖的版本正确性。

4. 额外注意事项

  • 确保n版本编译器已经预先构建完成,或者在Makefile中添加从n版本源代码构建的步骤(如果需要)
  • 建议把bootstrap目录加入.gitignore,避免把导出的代码提交到仓库
  • 可以将n.5编译器的二进制文件缓存起来(比如放到项目的缓存目录或Git LFS),减少重复构建的时间

内容的提问来源于stack exchange,提问作者jthulhu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 15:17:00