Was .PHONY
bedeutet in einem Makefile? Ich habe durchgemacht dies , aber es ist zu kompliziert.
Kann es mir jemand in einfachen Worten erklären?
quelle
Was .PHONY
bedeutet in einem Makefile? Ich habe durchgemacht dies , aber es ist zu kompliziert.
Kann es mir jemand in einfachen Worten erklären?
Standardmäßig sind Makefile-Ziele "Dateiziele" - sie werden zum Erstellen von Dateien aus anderen Dateien verwendet. Make geht davon aus, dass das Ziel eine Datei ist, und dies macht das Schreiben von Makefiles relativ einfach:
foo: bar
create_one_from_the_other foo bar
Manchmal möchten Sie jedoch, dass Ihr Makefile Befehle ausführt, die keine physischen Dateien im Dateisystem darstellen. Gute Beispiele dafür sind die gemeinsamen Ziele "sauber" und "alle". Möglicherweise ist dies nicht der Fall, aber möglicherweise befindet sich eine Datei mit dem Namen clean
in Ihrem Hauptverzeichnis. In einem solchen Fall wird Make verwirrt, da das clean
Ziel standardmäßig dieser Datei zugeordnet ist und Make es nur ausführt, wenn die Datei hinsichtlich ihrer Abhängigkeiten nicht auf dem neuesten Stand zu sein scheint.
Diese speziellen Ziele werden als falsch bezeichnet und Sie können explizit festlegen, dass Make nicht mit Dateien verknüpft ist, z.
.PHONY: clean
clean:
rm -rf *.o
Jetzt make clean
wird es wie erwartet ausgeführt, auch wenn Sie eine Datei mit dem Namen haben clean
.
In Bezug auf Make ist ein falsches Ziel einfach ein Ziel, das immer veraltet ist. Wenn Sie also danach fragen make <phony_target>
, wird es unabhängig vom Status des Dateisystems ausgeführt. Einige gemeinsame make
Ziele , die oft unecht sind: all
, install
, clean
, distclean
, TAGS
, info
, check
.
Nehmen wir an, Sie haben ein
install
Ziel, was in Makefiles sehr häufig vorkommt. Wenn Sie nicht verwenden.PHONY
und eine Datei mit dem Nameninstall
im selben Verzeichnis wie das Makefile vorhanden ist,make install
wird nichts unternommen . Dies liegt daran, dass Make die Regel so interpretiert, dass sie "das eine oder andere Rezept ausführen, um die Datei mit dem Namen zu erstelleninstall
" bedeutet. Da die Datei bereits vorhanden ist und sich ihre Abhängigkeiten nicht geändert haben, wird nichts unternommen.Wenn Sie jedoch das
install
Ziel PHONY erstellen, teilt es dem make-Tool mit, dass das Ziel fiktiv ist und dass make nicht erwarten sollte, dass es die eigentliche Datei erstellt. Daher wird nicht geprüft, ob dieinstall
Datei vorhanden ist, was bedeutet: a) ihr Verhalten wird nicht geändert, wenn die Datei vorhanden ist, und b) extrastat()
wird nicht aufgerufen.Im Allgemeinen sollten alle Ziele in Ihrem Makefile, die keine Ausgabedatei mit demselben Namen wie der Zielname erzeugen, PHONY sein. Dies umfasst in der Regel
all
,install
,clean
,distclean
, und so weiter.quelle
.sh
oder.bash
für "Programme" wegzulassen, die so ausgeführt werden, als hätten sie eine Hauptfunktion, und das Hinzufügen einer Erweiterung für Bibliotheken, die Sie einschließen (source mylib.sh
). Tatsächlich kam ich zu dieser SO-Frage, weil ich ein Skript im selben Verzeichnis wie mein Makefile hatteinstall
.PHONY
ganze Zeit ....PHONY
Version sind.HINWEIS : Das Make-Tool liest das Makefile und überprüft in einer Regel die Änderungszeitstempel der Dateien auf beiden Seiten des Symbols ':'.
Beispiel
In einem Verzeichnis 'test' sind folgende Dateien vorhanden:
In Makefile wird eine Regel wie folgt definiert:
Nehmen wir nun an, dass die Datei 'Hallo' eine Textdatei ist, die einige Daten enthält, die nach der Datei 'Hallo.c' erstellt wurden. Der Zeitstempel für die Änderung (oder Erstellung) von "Hallo" ist also neuer als der von "Hallo.c". Wenn wir also 'Hallo machen' über die Befehlszeile aufrufen, wird Folgendes gedruckt:
Greifen Sie jetzt auf die Datei 'hello.c' zu und fügen Sie einige Leerzeichen ein, die die Codesyntax oder -logik nicht beeinflussen. Speichern und beenden Sie sie dann. Jetzt ist der Änderungszeitstempel von hello.c neuer als der von 'hallo'. Wenn Sie nun 'Hallo machen' aufrufen, werden die Befehle wie folgt ausgeführt:
Und die Datei 'Hallo' (Textdatei) wird mit einer neuen Binärdatei 'Hallo' (Ergebnis des obigen Kompilierungsbefehls) überschrieben.
Wenn wir .PHONY im Makefile wie folgt verwenden:
Wenn Sie dann 'make hello' aufrufen, werden alle im pwd 'test' vorhandenen Dateien ignoriert und der Befehl jedes Mal ausgeführt.
Angenommen, für das Hallo-Ziel sind keine Abhängigkeiten deklariert:
und 'Hallo' Datei ist bereits im pwd 'Test' vorhanden, dann wird 'Hallo machen' immer angezeigt als:
quelle
make
, sinnvoll, sondern macht letztendlich auch insgesamt Sinn, es geht nur um die Dateien! Vielen Dank für diese Antwort.quelle
Es ist ein Build-Ziel, das kein Dateiname ist.
quelle
Die beste Erklärung ist das GNU-Handbuch selbst: 4.6 Abschnitt "Falsche Ziele" .
.PHONY
ist einer der speziellen integrierten Zielnamen von make . Es gibt andere Ziele, an denen Sie interessiert sein könnten. Es lohnt sich daher, diese Referenzen durchzublättern.Möglicherweise interessieren Sie sich auch für die Standardziele von make wie
all
undclean
.quelle
Es gibt auch einen wichtigen kniffligen Leckerbissen von ".PHONY" - wenn ein physisches Ziel von einem falschen Ziel abhängt, das von einem anderen physischen Ziel abhängt:
TARGET1 -> PHONY_FORWARDER1 -> PHONY_FORWARDER2 -> TARGET2
Sie würden einfach erwarten, dass TARGET1, wenn Sie TARGET2 aktualisiert haben, als veraltet gegenüber TARGET1 angesehen werden sollte, sodass TARGET1 neu erstellt werden sollte. Und so funktioniert es wirklich .
Der schwierige Teil ist, wenn TARGET2 gegen TARGET1 nicht veraltet ist. In diesem Fall sollten Sie damit rechnen, dass TARGET1 nicht neu erstellt werden sollte.
Dies funktioniert überraschenderweise nicht, weil: das falsche Ziel trotzdem ausgeführt wurde (wie es normalerweise bei falschen Zielen der Fall ist ) , was bedeutet, dass das falsche Ziel als aktualisiert angesehen wurde . Und aus diesem Grund gilt TARGET1 als abgestanden gegen das falsche Ziel .
Erwägen:
Sie können damit herumspielen:
Sie können sehen, dass fileall indirekt über ein falsches Ziel von file1 abhängt. Aufgrund dieser Abhängigkeit wird es jedoch immer neu erstellt . Wenn Sie die Abhängigkeit ändern in
fileall
vonfilefwd
zufile
, jetztfileall
wird nicht jedes Mal wieder aufgebaut, aber nur dann , wenn alle abhängigen Ziele ist abgestanden dagegen als Datei.quelle
Das spezielle Ziel
.PHONY:
ermöglicht es, falsche Ziele zu deklarieren, so dassmake
nicht als tatsächliche Dateinamen überprüft werden. Es funktioniert immer, auch wenn solche Dateien noch vorhanden sind.Sie können mehrere
.PHONY:
in IhreMakefile
:Es gibt eine andere Möglichkeit, falsche Ziele zu deklarieren: Setzen Sie einfach '::'
Das '::' hat eine besondere Bedeutung: Ziele sind falsch und können mehrmals vorkommen:
Die Befehlsblöcke werden nacheinander aufgerufen.
quelle
Ich benutze sie oft, um dem Standardziel mitzuteilen, dass es nicht feuern soll.
Ohne PHONY,
make superclean
würde Feuerclean
,andsomethingelse
undcatcher superclean
; aber mit PHONYmake superclean
wird das nicht feuerncatcher superclean
.Wir müssen uns keine Sorgen machen, dass wir das machen
clean
Ziel PHONY ist, weil es nicht ganz falsch ist. Obwohl die saubere Datei nie erstellt wird, müssen Befehle ausgelöst werden, sodass make den Eindruck erweckt, dass es sich um ein endgültiges Ziel handelt.Das
superclean
Ziel ist jedoch wirklich falsch, daher wird make versuchen, es mit allem anderen zu stapeln, das Deps für dassuperclean
Ziel bereitstellt - dies schließt anderesuperclean
Ziele und das%
Ziel ein.Beachten Sie, dass wir überhaupt nichts über
andsomethingelse
oder sagenblah
, also gehen sie eindeutig zum Fänger.Die Ausgabe sieht ungefähr so aus:
quelle