给定一个Makefile,该Makefile通常使用并行构建的-j
标志运行。我希望它以结果消息终止。我希望这条消息说明构建是否失败,如果失败,错误是什么。如果构建成功(尽管可以(,它不必说什么,但它必须在目标构建失败时警告用户以及原因。
此行为在顺序生成期间已存在,但在并行生成期间不存在。并行生成交织输出,并且通常会忽略错误消息,因为其他目标的输出可能会将失败目标的错误推离屏幕。粗心的开发人员可能会在他/她的屏幕上看到任何错误,并假设构建成功。
这是一个非常直观的功能,我已经搜索了答案,但似乎没有任何直接的解决方案。有什么想法吗?
你基本上运行
make -j 8 2> >(tee /tmp/error.log)
test $? -ne 0 && echo "build errors:"
cat /tmp/error.log
构建完成后,您将获得所有 stderr。
--编辑 --
更新以使用 tee,以输出到标准输出并输出到文件中:
如果其中一个配方失败,则返回非零值,因此您可以从命令行执行以下操作(假设 bash shell(:
make 2>&1 | tee build.log
[ ${PIPESTATUS}[0] -eq 0 ] || ( echo "MAKE FAILED!"; grep --color build.log "Error:" )
${PIPESTATUS}[0]
为您提供第一个命令的退出代码(make 2>&1
(,而不是整个命令的退出状态(如果制作失败,退出状态将为tee
(。 它是特定于 bash 的,因此例如它不适用于zsh
。
或者,您可以添加与递归构建的顶级目标相同的逻辑。
ifndef IN_RECURSION
export IN_RECURSION:=1
$(info At top level -- defining default target)
_default:
@echo "doing recursive call of make"
@$(MAKE) $(MAKECMDGOALS) IN_RECURSION=1 2>&1 | tee build.log;
[ ${PIPESTATUS}[0] -eq 0 ] || ( echo "MAKE FAILED!"; grep --color "Error:" build.log )
.PHONY: _default
endif
all:
....
请注意,在这种情况下,用于连接两个配方行的至关重要,因为第二个命令必须在与第一个命令相同的 shell 实例中运行。