2014-09-23 7 views
5

Gibt es eine Möglichkeit, fehlende Abhängigkeiten zu testen, die beim Kompilieren eines Projekts mit mehreren Jobs angezeigt werden (-jN mit N> 1)?Wie testet man ein Makefile auf fehlende Abhängigkeiten?

Ich stoße oft auf Pakete, meistens Open Source, wo der Build-Prozess gut funktioniert, solange ich -j1 oder -jN benutze, wobei N einen relativ niedrigen Wert wie 4 oder 8 hat, aber wenn ich höhere Werte wie 48 verwende , ein wenig ungewöhnlich, beginnt es aufgrund fehlender Abhängigkeiten zu scheitern.

Ich habe versucht, mir ein Bash-Skript zu erstellen, das bei gegebenem Ziel alle Abhängigkeiten herausfinden und versuchen würde, jede dieser Abhängigkeiten explizit mit -j1 zu erstellen, um zu bestätigen, dass keine Abhängigkeiten von ihnen selbst fehlen. Es scheint, mit kleinem/mittlerem Paket zu arbeiten, aber scheitert an wichtigeren wie uClibc zum Beispiel.

ich mein Skript hier teilen bin, wie manche Leute besser verstehen kann, was ich durch das Lesen Code bedeuten. Ich hoffe auch, dass es eine robustere Lösung gibt, die geteilt werden könnte.

#!/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

Ich bin mir nicht sicher, was genau die Frage ... Ich glaube nicht, dass es irgendeine bessere Methode für erschöpfend parallel Korrektheit als die Überprüfung Sie haben Folgendes beschrieben: Ausführen eines Builds für jedes Ziel und Überprüfen, ob es funktioniert. Ich denke jedoch nicht, dass Sie die Builds auf "-j1" beschränken müssen. Wenn sie bei "-j1" scheitern, werden sie definitiv auch bei höherem "-j" scheitern, also können Sie auch Ihre Builds beschleunigen. – MadScientist

+0

Wie fällt das bei größeren Projekten aus? Scheitert es in einer praktischen Weise oder nur von einer Zeit zu laufen/Schwierigkeit der manuellen Aufruf Perspektive? –

+0

Ich denke, das Erzwingen von "-j1" -Masken hat so viele Probleme zur Folge, wie es in die Öffentlichkeit drängt. Unter der Annahme, dass die Voraussetzungen in der angegebenen Reihenfolge erstellt werden, ist jedes 'Ziel: Voraussetzung 'Voraussetzung, wobei' Voraussetzung 'von' Voraussetzung 'abhängt, ohne zu erklären, dass dies mit' -j1 'fehlschlägt, aber mit' -jN 'vergehen kann. Invertieren Sie die Reihenfolge dieser Voraussetzungen ('prereqB prereqA') und' -j1' wird niemals versagen, aber '-jN' könnte (aber genauso gut nicht, Sie müssten die Prereq-Reihenfolge fuzz machen, um sicher zu sein). –

Antwort

1

Ich bin nicht bekannt, dass Open-Source-Lösung, aber das ist genau das Problem, dass ElectricAccelerator, eine leistungsstarke Umsetzung des GNUS machen, zu lösen erstellt wurde. Es wird den Build parallel ausführen und fehlende Abhängigkeiten dynamisch erkennen und korrigieren, sodass die Build-Ausgabe die gleiche ist, als wenn sie seriell ausgeführt wurde. Es kann ein annotiertes Build-Protokoll erstellen, das Details zu den fehlenden Abhängigkeiten enthält. Zum Beispiel hat diese einfache Make-Datei eine nicht deklarierte Abhängigkeit zwischen abc und def:

all: abc def 

abc: 
     echo PASS > abc 

def: 
     cat abc 

Run diese mit EDie statt gmake und ermöglichen --emake-annodetail=history und die resultierende Anmerkungsdatei enthält diese:

<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> 

Insbesondere der <depList> Abschnitt zeigt, dass dieser Job, Jf42015c0 (in anderen Worten, def), auf Job hängt Jf4201588, weil dieser die Datei /tmp/foo/abc geändert.

Sie können es mit ElectricAccelerator Huddle einen Versuch kostenlos geben.

(Disclaimer: Ich bin der Architekt ElectricAccelerator)

+0

Ja, das zweite. Ich kenne ElectricAccelerator aus eigener Erfahrung in mehreren großen Unternehmenssoftwareumgebungen. Für mich ist es das Beste, was ich in Scheiben geschnitten habe. Haftungsausschluss: Ich bin kein Angestellter oder in irgendeiner Weise mit ElectricCloud verbunden. –

Verwandte Themen