25

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

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

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

但这不会停止 make ifcollect_sources.py以状态码 1 退出。这也捕获了标准输出,collect_sources.py但不会将其打印出来,所以我觉得我看错了方向。

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

有什么建议吗?

4

5 回答 5

7

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

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

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

编辑:要使其与默认的 Windows shell(可能还有任何像样的 shell)一起工作,您可以编写your_command && echo ok而不是ifshell函数内编写。我认为这对于(旧的)DOS shell 是不可能的。对于这些,您可能想要调整your_command或编写一个包装脚本来打印错误(或成功)的内容。

于 2008-10-22T12:58:42.337 回答
4

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

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

include BuildRules.mk

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

于 2008-10-22T18:22:46.100 回答
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 会认为您正在尝试调用命令并抱怨它。

于 2008-10-23T16:35:36.487 回答
0

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

.PHONY: BuildRules.mk

BuildRules.mk: collect_sources.py
        echo Generating build rules...)
        python $< >$@
        $(MAKE) -f BuildRules.mk
于 2018-04-22T08:09:41.867 回答
-1

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

于 2008-10-22T18:35:02.877 回答