2014-09-23 66 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