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

编写构建Docker镜像的Makefile报prerequisites cannot be defined in recipes错求助

错误原因
  • eval函数的作用是动态生成Make规则,这类规则定义逻辑必须放在Makefile的顶层解析阶段执行,不能放在任意目标的recipe(目标冒号后缩进的执行命令块)中。
  • Make运行时会先完成所有顶层规则、目标、依赖的解析,再执行选中目标的脚本命令。你现在把生成build_xxx规则的代码放在build目标的脚本段里,等于在命令执行阶段才尝试定义依赖关系,直接违反了Make的执行逻辑,因此触发报错。
修复方法

把动态生成规则的foreach逻辑从目标的recipe中移出,放在Makefile顶层,不需要缩进,也不归属任何目标。修正后的完整代码如下:

# 假设每个子目录都包含一个Dockerfile
IMAGES  := $(patsubst %/,%,$(dir $(wildcard */Dockerfile)))
BUILD_TARGS = $(patsubst %,build_%,$(IMAGES))
TEST_TARGS = $(patsubst %,test_%,$(IMAGES))
PUSH_TARGS = $(patsubst %,push_%,$(IMAGES))

VERSION := 1 # 可替换为 git 命令取版本号:$(shell git rev-parse --short=12 --verify HEAD)
DOCKER_REPO_URL := david.io/reponame

define docker_build =
build_$(1):
	@echo "Building $(1)"
	#docker build -t $(1) --force-rm $(1)
endef

define docker_test =
test_$(1):
	@echo "Testing $(1)"
	#docker inspect $(1)
	#docker run --rm $(1) help
endef

define docker_push =
push_$(1):
	@echo "Pushing $(1)"
	#docker tag $(1) $(DOCKER_REPO_URL):$(1)-$(VERSION)
	#docker push $(DOCKER_REPO_URL):$(1)-$(VERSION)
	#docker tag $(1) $(DOCKER_REPO_URL):$(1)
	#docker push $(DOCKER_REPO_URL):$(1)
endef

# 动态生成所有规则,放在顶层解析段
$(foreach image,$(IMAGES),$(eval $(call docker_build,$(image))))
$(foreach image,$(IMAGES),$(eval $(call docker_test,$(image))))
$(foreach image,$(IMAGES),$(eval $(call docker_push,$(image))))

.PHONY: all build test release clean $(IMAGES) $(BUILD_TARGS) $(TEST_TARGS) $(PUSH_TARGS)

all: build test release

build: $(BUILD_TARGS)

test: $(TEST_TARGS)

release: $(PUSH_TARGS)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 10:27:01