如何使失败的$(shell)命令中断Make

时间:2008-10-22 12:29:04

标签: shell makefile

我有一个Makefile,它在应用构建规则之前运行工具开始(这个工具为我写的)。如果这个工具是一个python脚本,以非空状态代码退出,我希望GNU Make在那里停止,而不是继续构建程序。

目前,我这样做(顶级,即第1列):

$(info Generating build rules...)
$(shell python collect_sources.py)
include BuildRules.mk

但如果collect_sources.py以状态代码1退出,则不会停止make。这也会捕获collect_sources.py的标准输出,但不打印出来,所以我感觉我是朝错误的方向看。

如果可能的话,当一个简单的MS-DOS shell是标准系统shell时,该解决方案甚至可以工作。

有什么建议吗?

5 个答案:

答案 0 :(得分:6)

可能有更好的方法,但我尝试了以下内容并且有效:

$(if $(shell if your_command; then echo ok; fi), , $(error your_command failed))

在这里,我假设your_command没有给出任何输出,但在这种情况下解决起来应该不难。

编辑:为了使其能够使用默认的Windows shell(可能是任何体面的shell),您可以在your_command && echo ok函数中编写if而不是shell。我不认为这对于(较旧的)DOS shell是可能的。对于这些,你可能想要调整your_command或编写一个包装脚本来打印错误(或成功)的东西。

答案 1 :(得分:4)

您应该使用常规目标来创建BuildRules.mk:

BuildRules.mk: collect_sources.py
        python $< >$@

include BuildRules.mk

这是自动生成依赖项时使用的标准技巧。

答案 2 :(得分:4)

好的,这是我自己的解决方案,遗憾的是,它不是基于collect_sources.py脚本的状态代码,而是基于Works For Me(TM)并让我看到脚本产生的任何输出:

SHELL_OUTPUT := $(shell python collect_sources.py 2>&1)
ifeq ($(filter error: [Errno %],$(SHELL_OUTPUT)),)
  $(info $(SHELL_OUTPUT))
else
  $(error $(SHELL_OUTPUT))
endif

编写脚本,以便任何错误产生以"collect_sources: error:"开头的输出。此外,如果python无法找到或执行给定的脚本,它会输出包含消息"[Errno 2]"或类似信息的错误消息。所以这段小代码只捕获输出(将stderr重定向到stdout)并搜索错误消息。如果没有找到,则只使用$(info)打印输出,否则使用$(error),这有效地使Make停止。

请注意ifeq ... endif中的缩进是用空格完成的。如果使用了标签,Make会认为您正在尝试调用命令并抱怨它。

答案 3 :(得分:0)

修复https://stackoverflow.com/a/226974/192373

.PHONY: BuildRules.mk

BuildRules.mk: collect_sources.py
        echo Generating build rules...)
        python $< >$@
        $(MAKE) -f BuildRules.mk

答案 4 :(得分:-1)

确保您没有使用-k选项调用make / gmake。