【发布时间】:2015-03-21 13:48:38
【问题描述】:
我在一个大型项目中工作,我们有几个子目录可以从中构建库/存档。大多数子目录之间没有相互依赖关系,但有些子目录有。
例如,这是一般形式:
TARG1=targ1/
TARG2=targ2/
TARG3=targ3/
SUBDIRS= lib1\
lib2\
lib3\
...
.PHONY: $(TARG1) $(TARG2) $(TARG3)
构建顺序必须如下:TARG1 -> TARG2-> TARG3 -> SUBDIRS
我们的目标结构如下:
build_libs:
$(MAKE) subdirs
subdirs: $(SUBDIRS)
$(SUBDIRS): $(TARG3)
$(MAKE) -C $@
$(TARG3): $(TARG2)
$(MAKE) -C $@
$(TARG2): $(TARG1)
$(MAKE) -C $@
$(TARG1):
$(MAKE) -C $@
现在,正如我所见,这将允许最大程度的并行化,因为在构建目标 (TARG1 -> TARG3) 时,Make 可以同时构建 SUBDIRS 中的所有库。但也许有更好的方法来优化它?我看到,这种方法的缺点是我们得到了一个更大的 Makefile,因为我们必须为每个与另一个目标有依赖关系的目标指定一个配方。有什么方法可以避免这种情况并仍然允许完全并行化?
另一种方法是像这样构建目标:
SUBDIRS = targ1 targ2 targ3 lib1 lib2 lib3
subdirs:
for dir in $(SUBDIRS); do \
$(MAKE) -C $$dir; \
done
现在这种方法的好处是,只需按照正确的顺序编写目标,就可以轻松指定依赖关系。但是 Make 无法充分利用并行化,因为它必须先完成每个子目录,然后才能继续下一个。
也许我的假设是错误的,所以我问这个问题如何最好地组织目标以实现最佳并行化?作为一个附带问题,如何组织目标以避免代码重复?
【问题讨论】:
标签: makefile gnu-parallel