Makefile 与shell';陷阱';用于在退出时简明标识构建失败的命令

Makefile 与shell';陷阱';用于在退出时简明标识构建失败的命令,makefile,gnu,gnu-make,Makefile,Gnu,Gnu Make,标准:Makefile是GNU Make Makefile-我对makepp、qmake、cmake等不感兴趣。它们都很好(特别是cmake),但这是为了工作,在工作中我们使用GNU Make。最佳解决方案是纯Makefile解决方案,而不是解析make的shell脚本 我也不想做“失败后继续”的解决方案——如果它坏了,它就坏了,需要修复 情况是这样的,我有一个makefile,它并行地构建了多个目录——如果其中一个失败,当然整个构建都会失败,但直到所有的运行都完成(或失败)。这意味着make实

标准:Makefile是GNU Make Makefile-我对makepp、qmake、cmake等不感兴趣。它们都很好(特别是cmake),但这是为了工作,在工作中我们使用GNU Make。最佳解决方案是纯Makefile解决方案,而不是解析make的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“通过”>.result | | echo“失败”>.result,但make仍然需要某种陷阱或u onexit()清除命令,以便在退出时在它们处打印

任何Makefile忍者都有一个纯粹的Makefile解决方案吗


取消编辑-我的解决方案实际上没有按我希望的方式工作。。受阻

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

all : subdirs

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

subdirs-recursive: $(SUBDIRS)

当您希望make在第一次失败时中止,立即结束并终止所有正在运行的作业,而不是等待它们完成时,您需要像这样修补GNU make

然后,您需要为每个发出调用的shell设置一个陷阱(以及
set-opipefail
如果您使用管道),如本文所述

简言之:

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

“如果其中一个失败,当然整个构建都会失败,但直到所有的运行都完成(或失败)。”您可能可以通过预先设置
set-o pipefail来改善这种情况
$(SUBDIRS)
命令,这样失败的
$(MAKE)
的非零退出代码就不再被
sed
的成功退出所隐藏。如果
orange
失败,您希望它继续使用orange、banana等?@slowdog-MAKE的退出代码不一定是问题,但这是一个好的观点,+1代表you@Beta-因为它是一个make-j,它将同时构建多个目标-我希望构建失败,如果任何组件失败(并且它正确地做到了),它只是不清楚构建失败的原因。(因此需要一个“cleanup”命令。看起来我在某处看到的一些评论适用于这里:如果你想让
-j
选项正常工作,就必须处理依赖项链。我会尝试看看它在Linux内核makefiles中是如何完成的。+1尽管这是个好问题。