2607 Stimmen

Was ist der Zweck von .PHONY in einem Makefile?

Was bedeutet .PHONY in einem Makefile bedeuten? Ich bin durchgegangen ce aber das ist zu kompliziert.

Kann mir das jemand mit einfachen Worten erklären?

52voto

Edouard Thiel Punkte 5024

Das besondere Ziel .PHONY: erlaubt es, falsche Ziele zu deklarieren, so dass make prüft sie nicht als tatsächliche Dateinamen: Es funktioniert immer, auch wenn solche Dateien noch existieren.

Sie können mehrere .PHONY: in Ihrem Makefile :

.PHONY: all

all : prog1 prog2

...

.PHONY: clean distclean

clean :
    ...
distclean :
    ...

Es gibt noch eine andere Möglichkeit, falsche Ziele zu deklarieren: einfach gesagt :: ohne Vorbedingungen :

all :: prog1 prog2

...

clean ::
    ...
distclean ::
    ...

El :: hat weitere spezielle Bedeutungen, siehe aquí Die Rezepte werden immer ausgeführt, auch wenn das Ziel bereits existiert, so dass es sich um ein falsches Ziel handelt.

38voto

James Wald Punkte 13436

Die beste Erklärung ist das GNU make Handbuch selbst: 4.6 Abschnitt "Gefälschte Ziele .

.PHONY ist eine von make's Spezielle eingebaute Zielnamen . Es gibt noch weitere Ziele, die für Sie von Interesse sein könnten, so dass es sich lohnt, diese Referenzen zu überfliegen.

Wenn es an der Zeit ist, ein .PHONY-Ziel zu berücksichtigen, wird make sein Rezept bedingungslos aus, unabhängig davon, ob eine Datei mit diesem Namen existiert oder wann sie zuletzt geändert wurde.

Vielleicht interessieren Sie sich auch für make's Standard-Ziele wie zum Beispiel all y clean .

15voto

Ethouris Punkte 1681

Es gibt auch eine wichtige knifflige Behandlung von ".PHONY" - wenn ein physisches Ziel von einem falschen Ziel abhängt, das von einem anderen physischen Ziel abhängt:

ZIEL1 -> FALSCHER_WEITERLEITER1 -> FALSCHER_WEITERLEITER2 -> ZIEL2

Sie würden einfach erwarten, dass, wenn Sie TARGET2 aktualisiert haben, TARGET1 als veraltet im Vergleich zu TARGET1 betrachtet werden sollte, so dass TARGET1 neu erstellt werden sollte. Und so funktioniert es wirklich .

Der knifflige Teil ist, wenn TARGET2 ist nicht stale gegen TARGET1 - in diesem Fall sollten Sie davon ausgehen, dass TARGET1 nicht neu erstellt werden sollte.

Das funktioniert überraschenderweise nicht, weil: das gefälschte Ziel wurde trotzdem ausgeführt (wie es bei gefälschten Zielen üblich ist) was bedeutet, dass das gefälschte Ziel wurde als aktualisiert betrachtet . Und aus diesem Grund TARGET1 wird gegenüber dem falschen Ziel als veraltet betrachtet .

Bedenken Sie:

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

Sie können damit herumspielen:

  • zuerst "make prepare" ausführen, um die "Quelldateien" vorzubereiten
  • damit spielen, indem Sie auf bestimmte Dateien tippen, um sie zu aktualisieren

Sie können sehen, dass fileall indirekt von file1 durch ein falsches Ziel abhängt - aber es immer wird aufgrund dieser Abhängigkeit neu erstellt. Wenn Sie die Abhängigkeit in fileall から filefwd a file , jetzt fileall wird nicht jedes Mal neu erstellt, sondern nur, wenn eines der abhängigen Ziele als Datei veraltet ist.

5voto

jettero Punkte 805

Ich verwende sie oft, um dem Standardziel mitzuteilen, dass es nicht schießen soll.

superclean: clean andsomethingelse

blah: superclean

clean:
   @echo clean

%:
   @echo catcher $@

.PHONY: superclean

Ohne PHONY, make superclean würde schießen clean , andsomethingelse y catcher superclean ; aber mit PHONY, make superclean schießt nicht die catcher superclean .

Wir müssen uns keine Gedanken darüber machen, wie wir die clean Ziel ist PHONY, weil es nicht völlig falsch ist. Obwohl es nie die saubere Datei erzeugt, hat es Befehle, die es abfeuern kann, so dass Make denkt, es sei ein endgültiges Ziel.

Allerdings ist die superclean Ziel ist wirklich falsch, also wird make versuchen, es mit allem anderen zu kombinieren, das Deps für die superclean Ziel - dies schließt andere superclean Ziele und die % Ziel.

Beachten Sie, dass wir überhaupt nichts sagen über andsomethingelse o blah Sie gehen also eindeutig an den Fänger.

Die Ausgabe sieht in etwa so aus:

$ make clean
clean

$ make superclean
clean
catcher andsomethingelse

$ make blah 
clean
catcher andsomethingelse
catcher blah

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X