Jaki jest cel.Fałszywy w makefile?
Co oznacza .PHONY
w pliku Makefile? Przeszedłem przez to , ale to jest zbyt skomplikowane.
8 answers
Domyślnie cele Makefile są "celami plików" - są używane do budowania plików z innych plików. Make zakłada, że jego celem jest plik, co sprawia, że pisanie plików Makefile jest stosunkowo łatwe:
foo: bar
create_one_from_the_other foo bar
Jednak czasami chcesz, aby Twój plik Makefile uruchamiał polecenia, które nie reprezentują fizycznych plików w systemie plików. Dobrymi przykładami są wspólne cele "czyste" i "wszystko". Możliwe, że tak nie jest, ale ty możesz potencjalnie mieć plik o nazwie clean
w swoim głównym katalog. W takim przypadku Make będzie zdezorientowany, ponieważ domyślnie obiekt clean
będzie skojarzony z tym plikiem I Make uruchomi go tylko wtedy, gdy plik nie wydaje się być aktualny w odniesieniu do jego zależności.
Te specjalne cele są nazywane fałszywymi i można wyraźnie powiedzieć Make, że nie są powiązane z plikami, np.:
.PHONY: clean
clean:
rm -rf *.o
Teraz make clean
będzie działać zgodnie z oczekiwaniami, nawet jeśli Masz plik o nazwie clean
.
W kategoriach Make, fałszywy target jest po prostu celem, który jest zawsze Nieaktualny, więc za każdym razem, gdy zapytasz make <phony_target>
, uruchomi się, niezależnie od stanu systemu plików. Niektóre popularne cele, które są często fałszywe, to: all
, install
, clean
, distclean
, TAGS
, info
, check
.
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
2018-06-11 13:24:04
Załóżmy, że masz install
cel, który jest bardzo powszechny w plikach Makefile. Jeśli nie użyjesz .PHONY
, A plik o nazwie install
istnieje w tym samym katalogu co plik Makefile, to make install
nie zrobi nic. Dzieje się tak dlatego, że Make interpretuje regułę jako "wykonaj taką i taką przepis, aby utworzyć plik o nazwie install
". Ponieważ plik już tam jest, a jego zależności się nie zmieniły, nic nie zostanie zrobione.
Jeśli jednak uda Ci się sfałszować install
cel, będzie powiedz narzędziu make, że obiekt docelowy jest fikcyjny i że make nie powinien oczekiwać, że utworzy rzeczywisty plik. Dlatego nie sprawdzi, czy plik install
istnieje, co oznacza: a) jego zachowanie nie zostanie zmienione, jeśli plik istnieje i b) Dodatkowe stat()
nie zostanie wywołane.
Ogólnie wszystkie cele w pliku Makefile, które nie wytwarzają pliku wyjściowego o tej samej nazwie co nazwa docelowa, powinny być fałszywe. Zazwyczaj obejmuje to all
, install
, clean
, distclean
, i tak dalej.
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-01-13 01:59:54
Uwaga: narzędzie make odczytuje plik makefile i sprawdza znaczniki czasu modyfikacji plików po obu stronach symbolu':'w regule.
Przykład
W katalogu 'test' znajdują się następujące pliki:
prerit@vvdn105:~/test$ ls
hello hello.c makefile
W makefile reguła jest zdefiniowana następująco:
hello:hello.c
cc hello.c -o hello
Załóżmy teraz, że plik 'hello' jest plikiem tekstowym zawierającym pewne dane, który został utworzony po ' hello.plik C. Więc modyfikacja (lub utworzenie) znacznika czasu "hello" będzie nowsza niż to z " cześć.c'. Więc kiedy wywołamy 'make hello' z linii poleceń, wyświetli się jako:
make: `hello' is up to date.
Teraz dostęp do 'hello.c ' plik i umieścić kilka białych spacji w nim, co nie wpływa na składnię kodu lub logiki, a następnie zapisać i zamknąć. Teraz znacznik czasu modyfikacji hello.c jest nowsza od "hello". Teraz, jeśli wywołasz 'make hello', będzie to wykonywać polecenia w następujący sposób:
cc hello.c -o hello
I plik ' hello '(plik tekstowy) zostanie nadpisany nowym plikiem binarnym 'hello' (wynik powyższego polecenia kompilacji).
Jeśli użyjemy .PHONY in makefile as follow:
.PHONY:hello
hello:hello.c
cc hello.c -o hello
A następnie wywołaj 'make hello', zignoruje on dowolny plik znajdujący się w pwd o nazwie 'hello' i za każdym razem wykona polecenie.
Załóżmy teraz, że w pliku makefile nie ma zależności od celu:
hello:
cc hello.c -o hello
I plik 'hello' jest już obecny w pwd 'test', wtedy 'make hello' będzie zawsze wyświetlany jako:
make: `hello' is up to date.
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
2014-01-07 10:53:07
.PHONY: install
- oznacza, że słowo "install" nie reprezentuje nazwy pliku w tym Makefile;
- oznacza, że Makefile nie ma nic wspólnego z plikiem o nazwie "install" w tym samym katalogu.
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
2012-12-31 18:17:41
Jest to obiekt build, który nie jest nazwą pliku.
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
2010-01-27 16:48:20
Najlepszym wyjaĹ " nieniem jest sam podrÄ ™ cznik GNU make: 4.6 Phony Targets section .
.PHONY
jest jedną ze specjalnych wbudowanych nazw docelowych make . Są inne cele, które mogą Cię zainteresować, więc warto przejrzeć te odniesienia.
Kiedy nadszedł czas, aby rozważyć .Fałszywy cel, make uruchomi swój przepis bezwarunkowo, niezależnie od tego, czy plik o tej nazwie istnieje lub jaki jest czas ostatniej modyfikacji.
Ty może być również zainteresowany w standardowych celów, takich jak all
i clean
.
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
2014-04-03 23:49:40
Jest też jeden ważny tricky treat z ".PHONY " - gdy fizyczny cel zależy od fałszywego celu, który zależy od innego fizycznego celu: {]}
TARGET1 -> PHONY_FORWARDER1 -> PHONY_FORWARDER2 - > TARGET2
Można po prostu oczekiwać, że po zaktualizowaniu TARGET2, TARGET1 powinien zostać uznany za przestarzały w stosunku do TARGET1, więc TARGET1 powinien zostać odbudowany. i to naprawdę działa w ten sposób.
Najtrudniejsze jest to, gdy TARGET2 nie jest[11]} nieświeży wobec TARGET1-w w którym przypadku należy się spodziewać, że TARGET1 nie powinien zostać odbudowany.
To zaskakująco nie działa, ponieważ: fałszywy cel i tak został uruchomiony (jak zwykle robią to fałszywe cele) , co oznacza, że fałszywy cel został uznany za zaktualizowany . I z tego powodu TARGET1 jest uważany za przestarzały w stosunku do fałszywego celu.
Rozważmy:
all: fileall
fileall: file2 filefwd
echo file2 file1 >fileall
file2: file2.src
echo file2.src >file2
file1: file1.src
echo file1.src >file1
echo file1.src >>file1
.PHONY: filefwd
.PHONY: filefwd2
filefwd: filefwd2
filefwd2: file1
@echo "Produced target file1"
prepare:
echo "Some text 1" >> file1.src
echo "Some text 2" >> file2.src
Możesz się tym bawić:
- najpierw wykonaj 'make prepare', aby przygotować " źródło pliki "
- baw się tym, dotykając poszczególnych plików, aby zobaczyć je aktualizowane
Widać, że fileall zależy od file1 pośrednio przez fałszywy cel - ale zawsze jest odbudowywany z powodu tej zależności. Jeśli zmienisz zależność w fileall
z filefwd
na file
, Teraz fileall
nie jest odbudowywany za każdym razem, ale tylko wtedy, gdy którykolwiek z zależnych celów jest przestarzały wobec niego jako plik.
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
2015-02-11 10:11:52
Często używam ich, aby powiedzieć domyślnemu celowi, aby nie strzelał.
superclean: clean andsomethingelse
blah: superclean
clean:
@echo clean
%:
@echo catcher $@
.PHONY: superclean
Bez fałszu, make superclean
strzelałby clean
, andsomethingelse
, i catcher superclean
; ale z fałszywym, {[2] }nie odpali catcher superclean
.
Nie musimy się martwić o powiedzenie, że cel clean
jest fałszywy, ponieważ nie jest całkowicie fałszywy. Chociaż nigdy nie tworzy czystego Pliku, ma komendy do odpalenia, więc make pomyśli, że jest ostatecznym celem.
Jednak cel superclean
naprawdę jest fałszywy, więc make spróbuje go ułożyć z czymkolwiek innym, co zapewnia deps dla celu superclean
- obejmuje to inne cele superclean
i cel %
.
Zauważ, że nie mówimy nic o andsomethingelse
lub blah
, więc wyraźnie idą do łapacza.
Wyjście wygląda mniej więcej Tak:
$ make clean
clean
$ make superclean
clean
catcher andsomethingelse
$ make blah
clean
catcher andsomethingelse
catcher blah
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
2018-07-08 13:22:45