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

问题描述 投票:0回答:6

我有一个 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 时,该解决方案甚至应该可以工作。

有什么建议吗?

shell makefile
6个回答
8
投票

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

$(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
或编写一个包装脚本来打印错误(或成功)的内容。


4
投票

好的,这是我自己的解决方案,不幸的是,它不是基于collect_sources.py脚本的状态代码,但它对我有用(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 会认为您正在尝试调用命令并对此进行抱怨。


4
投票

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

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

include BuildRules.mk

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


0
投票

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

.PHONY: BuildRules.mk

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

0
投票

基于@MadScientist 对原始问题的评论:

如果您有 GNU make 4.2 或更高版本,您可以检查 $(.SHELL_STATUS) 变量将包含最后一个 $(shell ...) 的退出状态 功能评估

...并且还利用新的

intcmp
条件函数 ...

...您可能想定义这个宏:

.SHELLSTATUS_CHECK=$(intcmp ${.SHELLSTATUS},0,,,$(error .SHELLSTATUS_CHECK FAILED with .SHELLSTATUS=$(.SHELLSTATUS)))

...并将其注入到您的代码中,如下所示:

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

-1
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.