【问题标题】:How to handle the sub-make in GNU make errors?如何处理 GNU make 中的 sub-make 错误?
【发布时间】:2013-05-11 00:19:14
【问题描述】:

我在我的 Makefile(GNU) 中使用 sub-make。但是每当子制作失败时,主制作会在此之后继续成功运行。每当我的子制作失败时,我希望我的主 Makefile 失败。我怎么做?

all:   
    pushd ${STA_DIR};make clean;make ARGS=${A1},${A2};popd

只要 STA_DIR 中的 make 失败,主 make 就不会停止。我想停止主要制作。

【问题讨论】:

    标签: makefile gnu-make


    【解决方案1】:

    由于您没有提供任何有关您的规则的详细信息,因此我们无法回答这个问题。当 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,它不会失败,因此该命令的退出代码是成功。请注意,您不需要在此处使用pushdpopd(至少在 UNIX 系统上不需要),因为每个命令都在单独的 shell 中运行,因此当 shell 退出时,工作目录会被重置。

    你想要这样的东西:

    all:
            cd "${STA_DIR}" && ${MAKE} clean && ${MAKE} ARGS="${A1},${A2}"
    

    && 运算符是成功的短路测试;如果其中任何一个命令失败,则整个命令将立即失败。

    还记得在调用递归make时始终使用$(MAKE)${MAKE}(它们是相同的),不要使用静态make

    【讨论】:

    • 知道了。谢谢。我刚刚在我的 OP 中添加了我的实际 makefile 以供参考。
    • 优秀。我将对我的制作进行必要的更改。非常感谢!!
    • 递归调用使用${MAKE}make有什么区别?
    • gnu.org/software/make/manual/html_node/MAKE-Variable.html 实际上还有其他更好的理由。如果您想知道,请就此提出一个新问题:cmet 不适合回答无关主题的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    • 2015-05-09
    • 2017-06-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-08
    相关资源
    最近更新 更多