我们的项目为每个多目录子制作使用具有以下类型规则的Makefile:
DIRS = lib audio conf parser control
all: $(DIRS)
@for DIR in $(DIRS); \
do \
( cd $$DIR; $(MAKE) $(MFLAGS) all; ) \
done
如果任何文件无法在其中一个leaf make中编译,则构建将停止在该目录中 - 但其余的make仍在继续。如何设置这些Makefile,以便任何级别的第一个错误都会停止整个make?
由于
答案 0 :(得分:1)
来自bash手册的for循环部分:
返回状态是最后一个命令的退出状态 执行。
因此,您无需捕获返回状态。如果任何子品牌失败,您需要配方失败:
DIRS = lib audio conf parser control
all: $(DIRS)
@for DIR in $(DIRS); do \
$(MAKE) -C $$DIR $(MFLAGS) all || exit 1; \
done
但是,为每个目录设置单独的配方会更好,而不是单个for循环:
DIRS = lib audio conf parser control
all: $(DIRS)
.PHONY: all $(DIRS)
$(DIRS):
$(MAKE) -C $@ $(MFLAGS) all
这样,如果子制作失败,则完整规则的配方会失败并停止。请注意.PHONY
特殊目标,在这种情况下需要它,因为您希望运行配方,即使该目录已存在。
此结构还有另一个优点:如果以并行模式运行make(make -j N
),它将同时启动多个子制作,而不是仅使用for循环制作一个子制作。反过来,每个子品牌将并行启动多个配方,最多可达N
个工作。在多处理器或多核架构上,加速因子可能非常重要。
但是,如果您的项目不是并行安全的,也就是说,如果您的目录处理顺序很重要并且未在makefile中正确定义,则此优势可能会成为一个缺点。如果您遇到这种情况,可以添加:
.NOTPARALLEL:
主makefile开头的特殊目标告诉make。但是明确定义目录间依赖关系会更好。如果你不知道怎么做,请问另一个问题。
答案 1 :(得分:0)
我在this question's answer中找到答案:我必须重写以捕获每个子制作的返回状态。