W moim pliku GNUmakefile chciałbym mieć regułę, która korzysta z katalogu tymczasowego. Na przykład:
out.tar: TMP := $(shell mktemp -d)
echo hi $(TMP)/hi.txt
tar -C $(TMP) cf $@ .
rm -rf $(TMP)
Jak napisano, powyższa reguła tworzy katalog tymczasowy w momencie analizowania reguły . Oznacza to, że nawet ja nie rozumiem. Cały czas powstaje wiele katalogów tymczasowych. Chciałbym uniknąć zapełnienia mojego / tmp nieużywanymi katalogami tymczasowymi.
Czy istnieje sposób, aby zmienna była definiowana tylko podczas uruchamiania reguły, a nie w przypadku jej definiowania?
Moją główną myślą jest zrzucenie mktemp i tar do skryptu powłoki, ale wydaje się to trochę nieestetyczne.
$(eval $@_TMP := $(shell mktemp -d))
stanie się, gdy plik Makefile zostanie po raz pierwszy oceniony niezgodnie z procedurami reguł. Innymi słowy,$(eval ...)
dzieje się wcześniej niż myślisz. Chociaż może to być w porządku w tym przykładzie, ta metoda spowoduje problemy w przypadku niektórych operacji sekwencyjnych.Stosunkowo łatwym sposobem na to jest napisanie całej sekwencji jako skryptu powłoki.
Skonsolidowałem kilka pokrewnych wskazówek tutaj: https://stackoverflow.com/a/29085684/86967
źródło
@
aeval
i wykonywanie tej samej pracy). Zauważ, że na wyjściu widać$TMP
(np.tar -C $TMP ...
), Chociaż wartość jest poprawna przekazana do polecenia.SHELL := /bin/bash
w swoim makefile włączyć funkcje specyficzne dla BASH.Inną możliwością jest użycie osobnych linii do skonfigurowania Make zmiennych, gdy reguła zostanie uruchomiona.
Na przykład tutaj jest plik makefile z dwiema regułami. Jeśli reguła zostanie uruchomiona, tworzy katalog tymczasowy i ustawia TMP na nazwę katalog tymczasowy.
Uruchomienie kodu daje oczekiwany wynik:
źródło
ruleA: TMP = $(shell mktemp -d testruleA_XXXX)
iruleB: TMP = $(shell mktemp -d testruleB_XXXX)
stanie się, gdy plik Makefile zostanie po raz pierwszy oceniony. Innymi słowy,ruleA: TMP = $(shell ...
dzieje się wcześniej niż myślisz. Chociaż może to działać w tym konkretnym przypadku, ta metoda spowoduje problemy w przypadku niektórych operacji sekwencyjnych.Nie lubię odpowiedzi „Nie”, ale… nie.
make
Zmienne mają charakter globalny i należy je oceniać na etapie analizy pliku makefile, a nie na etapie wykonywania.W takim przypadku, dopóki zmienna lokalna dla pojedynczego celu, podążaj za odpowiedzią @ nobar i uczyń ją zmienną powłoki.
Zmienne specyficzne dla celu również są uważane za szkodliwe przez implementacje innych marek : kati , pillaake Mozilli . Z ich powodu cel można zbudować inaczej w zależności od tego, czy jest on zbudowany autonomicznie, czy jako zależność celu nadrzędnego od zmiennej specyficznej dla celu. I nie będziesz wiedział, jak to było , ponieważ nie wiesz, co jest już zbudowane.
źródło