GNU Makefile相当于shell'TRAP'命令,用于在退出时简明地识别构建失败

时间:2011-06-20 19:11:13

标签: makefile gnu gnu-make

标准:Makefile是一个GNU Make Makefile - 我对makepp,qmake,cmake等不感兴趣。他们都很好(特别是cmake),但这是为了工作和工作,我们使用GNU Make。最佳解决方案是纯Makefile解决方案,而不是解析为您制作的shell脚本。

我也不想做一个'继续失败'的解决方案 - 如果它被打破了,它就会被打破,需要修复。

情况是这样的,我有一个并行构建多个目录的makefile - 如果其中一个失败,当然整个构建失败,但直到所有运行都运行完成(或失败)。这意味着make实际失败的原因被埋没在make的输出结束的任意位置。

以下是我所得到的一个例子:

all: $(SUBDIRS)

SUBDIRS = \
  apple \
  orange \
  banana \
  pineapple \
  lemon \
  watermelon \
  grapefruit

$(SUBDIRS):
  cd $@ && $(MAKE) $(MFLAGS) 2>&1 | sed -e "s/^/$(notdir $(@)): /g"

如果我运行'make -j 5'并且'orange'碰巧失败了 - 我想在最后看到这样的表 制作过程

  apple     - passed
  orange    - FAILED
  banana    - passed
  pineapple - passed
  lemon     - passed

我考虑过和&& echo“pass”> .result || echo“FAILED”> .result,但仍然需要某种TRAP或__onexit()清理命令在退出时打印它们。

任何Makefile ninjas都有一个pure-makefile解决方案吗?

取消编辑 - 我的解决方案实际上并没有按照我希望的方式工作.. STYMIED!

2 个答案:

答案 0 :(得分:3)

如果你想让make在第一次失败时中止,立即结束并杀死所有正在进行的作业而不是等待它们完成,你需要修补GNU Make这样 http://lists.gnu.org/archive/html/bug-make/2009-01/msg00035.html

然后你需要为调用的每个shell设置一个陷阱(如果使用管道,还需要设置set -o pipefail),如本文http://lists.gnu.org/archive/html/help-make/2009-02/msg00011.html中所述

简而言之:

target1:
    trap 'kill $$(jobs -p)'; command && something || something-else
target2:
    trap 'kill $$(jobs -p)'; set -o pipefail; command | sed '...'

答案 1 :(得分:0)

我看到的唯一方法是使用sub-make自我执行:

all : subdirs

subdirs : 
    $(MAKE) -f $(lastword $(MAKEFILE_LIST)) subdirs-recursive || cat log

subdirs-recursive: $(SUBDIRS)