2014-09-23 36 views
5

有没有一种方法可以测试编译多个作业(-jN,其中N> 1)时出现的缺失依赖关系?如何测试缺少依赖关系的Makefile?

我经常遇到包,主要是开源的,只要我使用-j1或-jN,其中构建过程工作正常,其中N是一个相对较低的值,如4或8,但如果我使用较高的值喜欢48 ,有点不寻常,它由于缺少依赖关系而开始失败。

我试图构建自己的bash脚本,给定目标,找出所有依赖关系,并尝试使用-j1显式构建每个这些依赖关系,以验证没有任何依赖关系缺失。它似乎可以使用小型/中型软件包,但对于uClibc等更重要的软件包却失败了。

我在这里分享我的脚本,因为有些人可能更好地理解我的意思是通过阅读代码。我也希望有一个更强大的解决方案存在并且可以共享回来。

#!/bin/bash 
TARGETS=$* 
echo "TARGETS=$TARGETS" 

for target in $TARGETS 
do 
    MAKE="make" 
    RULE=`make -j1 -n -p | grep "^$target:"` 
    if [ -z "$RULE" ]; then 
     continue 
    fi 

    NEWTARGETS=${RULE#* } 
    if [ -z "$NEWTARGETS" ]; then 
     continue 
    fi 

    if [ "${NEWTARGETS}" = "${RULE}" ]; then 
     # leaf target, we do not want to test. 
     continue 
    fi 

    echo "RULE=$RULE" 
# echo "NEWTARGETS=$NEWTARGETS" 
    $0 $NEWTARGETS 
    if [ $? -ne 0 ]; then 
     exit 1 
    fi 

    echo "Testing target $target" 
    make clean && make -j1 $target 
    if [ $? -ne 0 ]; then 
     echo "Make parallel will fail with target $target" 
     exit 1 
    fi 
done 
+2

我不知道确切的问题是什么......我不认为有一个为详尽比一个验证并行正确性什么更好的方法您已经描述过:为每个目标运行构建并验证它是否有效。不过,我不认为你必须限制构建到'-j1'。如果他们在'-j1'上失败,那么他们肯定会在更高的'-j'上失败,所以你不妨加快你的构建。 – MadScientist 2014-09-23 17:50:16

+0

这对大型项目有什么影响?它是否以实际的方式失败或仅仅是从运行时间/手动调用角度的困难? – 2014-09-23 17:59:50

+0

我认为迫使'-j1'口罩尽可能多的prereq问题,因为它迫使公开。假设prereq是按照列出的顺序构建的,那么任何'target:prereqA prereqB',其中'prereqA'依赖于'prereqB',而不会声明失败时使用'-j1',但可能使用'-jN'来传递。反转这些先决条件的顺序('prereqB prereqA')和'-j1'永远不会失败,但是'-jN'可能会(但是同样可能不会,你必须确定prereq顺序)。 – 2014-09-23 18:09:31

回答

1

我不知道任何开源解决方案,但是这正是问题ElectricAccelerator,GNU的高性能实现作,是为了解决。它将并行执行构建并动态检测并纠正缺失的依赖关系,以便构建输出与串行运行相同。它可以生成一个带注释的构建日志,其中包含有关缺失依赖关系的详细信息。例如,这个简单的生成文件具有abcdef之间未声明的依赖性:

all: abc def 

abc: 
     echo PASS > abc 

def: 
     cat abc 

与emake代替使用gmake运行该并启用--emake-annodetail=history,并将得到的注释文件包括这样的:

<job id="Jf42015c0" thread="f4bfeb40" start="5" end="6" type="rule" name="def" file="Makefile" line="6" neededby="Jf42015f8"> 
<command line="7"> 
<argv>cat abc</argv> 
<output>cat abc 
</output> 
<output src="prog">PASS 
</output> 
</command> 
<depList> 
<dep writejob="Jf4201588" file="/tmp/foo/abc"/> 
</depList> 
<timing invoked="0.356803" completed="0.362634" node="chester-1"/> 
</job> 

特别<depList>部分显示此作业Jf42015c0(换句话说,def)取决于作业Jf4201588,因为后者修改了文件/tmp/foo/abc。您可以免费试用ElectricAccelerator Huddle

(免责声明:我ElectricAccelerator可建筑师)

+0

是的,其次。我从多个大型企业软件环境的个人经验中了解ElectricAccelerator。就我而言,这是自切片面包以来最好的。免责声明:我不是员工或以任何方式隶属于ElectricCloud。 – 2014-10-02 03:57:12