递归make的并行执行

在稍微大一些的c/c++项目中, 如果想要一个比较好的项目结构, 很多功能实现以模块划分, 模块可以单独编译测试运行, 并且希望也可以从项目根目录进行整体编译, 那么不可避免的会希望涉及到递归make. 多个子模块往往没有太多依赖关系, 那么最好是其彼此可以并行编译, 以最大化节省编译时间.

非并行

subdirs:
    $(MAKE) -C foo
    $(MAKE) -C bar
    $(MAKE) -C baz

编译subdirs目标, 会依次进入foo, bar, 和baz子目录执行编译. 三个子目录的编译是按次序执行, 总耗时长.

并行

SUBDIRS = foo bar baz
.PHONY: subdirs $(SUBDIRS)
$(SUBDIRS):
    $(MAKE) -C $@
subdirs: $(SUBDIRS)

略微修改后, subdirs依赖于$(SUBDIRS)目标, 也就是foo, bar, 和baz. 依赖目标在无额外条件下, 皆是可以并行运行, 故可以被多线程优化以节省编译时间.

如果子目录之间存在部分相互依赖关系, 可以加入以下依赖,

foo: baz

References