2

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

我创建了以下示例示例文件为 ZIP - 实际项目要复杂得多)。

顶层Makefile如下:

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

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

子项目的 Makefile 如下所示(p1,p2p3):

all: p1

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

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

并且 Makefilelib看起来像这样:

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 个子项目 - 其中大多数具有项目间依赖关系 - 手动同步将非常困难。

4

1 回答 1

0

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

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

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

default: p1 p2 p3

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

.PHONY: default p1 p2 p3

现在假设您要确保p1运行之前p2并且p3因为您要p1构建所有共享目标;然后你会在顶级 makefile 中添加这样的规则:

p2 p3: p1

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

于 2016-10-26T13:11:42.947 回答