防止两个make实例执行相同的目标(并行make)

时间:2011-03-15 08:58:16

标签: makefile

我尝试在我们的构建服务器上进行并行make。我在这里遇到一个非常频繁的问题,即试图制造两个不同目标的两个实例,例如A和B,几乎同时尝试制作两者都需要的目标,比如C。

由于两个实例都试图在不同的实例中一起制作C,因此C make使其中任何一个失败,因为制作C需要在此处移动某些文件,并且其中一个实例最终移动或删除已创建的文件。

如果已经制作目标,是否有可用于阻止重新进入makefile的常用构造?

更新

好的,让我这样说吧:  我的申请要求A.lo和B.lo出席。这些A.lo和B.lo是与C.lo相关联的库。 因此规则看起来像

app.d:A.lo B.lo(其他人)

(做连结)

在其他一些目录中说A(将容纳A.lo):

A.lo:C.lo(其他.o s和.lo s)

(做连结)

在其他一些目录中说B(将容纳B.lo):

B.lo:C.lo(其他.o s和.lo s)

(做连结)

因此实际上在制作app.d制作叉子时,两个平行的制作目标A.lo和B.lo. 一旦进入目录A和B,就会独立地为目标C.lo关闭另外两个线程,并且有时这两个线程同时链接C.lo,这导致其中一个失败,出现一些奇怪的错误,如文件无法识别(因为它可能被其他链接器实例写入)

我该如何解决这个问题?如果没有C.lo链接它们,就不可能创建A.lo和B.lo.

2 个答案:

答案 0 :(得分:2)

这可能听起来有点,明显,但最简单的解决方案就是安排在C或{{1}之前明确构建A }。这样,当递归使BA运行时,B已经是最新的,并且都不会尝试构建它。

如果你的toplevel makefile看起来像这样:

C

您可以像这样扩展它:

all: buildA buildB
buildA:
    $(MAKE) -C A

buildB:
    $(MAKE) -C B

你没有详细介绍你的具体构建,所以可能这不仅仅是插入和工作,但希望你能得到这个想法。

答案 1 :(得分:1)

我使用“mkdir”技术解决了这个问题:

SHELL = /bin/bash

all: targetC targetD

targetC: targetA
............

targetD: targetB
............

targetA targetB: source
    -mkdir source.lock && ( $(command) < source ; rm -r source.lock )
    $(SHELL) -c "while [ -d source.lock ] ; do sleep 0.1 ; done"

但我很乐意看到更优雅的解决方案。