Parallel Make - 多次调用子项目

时间:2016-10-26 09:59:50

标签: makefile parallel-processing gnu-make multiple-makefiles

问题已在文件级别得到解答。但是我有一个更大的项目,它有很多项目间依赖项(由动态生成的DBus头文件引起)。

我创建了以下示例example files as ZIP - 真正的项目要复杂得多。)

顶级Makefile如下:

sub-%:
    $(MAKE) -C $(patsubst sub-%,%,$@)

default:
    $(MAKE) -j12 sub-p1 sub-p2 sub-p3

子项目的Makefile看起来像这样(p1p2p3):

all: p1

../lib/lib.a:
    $(MAKE) -C ../lib lib.a

p1: ../lib/lib.a
    cp -f ../lib/lib.a p1

lib的Makefile看起来像这样:

lib.a:
    sleep 2
    date > $@
    echo Done with building $@

问题:这个库是为每个p* - 项目并行创建的 - 在这个例子中它不是问题,但在我们的例子中它会导致无法解决的问题

当我在顶层调用make时,我得到以下输出:

$ make
make -j12 sub-p1 sub-p2 sub-p3
make[1]: Entering directory '/home/kkr/tmp/parallelmake'
make -C p1
make -C p2
make -C p3
make[2]: Entering directory '/home/kkr/tmp/parallelmake/p1'
make -C ../lib lib.a
make[2]: Entering directory '/home/kkr/tmp/parallelmake/p2'
make -C ../lib lib.a
make[2]: Entering directory '/home/kkr/tmp/parallelmake/p3'
make -C ../lib lib.a
make[3]: Entering directory '/home/kkr/tmp/parallelmake/lib'
make[3]: Entering directory '/home/kkr/tmp/parallelmake/lib'
make[3]: Entering directory '/home/kkr/tmp/parallelmake/lib'
sleep 2
sleep 2
sleep 2
date > lib.a
date > lib.a
date > lib.a
make[3]: Leaving directory '/home/kkr/tmp/parallelmake/lib'
make[3]: Leaving directory '/home/kkr/tmp/parallelmake/lib'
make[3]: Leaving directory '/home/kkr/tmp/parallelmake/lib'
cp -f ../lib/lib.a p3
cp -f ../lib/lib.a p1
cp -f ../lib/lib.a p2
make[2]: Leaving directory '/home/kkr/tmp/parallelmake/p3'
make[2]: Leaving directory '/home/kkr/tmp/parallelmake/p1'
make[2]: Leaving directory '/home/kkr/tmp/parallelmake/p2'
make[1]: Leaving directory '/home/kkr/tmp/parallelmake'

问题:是否可以以某种方式自动同步子项目?

由于real project有13个子项目 - 其中大多数具有项目间依赖性 - 因此手动同步将非常困难。

1 个答案:

答案 0 :(得分:0)

递归make系统显然无法“自动”同步它;它们是完全独立的过程,无法告诉对方他们正在运行给定的目标。

你有两个选择。第一个是最好但可能需要做很多工作的,就是重新构建你的构建系统,这样它就不是递归的。如果你有一个make调用来构建整个系统,那么只有一个make实例,它将全局协调所有目标的创建。您根本不需要$(MAKE) -C ../lib lib.a规则。

如果这不可行,那么您需要重写顶级makefile,以便强制执行排序,以便您永远不会同时开始创建依赖于同一外部目标的两个目录。例如,不是上面显示的顶级makefile,而是这样写:

default: p1 p2 p3

p%: ; $(MAKE) -C $@

.PHONY: default p1 p2 p3

现在假设您要确保p1p2p3之前运行,因为您希望p1构建所有共享目标;然后你将这样的规则添加到顶级makefile:

p2 p3: p1

您可以根据需要添加其他订单。