【问题标题】:How do you abort on shell command errors in makefiles?你如何中止 makefile 中的 shell 命令错误?
【发布时间】:2011-07-24 06:11:57
【问题描述】:

我正在尝试编写一个 makefile 来打包一些 PHP 脚本。我还希望它在构建最终 zip 文件之前检查语法错误(使用内置的 php lint 工具),以防止任何意外错误滑入。

目前为止

all: dist
clean:
    rm -f output.zip
dist: clean
    for i in `find . -name "*.php"`; do php -l $$i; done
    zip -r output.zip src -x "*/.*" "*/tests*"

这可行,但如果出现 PHP 错误,我希望它中断而不继续构建 zip 文件(原因很明显)。目前,它们可能只是迷失在成功运行 lint 的输出页面和 zip 文件中。

我这样做的方式是否正确?我应该使用 make 循环而不是 shell 循环吗?如何让 make 在 shell 命令错误时中止?

【问题讨论】:

    标签: php makefile


    【解决方案1】:

    你可以这样做:

    for i in `find . -name "*.php"`; do \
      php -l $$i; \
      if [ $$? -ne 0 ] ; then exit 42 ; fi \
    done
    

    【讨论】:

      【解决方案2】:

      dist 配方中的 shell for 循环对 make 隐藏了 php -l 的退出状态,因此它不知道退出。 Mat's answer 展示了如何通过在错误时退出 shell 命令来解决此问题。

      可以像这样完全避免 shell 循环:

      all: dist
      clean:
          rm -f output.zip
      LINT_TARGETS := $(addprefix lint-,$(shell find . -name "*.php"))
      .PHONY: $(LINT_TARGETS)
      $(LINT_TARGETS):lint-%:%
          php -l $<
      dist: clean $(LINT_TARGETS)
          zip -r output.zip src -x "*/.*" "*/tests*"
      

      现在有一个phony target 和一个static pattern rule 来运行每个php -l 命令。如果其中任何一个失败,dist 配方将不会运行。这可以说比 shell 循环更难阅读,但这意味着 a)来自 make 本身的错误消息会为您指出有问题的文件,并且 b)使用 make -j 您可以进行多线程 lint 检查 :-)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-18
        • 1970-01-01
        • 2019-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-14
        • 2019-08-05
        相关资源
        最近更新 更多