In meiner GNUmake-Datei möchte ich eine Regel haben, die ein temporäres Verzeichnis verwendet. Beispielsweise:
out.tar: TMP := $(shell mktemp -d)
echo hi $(TMP)/hi.txt
tar -C $(TMP) cf $@ .
rm -rf $(TMP)
Wie oben beschrieben, erstellt die obige Regel das temporäre Verzeichnis zum Zeitpunkt des Analysierens der Regel . Dies bedeutet, dass viele temporäre Verzeichnisse erstellt werden, auch wenn ich nicht die ganze Zeit rumgefahren bin. Ich möchte vermeiden, dass mein / tmp mit nicht verwendeten temporären Verzeichnissen übersät ist.
Gibt es eine Möglichkeit, die Variable nur zu definieren, wenn die Regel ausgelöst wird, und nicht, wenn sie definiert wird?
Mein Hauptgedanke ist es, mktemp und tar in ein Shell-Skript zu kopieren, aber das scheint etwas unansehnlich.
$(eval $@_TMP := $(shell mktemp -d))
wird passieren, wenn das Makefile zum ersten Mal ausgewertet wird, nicht in der Reihenfolge der Regelprozeduren. Mit anderen Worten,$(eval ...)
passiert früher als Sie denken. Während dies für dieses Beispiel in Ordnung sein könnte, verursacht diese Methode Probleme bei einigen sequentiellen Operationen.Eine relativ einfache Möglichkeit besteht darin, die gesamte Sequenz als Shell-Skript zu schreiben.
Ich habe hier einige verwandte Tipps zusammengefasst: https://stackoverflow.com/a/29085684/86967
quelle
@
undeval
und machen den gleichen Job). Beachten Sie, dass in Ihrer Ausgabe$TMP
(z. B.tar -C $TMP ...
) angezeigt wird, obwohl der Wert korrekt an den Befehl übergeben wurde.SHELL := /bin/bash
in Ihrem Makefile auch BASH-spezifische Funktionen aktivieren.Eine andere Möglichkeit besteht darin, separate Zeilen zu verwenden, um Make-Variablen einzurichten, wenn eine Regel ausgelöst wird.
Hier ist zum Beispiel ein Makefile mit zwei Regeln. Wenn eine Regel ausgelöst wird, erstellt sie ein temporäres Verzeichnis und setzt TMP auf den Namen des temporären Verzeichnisses.
Das Ausführen des Codes führt zu dem erwarteten Ergebnis:
quelle
ruleA: TMP = $(shell mktemp -d testruleA_XXXX)
undruleB: TMP = $(shell mktemp -d testruleB_XXXX)
wird passieren, wenn das Makefile zum ersten Mal ausgewertet wird. Mit anderen Worten,ruleA: TMP = $(shell ...
passiert früher als Sie denken. Während dies in diesem speziellen Fall möglicherweise funktioniert, verursacht diese Methode bei einigen sequentiellen Operationen Probleme.Ich mag keine "Nicht" -Antworten, aber ... nicht.
make
Die Variablen von sind global und sollen während der "Parsing" -Stufe des Makefiles ausgewertet werden, nicht während der Ausführungsphase.In diesem Fall folgen Sie der Antwort von @ nobar , solange sich die Variable auf einem einzelnen Ziel befindet und machen Sie sie zu einer Shell-Variablen.
Auch zielspezifische Variablen werden von anderen make-Implementierungen als schädlich angesehen: kati , Mozilla pymake . Aufgrund dessen kann ein Ziel unterschiedlich erstellt werden, je nachdem, ob es eigenständig erstellt wurde oder als Abhängigkeit eines übergeordneten Ziels mit einer zielspezifischen Variablen. Und Sie werden nicht wissen, wie es war , weil Sie nicht wissen, was bereits gebaut ist.
quelle