Define make variable at rule execution time
W moim GNUmakefile chciałbym mieć regułę, która używa katalogu tymczasowego. Na przykład:
out.tar: TMP := $(shell mktemp -d)
echo hi $(TMP)/hi.txt
tar -C $(TMP) cf $@ .
rm -rf $(TMP)
Zgodnie z zapisem powyższa reguła tworzy katalog tymczasowy w czasie, gdy reguła jest przetwarzana . To oznacza, że nawet ja się nie całuję.tar cały czas tworzy się wiele katalogów tymczasowych. Chciałbym, aby mój /tmp nie był zaśmiecony nieużywanymi katalogami tymczasowymi.
Czy istnieje sposób, aby zmienna była zdefiniowana tylko wtedy, gdy reguła jest wywołana, w przeciwieństwie do ilekroć jest zdefiniowana?
Moją główną myślą jest wrzucenie mktemp i tar do skryptu powłoki, ale wydaje się to nieco nieestetyczne.
3 answers
W twoim przykładzie zmienna TMP
jest ustawiana (i tworzony jest katalog tymczasowy) za każdym razem, gdy oceniane są reguły dla out.tar
. Aby utworzyć katalog tylko wtedy, gdy out.tar
jest rzeczywiście zwolniony, musisz przenieść tworzenie katalogu w dół do kroków:
out.tar :
$(eval TMP := $(shell mktemp -d))
@echo hi $(TMP)/hi.txt
tar -C $(TMP) cf $@ .
rm -rf $(TMP)
Funkcja eval ocenia łańcuch znaków tak, jakby został wpisany do pliku makefile ręcznie. W tym przypadku ustawia zmienną TMP
na wynik funkcji shell
sprawdzam.
Edit (w odpowiedzi na komentarze):
Aby utworzyć unikalną zmienną, możesz wykonać następujące czynności:
out.tar :
$(eval $@_TMP := $(shell mktemp -d))
@echo hi $($@_TMP)/hi.txt
tar -C $($@_TMP) cf $@ .
rm -rf $($@_TMP)
To będzie poprzedzać nazwę celu (out.tar, w tym przypadku) do zmiennej, tworząc zmienną o nazwie out.tar_TMP
. Miejmy nadzieję, że to wystarczy, aby zapobiec konfliktom.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-15 22:18:59
Stosunkowo łatwym sposobem na to jest napisanie całej sekwencji jako skryptu powłoki.
out.tar:
set -e ;\
TMP=$$(mktemp -d) ;\
echo hi $$TMP/hi.txt ;\
tar -C $$TMP cf $@ . ;\
rm -rf $$TMP ;\
Zebrałem kilka powiązanych porad tutaj: https://stackoverflow.com/a/29085684/86967
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:43
Inną możliwością jest użycie osobnych linii do Ustawienia zmiennych Make, gdy reguła zostanie wywołana.
Na przykład, oto plik makefile z dwiema zasadami. Jeśli reguła zostanie wywołana, utworzy katalog temp i ustawi tmp na nazwę katalogu temp.
PHONY = ruleA ruleB display
all: ruleA
ruleA: TMP = $(shell mktemp -d testruleA_XXXX)
ruleA: display
ruleB: TMP = $(shell mktemp -d testruleB_XXXX)
ruleB: display
display:
echo ${TMP}
Uruchomienie kodu daje oczekiwany wynik:
$ ls
Makefile
$ make ruleB
echo testruleB_Y4Ow
testruleB_Y4Ow
$ ls
Makefile testruleB_Y4Ow
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-21 01:32:21