代码之家  ›  专栏  ›  技术社区  ›  Carl Seleborg

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

  •  20
  • Carl Seleborg  · 技术社区  · 16 年前

    我有一个makefile,它在应用构建规则(这个工具为我编写)之前先运行一个工具。如果这个工具是一个python脚本,退出时带有一个非空的状态代码,那么我希望gnu make就停在那里,不要继续构建程序。

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

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

    但这并不意味着 collect_sources.py 退出,状态代码为1。这还捕获了 收集资源.py 但是没有打印出来,所以我觉得我找错了方向。

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

    有什么建议吗?

    5 回复  |  直到 6 年前
        1
  •  6
  •   mweerden    16 年前

    也许有更好的方法,但我尝试了以下方法,它是有效的:

    $(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是可能的。对于这些你可能想适应的 尤尔命令 或者编写包装脚本以在出错(或成功)时打印某些内容。

        2
  •  4
  •   Carl Seleborg    16 年前

    好的,这是我自己的解决方案,不幸的是,这不是基于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) 有效地使停车。

    请注意,在 ifeq ... endif 使用空格。如果使用了制表符,make会认为您正试图调用一个命令并抱怨它。

        3
  •  4
  •   JesperE    16 年前

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

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

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

        4
  •  0
  •   Alex Cohn    6 年前

    定影 https://stackoverflow.com/a/226974/192373

    %PHONY: BuildRules.mk
    
    BuildRules.mk: collect_sources.py
            echo Generating build rules...)
            python $< >$@
            $(MAKE) -f BuildRules.mk
    
        5
  •  -1
  •   JohnMcG    16 年前

    确保不使用-k选项调用make/gmake。