我在一个大型项目中工作,在那里我们有几个子目录,我们从这些子目录中构建库/档案。大多数子目录不具有相互依赖的关系,但也有一些子目录相互依赖。
例如,这是一般的形式:
TARG1=targ1/
TARG2=targ2/
TARG3=targ3/
SUBDIRS= lib1\
lib2\
lib3\
...
.PHONY: $(TARG1) $(TARG2) $(TARG3)
构建顺序必须如下: TARG1 -> TARG1 2 -> 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无法充分利用并行化,因为它必须在进入下一个子目录之前完成每个子目录。
也许我的假设是错误的,因此我问这个问题,如何最好地组织目标,以允许最佳并行化?作为一个侧面的问题,如何组织目标,以避免代码重复?
发布于 2015-03-21 05:53:07
你不必重复食谱,如果它们都一样的话。如果您不想的话,不需要同时定义菜谱和先决条件。您可以将第一个示例重写为:
build_libs:
$(MAKE) subdirs
$(SUBDIRS) $(TARG1) $(TARG2) $(TARG3):
$(MAKE) -C $@
subdirs: $(SUBDIRS)
$(SUBDIRS): $(TARG3)
$(TARG3): $(TARG2)
$(TARG2): $(TARG1)
我真的不知道为什么要使用build_libs
递归;为什么不只使用build_libs: subdirs
https://stackoverflow.com/questions/29183454
复制相似问题