2016-03-29 5 views
2

Ich versuche eine gute Möglichkeit zu finden, einige RAII-ähnliche Aktionen in ein Makefile hinzuzufügen, das ich behalte. Derzeit habe ich etwas Ähnliches wie folgt aus:RAII-ähnliche Aktion in der Makefile-Regel

out: in 
    lockfile in.lock 
    echo in // Some action which can fail 
    rm -f in.lock 

Dieser Code funktioniert gut, wenn mehrere Jobs verwenden, da es in erster Linie geistige Gesundheit statt der Leistung gemeint ist. Zumindest, wenn meine Aktion nicht fehlschlägt. Also, wenn ich einen Rückfall hinzufügen möchte. Also kurz gesagt, es wird in etwa so aussehen:

out: in 
    lockfile in.lock 
    (echo in) || (rm -f in.lock; false) 
    rm -f in.lock 

Wieder einmal sieht gut aus, obwohl Ich mag nicht zweimal rm -f in.lock zu schreiben, noch die (echo in) sieht elegant aus, wenn der tatsächliche Inhalt mehrere Zeilen bash -Skript.

Dies würde ähnlich aussehen wie:

out: in 
    lockfile in.lock 
    trap "rm -f in.lock" EXIT;   \ 
    (echo in) 

Dies würde jedoch die tatsächlichen Regeln aussehen komplexer, wenn Sie verschiedene Regeln haben, die wirklich getrennt sind.

out: in 
    lockfile in.lock 
    trap "rm -f in.lock" EXIT;   \ 
    $(SHOW_DEPENDENCY_ON_DEBUG)  && \ 
    (echo in) 

Wo SHOW_DEPENDENCY_ON_DEBUG als echo [email protected] <=== $^ unter bestimmten Umständen und @ in anderen definiert werden. Ich bin mir also nicht sicher, ob ich alle Befehle gut ketten kann. Daher hoffe ich, dass jeder von euch einige Tricks kennt, die ich verpasst habe.

Kurz gesagt, Ich mag verwandeln:

out: in 
    lockfile in.lock 
    echo in // Some action(s) which can fail 
    rm -f in.lock 

In einer Weise, die immer rm -f in.lock ausführt, ohne bash-Befehle zu Kette oder die Aktion (en) zu duplizieren, die ausgeführt werden müssen, um die Aktionen zu beenden in den Regeln.

Antwort

1

Für das Problem der Ihre lockfile gewährleisten (oder jede Datei, die make macht) gelöscht wird was auch kommen mag, make eine Stammlösung hat: machen es zu einem .INTERMEDIATE target. Dann, wenn make die Datei erstellt, wird es am Ende automatisch gelöscht, kommen was auch immer, z.

Makefile

.PHONY: all clean 

all: out 

in: 
    touch [email protected] # Whatever 

.INTERMEDIATE: in.lock 

%.lock: % 
    touch [email protected] # Whatever 

out: in.lock 
    if [ "`shuf -i 0-1 -n 1`" = "0" ]; then echo Fail; false ; else echo Succeed; touch [email protected]; fi 
    rm -f $< 

clean: 
    rm -f in out 

Hier den Befehl:

if [ "`shuf -i 0-1 -n 1`" = "0" ]; then echo Fail; false ; else echo Succeed; touch [email protected]; fi 

wird auf einem pseudo-zufälligen Münzenwurf scheitern oder gelingen.

Einige Läufe:

$ make 
touch in # Whatever 
touch in.lock # Whatever 
if [ "`shuf -i 0-1 -n 1`" = "0" ]; then echo Fail; false ; else echo Succeed; touch out; fi 
Succeed 
rm -f in.lock 
$ make clean 
rm -f in out 
$ make 
touch in # Whatever 
touch in.lock # Whatever 
if [ "`shuf -i 0-1 -n 1`" = "0" ]; then echo Fail; false ; else echo Succeed; touch out; fi 
Fail 
Makefile:14: recipe for target 'out' failed 
make: *** [out] Error 1 
rm in.lock 

Aber diese Funktion nicht schieben, so weit wie die

rm -f $< 

aus dem Rezept zu entfernen. make löscht die Zwischenprodukte am Ausgang, was in Ordnung ist, wenn das Rezept fehlschlägt. Aber wenn das Rezept erfolgreich ist, möchten Sie wahrscheinlich die Lockfile sofort gelöscht, anstatt wenn make beendet, die später beliebig sein könnte.

Später

Jede Chance, die .INTERMEDIATE zu Wildcard, wie% .lock beziehen kann?

Nein, Sie haben würde bedeuten:

.INTERMEDIATE: %.lock 

und es gibt keine "Wildcard" gibt. Ohne % auf der linken Seite, ist es keine Musterregel und % auf der rechten Seite bedeutet nur %.

Aber Sie brauchen das nicht. Sie müssen die Namen der Voraussetzungen kennen, die Sie mit sperren oder zumindest in der Lage sein wollen, sie mit makefunctions zu berechnen. Ansonsten können Sie das Makefile überhaupt nicht schreiben. Also sagen sie, sie sind ina inb inc. Dann machen Sie alle Schlösser Zwischen wie:

inputs := ina inb inc 
locks := $(patsubst %,%.lock,$(inputs)) 

.INTERMEDIATE: $(locks) 
+0

Jede Chance, die .INTERMEDIATE zu Wildcard beziehen, wie% .lock? – JVApen

+0

@JVApen Nein, aber es ist OK. Siehe Aktualisierung. –

+0

Ich kenne diesen Trick, ist in meinem Fall nicht so einfach, obwohl ich denke, dass einige Bausteine ​​in der Lage sein werden, etwas zum Laufen zu bringen. Warum kann es nicht einfach sein? Tnx jedenfalls! – JVApen

Verwandte Themen