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

Makefile执行顺序异常:rm -rf未及时完成引发报错?

问题修复方案

问题根源

Makefile的执行分为解析阶段和命令执行阶段:

  • 解析阶段会先处理所有变量、函数(包括$(eval)、$(call))的展开
  • 命令执行阶段才会依次运行目标下的shell命令

你遇到的问题就是$(eval $(call get_sha1...))在解析阶段就已经执行,而mkdir是在后续的命令阶段才创建目录,导致获取SHA1时目录还不存在。

修复方法

方法1:将SHA1获取逻辑移到命令执行阶段(推荐)

把获取SHA1的操作放到目标的shell命令序列中,利用shell的顺序执行特性,确保目录创建、克隆完成后再获取SHA1:

do_the_work:
	mkdir -p out/my_work_dir
	git clone <仓库地址> out/my_work_dir
	# 直接在shell中获取SHA1并传递给后续操作
	SHA1=$$(git -C out/my_work_dir rev-parse HEAD) && \
	echo "当前仓库SHA1: $$SHA1" && \
	# 这里写依赖SHA1的后续操作,比如:
	# cp some_file out/my_work_dir/$$SHA1.file

方法2:用前置目标确保目录就绪后再执行SHA1获取

通过创建一个标记文件作为前置依赖,确保目录创建和克隆完成后,再执行SHA1获取逻辑:

# 定义获取SHA1的函数(仅在命令阶段调用)
define get_sha1
	SHA1=$(shell git -C $(1) rev-parse HEAD)
	export SHA1
endef

do_the_work: out/my_work_dir/.cloned
	# 此时目录已存在,安全调用get_sha1
	$(call get_sha1, out/my_work_dir)
	@echo "SHA1: $(SHA1)"
	# 后续依赖SHA1的操作

# 前置目标:确保目录创建和克隆完成
out/my_work_dir/.cloned:
	mkdir -p out/my_work_dir
	git clone <仓库地址> out/my_work_dir
	# 创建标记文件,避免重复克隆
	touch $@

关键注意事项

  • 避免在解析阶段执行依赖文件系统状态的操作(比如访问还未创建的目录)
  • 如果必须使用Makefile函数获取SHA1,一定要确保操作依赖的前置目标已经完成
  • 用$$表示shell中的变量,避免被Makefile提前解析

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 04:55:24