由于您没有提供任何有关您的规则的详细信息,因此我们无法回答这个问题。当 make 执行一个程序时,无论它是编译器、链接器、文档格式化程序还是其他 make 实例,它的工作方式都是一样的:如果退出代码是 0,在 UNIX 中是“成功” , 然后 make 继续下一条规则。如果退出代码不是0,这在 UNIX 中是“失败”,则停止(除非您使用了-k 选项)。
只有当它尝试构建的所有目标都成功时,make 程序本身才会以0 退出。
因此,如果编写正确,您的 make 将在子 make 失败时停止。如果没有,那么调用子 make 的规则将丢失退出代码,这就是父 make 不会失败的原因。如果您提供了您的规则,我们可以准确地告诉您如何解决它。
根据我的经验,我建议您可能有这样的规则来运行子制作:
SUBDIRS = foo bar biz
all:
for d in $(SUBDIRS); do $(MAKE) -C $$d; done
.PHONY: all
这里你没有检查每个子制作的退出代码,所以它不会停止。只有最后一个命令的最终退出代码从 shell 发送回 make。你应该像这样重写你的makefile(如果是这样的话):
SUBDIRS = foo bar biz
all: $(SUBDIRS)
$(SUBDIRS):
$(MAKE) -C $@
.PHONY: all $(SUBDIRS)
编辑
根据您的makefile 并阅读以上内容,您可以看到问题所在:脚本中的最后一个命令是popd,它不会失败,因此该命令的退出代码是成功。请注意,您不需要在此处使用pushd 和popd(至少在 UNIX 系统上不需要),因为每个命令都在单独的 shell 中运行,因此当 shell 退出时,工作目录会被重置。
你想要这样的东西:
all:
cd "${STA_DIR}" && ${MAKE} clean && ${MAKE} ARGS="${A1},${A2}"
&& 运算符是成功的短路测试;如果其中任何一个命令失败,则整个命令将立即失败。
还记得在调用递归make时始终使用$(MAKE)或${MAKE}(它们是相同的),不要使用静态make。