Jaki jest cel.Fałszywy w makefile?

Co oznacza .PHONY w pliku Makefile? Przeszedłem przez to , ale to jest zbyt skomplikowane.

Czy ktoś może mi to wyjaśnić w prosty sposób?
Author: Adam Matan, 2010-01-27

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.

 1395
Author: Eli Bendersky,
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.

 645
Author: George Y.,
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.
 68
Author: prerit jain,
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.
 64
Author: YourBestBet,
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.

 35
Author: JohnMcG,
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.

 22
Author: James Wald,
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.

 8
Author: Ethouris,
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
 0
Author: jettero,
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