Heim > Artikel > Backend-Entwicklung > Makefile-Regeln
Inhalt
1. Einführung 3
1.2. Einführung in das Makefile 4
1.4. Funktionsweise von Makefile 4
1.5. Verwendungsvariablen 5
1.7. Ein anderer Stil 6
1.8. Makefile 7
2.2. Enthält 8
2.3. „MAKEFILE“-Variable 8
2.5. Überladen Sie Makefile 9
3.1. Syntax der Regeln 9
3.3. Platzhalter 10
3.3.1. Fehler der Platzhalterfunktion 11
3.4. Verzeichnissuche 11
3.4 .2. Selektive Suche12
3.4.3. Verwendung automatischer Variablen12
3.5.PHONY-Ziel13
3.6.FORCE-Ziel14
3.7 >3.8. Integriertes außerordentliches Ziel15
3.10. Ein Ziel für mehrere Regeln15
3.11. Statische Modusregel 16
3.11 .2. Statische Modusregeln und implizite Regeln 17
3.13. Abhängigkeiten automatisch generieren 18
4.1. Echo 18
4.2. Ausführung 19
4.3. Parallele Ausführung 19
4.5. Interrupt make 20
4.6.1. 'MAKE'-Variablen 20
Übergabe von Variablen an Sub-Make 21
6. Referenzen 25
6.2. Funktion 26
6.4. Außergewöhnliche Variablen 29
GNU Make verwendet
Das Make-Programm wurde ursprünglich entwickelt, um C-Programmdateien zu verwalten und unnötige Neukompilierungen zu verhindern. Wie kann sichergestellt werden, dass alle Dateien, die diese Header-Datei enthalten, kompiliert werden, wenn der Befehlszeilen-Compiler verwendet wird? Die aktuelle 10-Maschinen-Version verwendet ein Batch-Programm, das vom Betreuer des Programms abhängt. Wenn Module auf die Header-Dateien des anderen verweisen, ist es schwierig, alle Dateien zu finden, die neu kompiliert werden müssen Ändern Sie diese Dateien im Batch-Prozess, um sie zu kompilieren. Tatsächlich können diese Aufgaben automatisch vom Make-Programm ausgeführt werden. Das Make-Tool ist sehr nützlich für die Verwaltung einiger Dateien, die voneinander abhängig sind. Es stellt eine Reihe von Codes für die Beziehung zwischen Dateien und Befehlen bereit (Programme, die zum Aktualisieren anderer Dateien aufgerufen werden). wenn sich Dateien ändern). Das Grundkonzept des Make-Tools ähnelt dem der PRoglog-Sprache. Sie sagen make, was getan werden muss, stellen einige Regeln bereit und make erledigt den Rest.
1. Einführung
Der Make-Job ermittelt automatisch, welche Teile des Projekts neu kompiliert werden müssen und führt Befehle aus, um sie zu kompilieren. Obwohl make hauptsächlich für C-Programme verwendet wird, können Sie es für jede beliebige Sprache verwenden, solange ein Befehlszeilen-Compiler bereitgestellt wird. Tatsächlich ist der Anwendungsbereich des Make-Tools nicht auf die Programmierung beschränkt. Sie können damit jede Aufgabe beschreiben und einige Dateien ändern, die andere Dateien automatisch aktualisieren müssen.
1.1. Vorbereitende Arbeiten
Wenn Sie make verwenden möchten, müssen Sie eine Datei namens „makefile“ schreiben. Diese Datei beschreibt die Beziehung zwischen den Dateien im Projekt und stellt Befehle zum Aktualisieren jeder Datei bereit. Ein typisches Projekt sieht folgendermaßen aus: Die ausführbare Datei wird durch die Zieldatei aktualisiert, und die Zieldatei wird durch Kompilieren der Quelldatei aktualisiert.
Nachdem das Makefile geschrieben wurde, reicht es bei jeder Änderung der Quelldatei aus, make auszuführen, und alle erforderlichen Neukompilierungen werden durchgeführt. Das Make-Programm verwendet die Datenbank im Makefile und den Zeitpunkt der letzten Änderung der Datei, um zu bestimmen, welche Datei aktualisiert werden muss. Für die zu aktualisierende Datei führt make die in der Datenbank aufgezeichneten Befehle aus.
Sie können Befehlszeilenparameter bereitstellen, um zu steuern, welche Dateien neu kompiliert werden müssen.
1.2. Makefile-Einführung
Makefile sagt make, was zu tun ist, in den meisten Fällen, wie ein Programm kompiliert und verknüpft wird.
Hier ist ein einfaches Makefile, das beschreibt, wie ein Editor bestehend aus 8 C-Dateien und 3 Header-Dateien kompiliert und verknüpft wird:
edit: main.o kbd.o command.o display.o
insert .o serach .o files.o utils.o
cc –o edit main.o kbd.o command.o display.o
insert.o files.o utils.o
main o : main.c defs.h
cc –c main.c
kdb.o : kbd.c defs.h command.h
cc –c kbd.c
Befehl. o : command .c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : .c defs.h buffer.h einfügen
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files .c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o
insert.o search.o files.o utils.o
Trennen Sie lange Zeilen zum leichteren Lesen, was den gleichen Effekt hat wie die Verwendung einer langen Zeile. Führen Sie einfach make aus, wenn Sie dieses Makefile verwenden, um die ausführbare Datei „edit“ zu erstellen. Wenn Sie die ausführbare Datei und die Zieldatei löschen möchten, führen Sie make clean aus.
Wenn make diesen Editor neu kompiliert, muss jede geänderte C-Datei neu erstellt werden Wenn die Header-Datei geändert wird, muss jede C-Datei, die die Header-Datei enthält, neu kompiliert werden. Bei jeder Kompilierung wird eine Objektdatei erstellt, die der Originaldatei entspricht. Schließlich werden die Objektdateien miteinander verknüpft, um eine neue ausführbare Datei zu erstellen.
1.3. Einführung in Regeln
Die Regeln im Makefile lauten wie folgt:
TARGET … : ABHÄNGIGKEITEN …
COMMAND
…
Vom Programm generierte Zieldateien (TARGET), z. B. ausführbare Dateien und Zieldateien, können auch eine auszuführende Aktion wie „Bereinigen“ sein.
ABHÄNGIGKEITEN sind Eingabedateien, die zum Generieren von Zielen verwendet werden. Ein Ziel hängt normalerweise von mehreren Dateien ab.
Befehl (COMMAND) ist eine von make ausgeführte Aktion. Es können mehrere Befehle vorhanden sein, die jeweils eine Zeile belegen. Hinweis: Das Startzeichen jeder Befehlszeile muss das TAB-Zeichen sein!
Befehle in Abhängigkeitsregeln sind normalerweise für die Generierung von Zieldateien verantwortlich, wenn sich abhängige Dateien ändern. Make führt diese Befehle aus, um Ziele zu aktualisieren oder zu generieren. Regeln dürfen keine Abhängigkeiten haben, z. B. Regeln, die das Ziel „sauber“ enthalten.
Die Regeln erklären, wie und wann die Dateien in den Regeln wiederholt werden müssen, um das Ziel basierend auf der Abhängigkeitsbeziehung zu generieren oder zu aktualisieren. Einige der Regeln mögen kompliziert erscheinen, aber sie entsprechen alle dem oben genannten Muster.
1.4. Funktionsweise von make
Standardmäßig beginnt make mit dem ersten Ziel (dem ersten Ziel, das nicht mit „.“ beginnt), das als Standardziel bezeichnet wird. Im obigen Makefile besteht das Standardziel darin, den Executor „edit“ zu aktualisieren, also setzen Sie dieses Ziel an den Anfang. Wenn make ausgeführt wird, liest das make-Programm das Makefile aus dem aktuellen Verzeichnis und beginnt mit der Verarbeitung der ersten Regel. Im Beispiel dient diese Regel dazu, „edit“ erneut zu verknüpfen, bevor make diese Regel verarbeiten kann. Hängt davon ab. Regeln für Dateien, in diesem Fall die Zieldatei. Diese Dateien werden nach ihren eigenen Regeln verarbeitet: Jede „.o“-Datei wird durch Kompilieren der Quelldatei aktualisiert, wenn die Quelldatei oder Headerdatei in der Abhängigkeitsbeziehung neuer als die Zieldatei ist oder die Zieldatei nicht existiert. es muss neu kompiliert werden.
Andere Regeln werden verarbeitet, da ihr Ziel eine Abhängigkeit vom Ziel ist. Regeln, die keine Abhängigkeit vom Ziel haben, werden nicht verarbeitet, es sei denn, die Make-Verarbeitung wird angegeben (z. B. make clean).
Bevor die Zieldatei neu kompiliert wird, versucht make, ihre Abhängigkeiten zu aktualisieren: Quelldateien und Headerdateien. Das Makefile im Beispiel spezifiziert keine Vorgänge für Quelldateien und Headerdateien: „.c“- und „.h“-Dateien sind nicht das Ziel von Regeln. Nachdem sichergestellt wurde, dass alle Objektdateien auf dem neuesten Stand sind, entscheidet make, ob „edit“ erneut verknüpft werden soll: Wenn „edit“ nicht vorhanden ist oder eine Objektdatei neuer ist, wird die Verknüpfungsarbeit fortgesetzt.
Wenn wir insert.c ändern und make ausführen, kompiliert make diese Datei, um „insert.o“ zu aktualisieren, und verknüpft dann „edit“. Wenn wir „command.h“ ändern und make ausführen, wird „kbd“ ausgeführt .o“, „command.o“, „files.o“ werden neu generiert und mit „edit“ verknüpft.
1.5. Verwendung von Variablen
Im Beispiel wird in der Regel „Bearbeiten“ die Zieldatei zweimal aufgeführt:
edit : main.o kbd.o command.o display.o
insert . o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o
insert.o search.o files.o utils.o
like Durch Wiederholung kann es leicht zu Fehlern kommen: Angenommen, eine neue Zieldatei wird zum Projekt hinzugefügt, diese darf nur zu einer Liste hinzugefügt werden. Dieses Risiko kann durch die Verwendung von Variablen beseitigt werden: Variablen ermöglichen das Ersetzen einer vordefinierten Zeichenfolge an mehreren Stellen .
Im Makefile können Sie diese Zeile schreiben, um die Variable „object“ zu definieren:
objects = main.o kbd.o command.o display.o
insert.o search.o files.o utils .o
Wenn also eine Liste von Zieldateinamen benötigt wird, verwenden Sie $(object), um den Wert der Variablen zu ersetzen. Das Folgende ist das Makefile nach der Verwendung von Variablen:
objects = main.o kbd.o command.o display.o
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs .h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : suchen. c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils .o : utils.c defs.h
cc -c utils.c
clean :
rm edit $(objects)
1.6. Vereinfachte Befehle
Es ist nicht notwendig, das auszuschreiben Kompilierungsbefehl für jede Datei, da make dies selbst tun kann. Es gibt eine implizite Regel zum Aktualisieren von „.o“-Dateien mit „.c“-Dateien. Verwenden Sie den Befehl „cc -c“. Make verwendet „cc -c main.c -o main.o“, um main.c in main.o zu kompilieren, sodass der Befehl in den Regeln zum Generieren von Objektdateien weggelassen werden kann.
Wenn die „.c“-Datei auf diese Weise verwendet wird, wird sie automatisch zur Abhängigkeitsbeziehung hinzugefügt. Daher kann die „.c“-Datei aus der Abhängigkeitsbeziehung weggelassen werden, sofern der Befehl weggelassen wird. Das Folgende ist ein vereinfachtes Makefile:
objects = main.o kbd.o command.o display.o
insert.o search.o files.o utils.o edit : $(objects)
cc - o edit $(objects) main.o : defs.h
kbd.o : defs.h command.h
command.o : defs.h command.h
display.o : defs. h buffer .h
insert.o : defs.h buffer.h
search.o : defs.h buffer.h
files.o : defs.h buffer.h command.h
utils .o : defs.h
.PHONY : clean
clean :
-rm edit $(objects)
1.7. Ein anderer Stil
Wenn die Ziele im Makefile alle mit impliziten Regeln generiert werden , Regeln können nach Abhängigkeitsbeziehungen gruppiert werden:
objects = main.o kbd.o command.o display.o
insert.o search.o files.o utils.o edit : $(objects)
cc -o edit $(objects) $(objects) : defs.h
kbd.o command.o Dateien. o : command.h
display.o insert.o search.o files.o : buffer.h
Hier wird „defs.h“ als Abhängigkeit für alle Zieldateien verwendet. Ob dieser Stil gut oder schlecht ist, hängt von den persönlichen Vorlieben ab. Er ist sehr kompakt, sieht aber etwas klarer aus, wenn die abhängigen Informationen für jedes Ziel zusammen vorliegen.
1.8. Bereinigung
Schreiben Sie Regeln, damit das Programm nicht kompiliert wird. Makefiles beschreiben normalerweise, wie andere Dinge erledigt werden: z. B. das Bereinigen des Verzeichnisses durch Löschen von Objektdateien und ausführbaren Dateien im Verzeichnis. Das Beispiel ist wie folgt geschrieben:
clean:
rm edit $(objects)
Die tatsächliche Situation ist, dass wir einige unerwartete Ereignisse verarbeiten müssen: Es gibt eine Datei namens „clean“; rm macht einen Fehler und möchte nicht, dass der Make-Prozess gestoppt wird. Die geänderte Version lautet wie folgt:
.PHONY : clean
clean :
-rm edit $(objects)
Eine solche Regel kann nicht am Anfang des Makefiles platziert werden, da dies nicht das ist, was wir standardmäßig tun. Da „clean“ keine Abhängigkeit von „edit“ ist, wird diese Regel nicht ausgeführt, wenn make ohne Argumente ausgeführt wird. Um diese Regel auszuführen, muss „make clean“ ausgeführt werden.
2.Makefile
Makefile enthält fünf Arten von Inhalten: explizite Regeln, implizite Regeln, Variablendefinitionen, Anweisungen und Kommentare.
1. Explizite Regeln beschreiben, wie das Ziel der Regel generiert wird. Es listet die Dateien auf, von denen das Ziel abhängt, und gibt den Befehl zum Generieren oder Aktualisieren des Ziels an.
2 der Datei basierend auf dem Dateinamen, was darauf hinweist, dass das Ziel möglicherweise von einer Datei mit einem ähnlichen Dateinamen abhängt, und der entsprechende Befehl angegeben wird.
3. Anweisungen ähneln Compiler-Pseudoanweisungen, einschließlich:
4. Weisen Sie make an, ein anderes Makefile zu lesen
6 >7. Das „#“ in einer Zeile beginnt als Kommentar und wird bis zum Ende der Zeile fortgesetzt, sofern nicht das Zeilenfortsetzungssymbol angetroffen wird. In „define“ und commands dürfen keine Kommentare enthalten sein, andernfalls können Kommentare überall erscheinen.
2.1.makefile-Name
Make sucht standardmäßig nach Makefiles mit den folgenden Namen: „GNUmakefile“, „makefile“ und „Makefile“ (Groß- und Kleinschreibung beachten). Normalerweise sollte Ihr Makefile „makefile“ oder „Makefile“ heißen. „GNUmakefile“ wird nicht empfohlen, es sei denn, Ihr Makefile ist für GNU Make angepasst. Andere Makes betrachten den Namen nicht als den Namen eines Makefiles.
Wenn Sie ein nicht standardmäßiges benanntes Makefile verwenden, müssen Sie den Befehlsschalter „-f“ oder „--file“ verwenden. Das Argument „-f NAME“ oder „--file NAME“ weist make an, NAME als Makefile einzulesen. Wenn mehrere Schalter verwendet werden, werden alle Dateien der Reihe nach verkettet. Wenn diese Option verwendet wird, werden Standard-Makefile-Namen nicht automatisch erkannt.
2.2. Fügen Sie die
„include“-Direktive ein, um make anzuweisen, die Verarbeitung des verbleibenden Inhalts anzuhalten und andere Makefiles einzulesen. Die Syntax lautet wie folgt:
include FILENAMES...
Am Anfang dieser Zeile können Leerzeichen stehen, Tabulatorzeichen sind jedoch nicht zulässig. Wenn der Dateiname Variablen oder Funktionen enthält, werden diese erweitert.
2.3. Variable „MAKEFILE“
Wenn die Umgebungsvariable „MAKEFILE“ definiert ist, betrachtet make ihren Wert als eine Reihe von durch Leerzeichen getrennten Dateinamen, die vom Make-Programm gelesen werden, bevor andere Makefiles verarbeitet werden. Dies ähnelt der Anweisung include; Ziele in diesen Dateien haben keinen Einfluss auf die Standardziele und make betrachtet es nicht als Fehler, wenn die Datei nicht gefunden wird.
Der Hauptzweck dieser Variablen besteht darin, bei der Kommunikation rekursiv auf das Make-Programm zu verweisen
2.4 So generieren Sie das Makefile neu
Manchmal wird das Makefile aus anderen Dateien generiert, z. B. RCS- oder SCCS-Dateien. Wenn das Makefile aus anderen Dateien generiert wird, muss make die neueste Version des Makefiles lesen.
Nachdem alle Makefiles gelesen wurden, betrachtet make jedes Makefile als Ziel und versucht, es zu aktualisieren. Wenn es im Makefile eine Regel für die Aktualisierung gibt oder implizite Regeln gelten, werden die erforderlichen Aktualisierungen durchgeführt . Nachdem alle Makefiles überprüft wurden und sich welche geändert haben, startet make den Lesevorgang neu (make versucht erneut, die Aktualisierung durchzuführen, aber normalerweise ändert sich nichts mehr, da es bereits die neueste Version ist).
Wenn eine Datei die Doppelpunktregel verwendet und einen Befehl, aber keine Abhängigkeiten bereitstellt, wird die Datei immer aktualisiert. Wenn im Falle eines Makefiles das Makefile eine Doppelpunktregel hat und Befehle, aber keine Abhängigkeiten bereitstellt, wird das Makefile immer neu generiert, was zu einem Zyklus führt: make aktualisiert das Makefile einfach ständig, führt aber keine Arbeit aus. Um diese Situation zu vermeiden, generiert make keine Makefiles mit Doppelpunktregeln neu, die nur Befehle ohne Abhängigkeiten enthalten.
Wenn die Option „-f“ oder „--file“ nicht verwendet wird, versucht make den Standardnamen der Makefile-Datei. Im Gegensatz zur Angabe der Optionen „-f“ oder „--file“ kann make nicht bestimmen, ob diese Dateien vorhanden sein sollen. Wenn jedoch kein Standard-Makefile vorhanden ist, aber durch Ausführen von Make-Regeln generiert werden kann, möchten Sie möglicherweise, dass diese Regeln ausgeführt werden, damit das Makefile verwendet werden kann.
Wenn es also kein Standard-Makefile gibt, versuchen Sie, es in der Reihenfolge zu generieren, in der die Makefile-Namen nachgeschlagen werden, bis es gelingt oder keine Namen mehr vorhanden sind. Beachten Sie, dass es kein Fehler ist, wenn make kein Makefile finden oder generieren kann; ein Makefile ist nicht immer erforderlich.
Bei Verwendung der Optionen „-t“ oder „--toUCh“ ist es unerwünscht, ein veraltetes Makefile zu verwenden, um zu entscheiden, welches Ziel berührt werden soll. Die Option „-t“ hat also keine Auswirkung auf Makefile-Aktualisierungen; die Befehle „-q“ (oder „--question“) und „-n“ (oder „--just-print“) verhindern keine Makefile-Aktualisierungen, weil Veraltete Makefiles erzeugen eine falsche Ausgabe. Auf diese Weise aktualisiert „make -f mfile -n foo“ „mfile“, liest es ein, gibt die zum Aktualisieren von „foo“ erforderlichen Befehle aus, führt sie jedoch nicht aus. Die mit „foo“ verbundenen Befehle sind der Inhalt der aktualisierten „mfile“.
Aber manchmal möchten Sie das Makefile nicht aktualisieren, Sie können das Makefile als Ziel in der Befehlszeile verwenden. Wenn das Makefile explizit als Ziel angegeben wird, gilt die Option „-t“ auch für sie.
Auf diese Weise liest „make -f mfile -n mfile foo“ „mfile“ und gibt den aktualisierten Befehl aus, der ausgeführt werden soll. Der Befehl von „foo“ ist der Inhalt der aktuellen „mfile“.
2.5. Überladen von Makefiles
Sie können die Anweisung „include“ verwenden, um andere Makefiles einzuschließen und Zielvariablendefinitionen hinzuzufügen. Allerdings erlaubt make keine unterschiedlichen Befehle für dasselbe Ziel, und es gibt andere Möglichkeiten, das Ziel zu erreichen.
Angenommen, es gibt „makefile“ und „mfile“, dann sollte „makfile“ „mfile“ enthalten, aber beide haben Regeln für das Ziel „foo“. Dies ist eine Regel, die in „makefile“ geschrieben werden kann, um jedem Muster zu entsprechen. Sie gibt an, dass nach „mfile“ gesucht wird, wenn make das Ziel nicht findet:
foo:
frobnicate > 🎜>% : force
@$(MAKE) -f mfile $@
force: ;
Beim Ausführen von „make foo“ findet make „makefile“ und führt den Befehl „frobnicate >“ aus; führt „make bar“ aus, es wird keine entsprechende Regel in „makefile“ gefunden. Wenn der Befehl „make -f mfile bar“ ausgeführt wird, gelten auch andere Ziele, die nicht in „makefile“ erwähnt werden .
Diese Methode funktioniert, weil das Muster der Musterregel „%“ ist, das mit jedem Ziel übereinstimmen kann; diese Regel basiert auf „force“, was sicherstellt, dass der Befehl ausgeführt wird, auch wenn das Ziel „force“ vorhanden ist Der leere Befehl „Regel“ verhindert, dass „make“ nach impliziten Regeln dafür sucht – dies würde einen Abhängigkeitszyklus verursachen.
3. Regeln
Die Regeln im Makefile beschreiben, wie eine bestimmte Datei generiert wird, die das Ziel der Regel ist. Regeln listen die Abhängigkeitsdateien des Ziels auf und geben Befehle zum Erstellen oder Aktualisieren des Ziels an.
Die Reihenfolge der Regeln ist nicht wichtig, außer um das Standardziel zu bestimmen: Das Standardziel ist die erste Regel im ersten Makefile; wenn die erste Regel mehrere Ziele hat, ist das erste Ziel das Standardziel. Es gibt zwei Ausnahmen: Ziele, die mit „.“ beginnen, sind keine Standardziele;
Normalerweise besteht eine der Regeln, die wir schreiben, darin, das gesamte Programm oder alle im Makefile angegebenen Programme zu kompilieren.
3.1. Beispiel
foo.o : foo.c defs.h # Modul zum Twiddeln der Frobs
cc -c -g foo.c
Es zielt auf 'foo.o' ab und hängt davon ab on Für „foo.c“ und „defs.h“ gibt es den Befehl „cc -c -g foo.c“. Die Befehlszeile beginnt mit dem TAB-Zeichen, um sie als Befehl zu kennzeichnen.
Diese Regel erklärt zwei Dinge:
8. Wie man entscheidet, ob „foo.o“ alt ist: ob es nicht existiert oder ob „foo.c“ oder „defs.h“ neuer ist als es.
9. So aktualisieren Sie die Datei „foo.o“: indem Sie das Programm „cc“ ausführen. Der Befehl erwähnt „defs.h“ nicht, daher können wir davon ausgehen, dass „foo.c“ es enthält, weshalb „defs.h“ in die Abhängigkeitsbeziehung eingefügt wird.
3.2. Syntax der Regeln
Die Syntax lautet wie folgt:
TARGETS : ABHÄNGIGKEITEN
BEFEHL
...
oder
TARGETS : ABHÄNGIGKEITEN ; BEFEHL
..
TARGETS sind durch Leerzeichen getrennte Dateinamen, es können Platzhalter verwendet werden. Normalerweise hat eine Regel nur ein Ziel, gelegentlich jedoch auch mehrere Ziele.
Die Befehlszeile beginnt mit der TAB-Taste. Der erste Befehl kann in der nächsten Zeile nach der Abhängigkeitsbeziehung oder in derselben Zeile nach dem Semikolon stehen;
Da das „$“-Symbol als Variablenreferenz verwendet wird, müssen Sie zwei schreiben, wenn Sie das „$“-Symbol in einer Regel verwenden möchten: „$$“. Sie können das Symbol '' verwenden, um eine lange Zeile zu teilen. Dies ist jedoch nicht erforderlich, da make keine Begrenzung der Zeilenlänge hat.
3.3. Platzhalterzeichen
Der Dateiname in der Regel kann Platzhalterzeichen wie „*“, „?“ enthalten.
Das Zeichen „~“ vor dem Dateinamen hat eine besondere Bedeutung. Wenn es allein oder gefolgt von einem „/“ verwendet wird, stellt es das Home-Verzeichnis des Benutzers dar. „~/bin“ wird beispielsweise zu „/home/you/bin“ erweitert. Wenn auf „~“ ein Wort folgt, stellt es das dar Home-Verzeichnis des durch das Wort angegebenen Benutzers. Beispielsweise wird „~john/bin“ zu „/home/john/bin“ erweitert.
Platzhalter werden in Zielen, Abhängigkeiten und Befehlen automatisch erweitert. In anderen Fällen werden Platzhalter erweitert, es sei denn, die Funktion „Platzhalter“ wird explizit verwendet. Die Sonderbedeutung von Wildcard-Zeichen kann mit dem ''-Symbol abgeschlossen werden.
Beispiel:
clean:
rm -f *.o
und
print: *.c
lpr -p $?
touch print
Wildcard in der Definition Variablen werden nicht erweitert, zum Beispiel:
objects = *.o
dann ist der Wert von Objekten die Zeichenfolge „*.o“, aber wenn Sie Objekte in einem Ziel, einer Abhängigkeit oder einem Befehl verwenden, erfolgt eine Erweiterung. Um Objekte auf erweiterten Inhalt festzulegen, verwenden Sie:
objects := $(wildcard *.o)
3.3.1 Defekte von Platzhaltern
Dies ist ein Beispiel für die Verwendung von Platzhaltern, aber das Ergebnis entspricht nicht Ihren Erwartungen. Angenommen, die ausführbare Datei „foo“ wird aus allen „.o“-Dateien im aktuellen Verzeichnis generiert:
objects = *.o foo : $(objects)
cc -o foo $(CFLAGS) $(objects )
Der Wert der Objektvariablen ist die Zeichenfolge „*.o“. Die Platzhaltererweiterung erfolgt in der Regel „foo“, sodass alle vorhandenen „.o“-Dateien von „foo“ abhängig werden und bei Bedarf neu kompiliert werden.
Aber was ist, wenn alle „.o“-Dateien gelöscht werden? Wenn der Platzhalter mit keiner Datei übereinstimmt, bleibt alles wie es ist: Dann hängt „foo“ von einer Datei namens „*.o“ ab, da diese Datei wahrscheinlich nicht existiert. Das Programm „make“ meldet, dass es „*.o“ nicht generieren kann. o' 'Fehler in der Datei, dies ist nicht das erwartete Ergebnis.
Es ist tatsächlich möglich, mit Platzhaltern die gewünschten Ergebnisse zu erzielen, erfordert jedoch komplexe Techniken, einschließlich der Funktion „Platzhalter“ und der Funktion zum Ersetzen von Zeichenfolgen.
3.3.2.Wildcard-Funktion
Wildcards werden automatisch in Regeln ausgeführt. Allerdings werden Platzhalter in Variablenzuweisungen und Funktionsargumenten nicht erweitert. Wenn in diesen Fällen eine Platzhaltererweiterung erforderlich ist, muss die Funktion „Platzhalter“ verwendet werden. Die Syntax lautet wie folgt:
$(wildcard PATTERN...)
Diese Zeichenfolge, die irgendwo im Makefile erscheint, wird durch eine durch Leerzeichen getrennte Liste vorhandener Dateien ersetzt, die einem beliebigen Dateinamenmuster entsprechen. Wenn keine Datei mit einem Muster übereinstimmt, wird das Muster bei der Ausgabe von „Wildcard“ ignoriert. Beachten Sie, dass sich dies von der oben beschriebenen Wildcard-Verarbeitung unterscheidet.
Eine Funktion der „Wildcard“-Funktion besteht darin, alle „.c“-Dateien im Verzeichnis zu finden:
$(wildcard *.c)
Sie können das Suffix „.c“ durch „.o“ ersetzen ' aus der C-Dateiliste ruft die Liste der Zieldateien ab:
$(patsubst %.c,%.o,$(wildcard *.c))
Auf diese Weise wird das Makefile im vorherigen Abschnitt umgeschrieben als :
objects := $(patsubst %.c,%.o,$(wildcard *.c)) foo : $(objects)
cc -o foo $(objects)
Dieses Makefile nutzt die impliziten Regeln zum Kompilieren von C-Programmen, sodass keine expliziten Regeln für die Kompilierung geschrieben werden müssen. („:=“ ist eine Variante von „=“)
Hinweis: Bei „PATTERN“ muss die Groß-/Kleinschreibung beachtet werden.
3.4. Verzeichnissuche
Bei großen Systemen werden Quelldateien und Zieldateien normalerweise in unterschiedlichen Verzeichnissen abgelegt. Mit der Verzeichnissuchfunktion kann make automatisch nach abhängigen Dateien in mehreren Verzeichnissen suchen. Wenn Sie Dateien neu verteilen, müssen Sie die Regeln nicht ändern, sondern nur den Suchpfad.
3.4.1. „VPATH“
Die Make-Variable „VPATH“ listet die Verzeichnisliste auf, die make durchsuchen soll. In vielen Fällen enthält das aktuelle Verzeichnis keine abhängigen Dateien und „VPATH“ beschreibt eine Suchliste aller Dateien, einschließlich derjenigen, die das Ziel der Regel sind.
Wenn eine Ziel- oder abhängige Datei nicht im aktuellen Verzeichnis gefunden wird, sucht „make“ nach einer Datei mit demselben Namen in dem in „VPATH“ aufgeführten Verzeichnis. Wenn diese Datei gefunden wird, wird sie zu einer abhängigen Datei; Regeln können die Dateien so verwenden, als ob sie sich im aktuellen Verzeichnis befänden.
In der Variablen „VPATH“ werden Verzeichnisnamen durch Doppelpunkte oder Leerzeichen getrennt. Die Reihenfolge, in der die Verzeichnisse aufgelistet sind, bestimmt die Reihenfolge, in der make-Suchen durchgeführt werden. (Hinweis: Die GNU-Make-Verzeichnisnamen, die in pSOSystem 2.5 nach Win32 übertragen werden, müssen durch Semikolons getrennt werden, im Folgenden als Win32-GNU-Make bezeichnet.) Zum Beispiel: VPATH = src:../headers, dann wird die Regel
foo.o : foo.c
als
foo.o : src/foo.c
interpretiert, wobei „foo.c“ angenommen wird ' Es existiert nicht im aktuellen Verzeichnis und kann im Verzeichnis „src“ gefunden werden.
3.4.2. Selektive Suche
Ähnlich wie die Variable „VPATH“, aber selektiver ist die Direktive „vpath“ (beachten Sie, dass sie in Kleinbuchstaben geschrieben ist), die den Suchpfad für Dateien angeben kann, die einem bestimmten Muster entsprechen. Dadurch können Sie unterschiedliche Suchpfade für verschiedene Dateitypen angeben.
Die 'vpath'-Direktive hat drei Formen:
10.'vpath PATTERN DirectorIES'
Geben Sie den Suchpfad DIRECTORIES für Dateinamen an, die mit PATTERN übereinstimmen. Die Aufteilung der Verzeichnisse ist dieselbe wie bei '. VPATH'
11.'vpath PATTERN'
Löschen Sie den angegebenen Suchpfad für Dateinamen, die mit PATTERN übereinstimmen
12.'vpath'
Löschen Sie alle zuvor mit 'vpath' angegebenen Suchpfade
'vpath ' Das Muster ist eine Zeichenfolge, die „%“ enthält: Diese Zeichenfolge muss mit dem zu durchsuchenden Dateinamen übereinstimmen, und das Zeichen „%“ entspricht 0 oder mehr beliebigen Zeichen. Beispiel: „%.h“ entspricht jeder Datei, die mit „.h“ endet (wenn kein % vorhanden ist, muss das MUSTER genau mit der abhängigen Datei übereinstimmen, was nicht häufig verwendet wird).
Wenn im aktuellen Verzeichnis keine abhängige Datei vorhanden ist und das MUSTER in „vpath“ mit dem Namen der abhängigen Datei übereinstimmt, werden die in VERZEICHNISSE im Befehl aufgeführten Verzeichnisse genauso verarbeitet wie in „VPATH“. Beispiel:
vpath %.h ../headers
weist make an, nach „.h“-Dateien zu suchen, die im aktuellen Verzeichnis im Verzeichnis ../headers nicht gefunden werden.
Wenn mehrere „vapth“-Musterübereinstimmungen auf Dateinamen basieren, verarbeitet make sie einzeln und durchsucht alle angegebenen Verzeichnisse. Machen Sie Prozesse zu „vapth“ in der Reihenfolge, in der sie im Makefile erscheinen; mehrere „vapth“ des gleichen Modus sind unabhängig voneinander.
vpath %.c foo
vpath % blish
vpath %.c bar
sucht nach der Datei „.c“ in der Reihenfolge „foo“, „blish“, „bar“. Und
vpath %.c foo:bar
vpath % blish
sucht in der Reihenfolge „foo“, „bar“, „blish“.
3.4.3. Verwendung automatischer Variablen
Die Ergebnisse der Verzeichnissuche ändern die Befehle in der Regel nicht: Die Befehle werden unverändert ausgeführt. Daher müssen Sie Befehle schreiben, die für Verzeichnissuchfunktionen geeignet sind. Dies kann durch die Verwendung automatischer Variablen wie „$^“ erfolgen. „$^“ stellt alle abhängigen Dateien in der Regel dar, einschließlich der Verzeichnisnamen, in denen sie sich befinden (siehe Verzeichnissuche); „$@“ stellt das Ziel dar. Zum Beispiel:
foo.o : foo.c
cc -c $(CFLAGS) $^ -o $@
Normalerweise enthält die abhängige Datei auch Header-Dateien, diese werden jedoch in nicht erwähnt der Befehl Datei: Die Variable '$<' stellt die erste abhängige Datei dar:
VPATH = src:../headers
foo.o : foo.c defs.h hack.h
cc –c $( CFLAGS) $< -o $@
3.4.4. Die Angabe der Verzeichnissuche mit „VPATH“ und „vpath“ wirkt sich auch auf implizite Regeln aus. Beispiel: Die Datei „foo.o“ hat keine expliziten Regeln, make berücksichtigt die impliziten Regeln: Wenn „foo.c“ existiert, kompilieren Sie sie, wenn die Datei nicht existiert, suchen Sie im entsprechenden Verzeichnis; c'' ' in einem beliebigen Verzeichnis vorhanden ist, werden die impliziten Regeln der C-Kompilierung angewendet.
Bei Befehlen mit impliziten Regeln ist es häufig erforderlich, automatische Variablen zu verwenden, damit durch eine Verzeichnissuche ermittelte Dateinamen ohne zusätzlichen Aufwand verwendet werden können.
3.5.PHONY-Ziel
Das Phony-Ziel ist kein tatsächlicher Dateiname, sondern nur der Name des Befehls, der bei expliziter Anforderung ausgeführt werden soll. Es gibt zwei Gründe für die Verwendung gefälschter Ziele: um Konflikte mit gleichnamigen Dateien zu vermeiden und um die Leistung zu verbessern.
Wenn Sie eine Regel schreiben, die keine Zieldatei generiert, wird der entsprechende Befehl jedes Mal ausgeführt, wenn das Ziel erstellt wird. Zum Beispiel:
clean:
rm *.o temp
Da der Befehl „rm“ keine „clean“-Datei generiert, wird dieser Befehl jedes Mal ausgeführt, wenn „make clean“ ausgeführt wird. Wenn eine „saubere“ Datei im Verzeichnis erscheint, ist die Regel ungültig: Es gibt keine abhängige Datei, die Datei „sauber“ ist immer die neueste und der Befehl wird niemals ausgeführt. Um dieses Problem zu vermeiden, verwenden Sie „.PHONY“. um das Ziel festzulegen. Zum Beispiel:
.PHONY : clean
Wenn Sie „make clean“ auf diese Weise ausführen, wird ignoriert, ob die „clean“-Datei vorhanden ist oder nicht.
Es ist bekannt, dass das falsche Ziel keine tatsächliche Datei ist, die von anderen Dateien generiert wurde, und make überspringt die implizite Regelsuche. Aus diesem Grund verbessert die Angabe eines falschen Ziels die Leistung, auch wenn Sie sich keine Sorgen darüber machen, ob die tatsächliche Datei vorhanden ist oder nicht. Das vollständige Beispiel lautet wie folgt:
.PHONY : clean
clean :
rm *.o temp
Phony Target sollte sich nicht auf die echte Zieldatei verlassen. Wenn ja, wird der Befehl jedes Mal ausgeführt, wenn make diese Datei aktualisiert. Solange das falsche Ziel nicht vom realen Ziel abhängig ist, werden die Befehle der Regel nur ausgeführt, wenn dieses Ziel angegeben ist.
Falsche Ziele können Abhängigkeiten haben. Wenn sich in einem Verzeichnis mehrere Programme befinden, ist es bequemer, sie in einem Makefile abzulegen. Da das Standardziel das erste Ziel im Makefile ist, wird dieses falsche Ziel normalerweise „all“ genannt und seine abhängigen Dateien sind jedes Programm:
all : prog1 prog2 prog3
.PHONY : all
prog1 : prog1.o utils.o
cc -o prog1 prog1.o utils.o
prog2 : prog2.o
cc -o prog2 prog2.o
prog3 : prog3.o sort .o utils. o
cc -o prog3 prog3.o sort.o utils.o
Auf diese Weise werden durch die Verwendung von „make“ alle drei Programme generiert.
Wenn ein falsches Ziel eine Abhängigkeit von einem anderen ist, entspricht seine Funktion einer Unterroutine, zum Beispiel:
.PHONY: cleanall cleanobj cleandiff
cleanall : cleanobj cleandiff
rm program
cleanobj :
rm *.o
cleandiff :
rm *.diff
3.6.FORCE target
Wenn eine Regel keine Abhängigkeiten und keinen Befehl hat und ihr Ziel kein vorhandener Dateiname ist, machen Sie betrachtet diese Regel als ausgeführt. Dieses Ziel wird immer aktualisiert. Das heißt, wenn eine Regel auf dieses Ziel angewiesen ist, werden ihre Befehle immer ausgeführt.
clean: FORCE
rm $(objects)
FORCE:
Im Beispiel erfüllt das Ziel „FORCE“ diese außergewöhnliche Bedingung, sodass das davon abhängige Ziel „clean“ dazu gezwungen wird seinen Befehl ausführen. Der Name „FORCE“ hat keine besondere Bedeutung, er wird nur häufig verwendet. Die Verwendung von „FORCE“ auf diese Weise hat den gleichen Effekt wie „.PHONY: clean“. Die Verwendung von „.PHONY“ ist klarer und effizienter, aber nicht alle „Marken“ unterstützen es, so dass viele Makefiles „FORCE“ verwenden.
3.7. Leeres Ziel
Ein leeres Ziel ist eine Variante des falschen Ziels: eine Aktion, die zum Ausführen einer expliziten Anfrage verwendet wird. Der Unterschied zum falschen Ziel besteht darin, dass diese Zieldatei tatsächlich existieren kann. Der Inhalt der Zieldatei ist irrelevant und normalerweise leer. Der Zweck der leeren Zieldatei besteht darin, anhand ihrer letzten Änderung den Zeitpunkt der letzten Befehlsausführung aufzuzeichnen. Dies wird durch die Aktualisierung der Zieldatei mit dem Befehl „touch“ erreicht.
print: foo.c bar.c
lpr -p $?
touch print
Mit dieser Regel wird bei der Ausführung von „make print“ festgestellt, ob sich eine Datei seit dem letzten „make print“ geändert hat, Der Befehl „lpr“ wird ausgeführt. Die automatische Variable „$?“ wird verwendet, um nur die Dateien auszudrucken, die sich geändert haben.
3.8. Eingebaute außergewöhnliche Ziele
Bestimmte Namen haben außergewöhnliche Bedeutungen, wenn sie als Ziele existieren.
13..PHONY Die Abhängigkeiten dieses Ziels werden als falsche Ziele betrachtet. Bei der Verarbeitung dieser Ziele wird der Befehl bedingungslos ausgeführt, unabhängig davon, ob der Dateiname existiert oder wann er zuletzt geändert wurde
14. .SUFFIXES dieser Ziel-Reliance wird als Suffixliste betrachtet. Verwenden Sie
, wenn Sie Suffixregeln überprüfen15..DEFAULT Die Regeln für dieses Ziel werden auf Ziele ohne Regeln (explizit oder implizit) angewendet. Wenn der Befehl „DEFAULT“ definiert ist, wird dieser Befehlssatz für alle abhängigen Dateien ausgeführt, die keine Regelziele sind
16..PRECIOUS Die abhängigen Dateien dieses Ziels erhalten eine Sonderbehandlung: wenn make beendet wird oder die Ausführung Wenn der Befehl unterbrochen wird, werden diese Ziele nicht gelöscht. Wenn es sich bei dem Ziel um eine Zwischendatei handelt, wird sie nicht gelöscht, wenn sie nicht mehr benötigt wird. Das Zielmuster impliziter Regeln (z. B. %.o) kann als abhängige Datei von „.PRECIOUS“ verwendet werden, sodass die durch diese Regeln generierten Zwischendateien gespeichert werden können.
17..INTERMEDIATE Die abhängigen Dateien dieses Ziels gelten als Zwischendateien. Wenn das Ziel keine abhängigen Dateien hat, gelten alle Zieldateien im Makefile als Zwischendateien.
18..IGNORE Wenn Befehle ausgeführt werden, die auf Regeln für dieses Ziel basieren, ignoriert make Fehler. Der Befehl selbst ist bedeutungslos. Wenn die Regel keine Abhängigkeiten aufweist, bedeutet dies, dass Fehler in allen Befehlsausführungen ignoriert werden, da sie sich auf alle Befehle auswirkt. Es wird nicht empfohlen, andere, selektivere Methoden zum Ignorieren zu verwenden Fehler.
19..SILENT Beim Ausführen eines regelabhängigen Befehls für dieses Ziel gibt make den Befehl selbst nicht aus. Der Befehl der Regel ergibt keinen Sinn. Wenn „.SILIENT“ keine Abhängigkeiten aufweist, bedeutet dies, dass bei der Ausführung nicht alle Befehle im Makefile gedruckt werden. Diese Regel dient nur der Abwärtskompatibilität.
20..EXPORT_ALL_VARIABLES existiert nur als Ziel und weist make an, alle Variablen an den untergeordneten Prozess auszugeben.
Wenn das Suffix einer definierten impliziten Regel als Ziel verwendet wird, gilt es auch als außergewöhnliches Ziel; dasselbe gilt für die Verbindung zweier Suffixe, wie z. B. „.c.o“. Bei diesen Zielen handelt es sich um Suffixregeln, eine veraltete (aber immer noch weit verbreitete) Methode zur Definition impliziter Regeln. Das Suffix beginnt normalerweise mit „.“, daher beginnen auch außergewöhnliche Ziele mit „.“
3.9. Eine Regel mit mehreren Zielen
Eine Regel mit mehreren Zielen hat die gleiche Wirkung wie das Schreiben mehrerer Regeln mit jeweils einem Ziel. Der gleiche Befehl gilt für alle Ziele, seine Wirksamkeit variiert jedoch, indem das tatsächliche Ziel durch „$@“ ersetzt wird. Die Abhängigkeiten aller Ziele in den Regeln sind gleich.
Dies ist in zwei Situationen nützlich:
★ Nur Abhängigkeiten, keine Befehle erforderlich. Zum Beispiel:
kbd.o command.o files.o: command.h
21. Alle Ziele haben den gleichen Befehl. Die Befehle müssen nicht genau gleich sein, da „$@“ im folgenden Befehl verwendet werden kann:
bigoutput littleoutput : text.g
generate text.g -$(subst output,,$@) > ; $@
Entspricht
bigoutput : text.g
generate text.g -big > bigoutput
littleoutput : text.g
generate text.g -little > >. Hierbei wird davon ausgegangen, dass das Programm „generate“ zwei Ausgaben erzeugt: eine mit der Option „-big“ und eine mit der Option „-little“. Wenn Sie sich vorstellen, die Abhängigkeitsbeziehung mit dem Änderungsbefehl „$@“ zu ändern, kann dies nicht durch gewöhnliche Regeln mit mehreren Zielen erreicht werden, sondern durch Musterregeln.
3.10. Mehrere Regeln für ein Ziel
Eine Datei kann das Ziel mehrerer Regeln sein und die Abhängigkeiten aller Regeln werden zusammengeführt. Wenn das Ziel älter ist als eine der abhängigen Dateien, wird der Befehl ausgeführt.
In einer Datei kann nur ein Befehlssatz ausgeführt werden. Wenn mehrere Regeln Befehle für dieselbe Datei erteilen, verwendet make die letzte Gruppe und gibt eine Fehlermeldung aus (Ausnahme: Wenn der Dateiname mit „.“ beginnt, wird keine Fehlermeldung gedruckt. Dies dient der Kompatibilität mit anderen make ). Es gibt keinen Grund, das Makefile so zu schreiben, weshalb make die Fehlermeldung ausgibt.
Eine zusätzliche Regel mit nur Abhängigkeitsbeziehungen kann zusätzliche Abhängigkeitsdateien für viele Dateien gleichzeitig bereitstellen. Beispielsweise repräsentiert die Variable „objects“ die gesamte Ausgabe des Compilers im System. Eine einfache Möglichkeit zu veranschaulichen, dass alle Dateien neu erstellt werden müssen, wenn sich „config.h“ ändert, ist wie folgt:
objects = foo.o bar .o
foo. o : defs.h
bar.o : defs.h test.h
$(objects) : config.h
Es besteht keine Notwendigkeit, die tatsächliche Zieldateigenerierung zu ändern Regeln können bei Bedarf hinzugefügt oder gelöscht werden. Ein weiterer Trick besteht darin, dass zusätzliche Abhängigkeiten durch Variablen dargestellt werden können. Wenn make ausgeführt wird, können Variablen Werte zugewiesen werden:
extradeps=
$(objects) : $(extradeps)
Wenn der Befehl `make extradeps= foo.h‘ wird als ‚foo.h‘ als abhängige Datei für jede Objektdatei ausgeführt, was beim einfachen ‚make‘-Befehl jedoch nicht der Fall ist.
3.11. Statische Musterregeln
Statische Musterregeln können mehrere Ziele angeben und den Zielnamen verwenden, um den Namen der abhängigen Datei allgemeiner vorzuschlagen als gewöhnliche Regeln für mehrere Ziele, da dies nicht erforderlich ist das Gleiche von: Abhängigkeiten müssen ähnlich, aber nicht unbedingt identisch sein.
3.11.1. Syntax
TARGETS ...: TARGET-PATTERN: DEP-PATTERNS ...
COMMANDS
...
TARGETS-Liste gibt das Ziel der Regelanwendung an und kann enthalten Platzhalter, was das gleiche Ziel hat wie die normalen Regeln. TARGET-PATTERN und DEP-PATTERNS geben an, wie die Abhängigkeitsbeziehung des Ziels berechnet wird: Das mit TARGET-PATTERN übereinstimmende Ziel extrahiert einen Teil des Namens, den sogenannten Stamm (Stamm), und der Stamm wird durch DEP-PATTERNS ersetzt, um den zu bilden Name der Abhängigkeitsdatei.
Jedes Muster enthält normalerweise ein „%“-Zeichen. Wenn TARGET-PATTERN mit einem Ziel übereinstimmt, kann das Zeichen „%“ mit jedem Teil des Zielnamens übereinstimmen; dieser Teil ist der Stamm, und der Rest des Musters muss genau übereinstimmen. Beispielsweise stimmt „foo.o“ mit „%.o“ überein, was der Stamm ist; die Ziele „foo.c“ und „foo.out“ stimmen nicht mit diesem Muster überein.
Der Name der Abhängigkeitsdatei des Ziels wird durch Ersetzen von „%“ in DEP-PATTERNS durch den Stamm gebildet: Wenn das Abhängigkeitsmuster „%.c“ lautet, kann das Ersetzen des Stamms „foo“ zu „foo.c“ führen. Es ist auch zulässig, wenn das Abhängigkeitsmuster „%“ nicht enthält und diese Abhängigkeitsdatei für alle Ziele gültig ist.
Wenn Sie das Zeichen „%“ in einer Musterregel verwenden müssen, müssen Sie das Zeichen „“ davor hinzufügen. Wenn das Zeichen „“ vor „%“ sinnvoll ist, müssen Sie davor das Zeichen „“ hinzufügen „Andere“ „Das muss nicht so sein.“ Beispielsweise wird „the%weird%pattern“ von „the%weird“ vorangestellt und gefolgt von „pattern“. Das letzte „“ bleibt unverändert, da es das „%“-Zeichen nicht beeinflusst.
Das folgende Beispiel kompiliert „foo.o“ und „bar.o“ aus den entsprechenden „.c“-Dateien:
objects = foo.o bar.o
$(objects): %.o: % .c
$(CC) -c $(CFLAGS) $< -o $@
Jedes Ziel muss mit dem Zielmuster übereinstimmen und bei nicht übereinstimmenden Zielen wird eine Warnung ausgegeben. Wenn nur einige Dateien in der Liste mit dem Muster übereinstimmen, können Sie die Filterfunktion verwenden, um nicht übereinstimmende Dateinamen zu entfernen:
files = foo.elc bar.o lose.o $(filter %.o,$(files )) : %.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
$(filter %.elc,$(files)): %.elc: %.el
emacs -f batch-byte-compile $<
Im Beispiel „$(filter %.o,$(files))“ ist das Ergebnis „bar.o lose.o“; $(filter % .elc,$(files))‘ ergibt „foo.elc“. Das folgende Beispiel veranschaulicht die Verwendung von „$*“:
bigoutput littleoutput : %output : text.g
generate text.g -$* > „$*“ Erweitert sich zum Stamm „big“ oder „little“.
3.11.2. Statische Musterregeln und implizite Regeln haben als Musterregeln viel gemeinsam. Der Unterschied besteht darin, dass sie auf Dateinamen basieren Methode zur Entscheidung, wann eine Regel angewendet werden soll.
Implizite Regeln können auf jedes Ziel angewendet werden, das seinem Muster entspricht, jedoch nur für Ziele ohne einen angegebenen Befehl. Wenn mehrere anwendbare implizite Regeln vorhanden sind, wird je nach Reihenfolge der Regeln nur eine verwendet.
Umgekehrt gelten Regeln im statischen Modus für die explizite Liste von Zielen in der Regel, nicht für andere Ziele und gelten immer für jedes angegebene Ziel. Wenn es zwei widersprüchliche Regeln gibt und beide über Befehle verfügen, ist dies ein Fehler.
Die Vorteile statischer Modusregeln gegenüber impliziten Regeln sind wie folgt:
22. Implizite Regeln können für einige Dateien überschrieben werden, die nicht syntaktisch klassifiziert, aber explizit aufgelistet werden können.
Der Inhalt von Verzeichnissen kann nicht ermittelt werden Der genaue Inhalt einiger fremder Dateien kann dazu führen, dass make die falschen impliziten Regeln anwendet; das Endergebnis kann von der Reihenfolge der impliziten Regeln abhängen. Bei der Anwendung statischer Musterregeln besteht diese Unsicherheit nicht: Die Regeln gelten für klar festgelegte Ziele.
3.12. Doppelpunktregeln
Auf das Ziel von Doppelpunktregeln folgt „::“ anstelle von „:“. Wenn ein Ziel in mehreren Regeln vorkommt, ist seine Verarbeitung die gleiche wie bei normalen Regeln . werden unterschiedlich gehandhabt.
Wenn ein Ziel in mehreren Regeln vorkommt, müssen alle Regeln vom gleichen Typ sein: alle einfach oder alle mit Doppelpunkt. Wenn es sich um einen Doppelpunkt handelt, sind die Regeln unabhängig voneinander. Wenn das Ziel aktualisiert werden muss, kann es sein, dass der Befehl der Regel nicht ausgeführt wird oder dass einige davon oder alle ausgeführt werden Die Regeln werden ausgeführt.
Die Tatsache, dass Doppelpunktregeln für dasselbe Ziel vollständig isoliert sind, wird jede Regel separat verarbeitet, genau wie die Regeln für verschiedene Ziele. Die wahre Bedeutung solcher Regeln Diese sind für die Reihenfolge der Befehlsausführung irrelevant.
Diese Regel ist manchmal unklar, aber nicht sehr nützlich. Sie bietet einen Mechanismus zur unterschiedlichen Behandlung von Zielen, indem sie sich auf Dateiaktualisierungen verlässt, was selten vorkommt. Jede dieser Regeln sollte den Befehl bereitstellen; andernfalls wird die entsprechende implizite Regel verwendet.
3.13. Abhängigkeiten automatisch generieren
Im Makefile gibt es viele Regeln, dass einige Zieldateien von einigen Headerdateien abhängen. Beispiel: „main.c“ verwendet „defs.h“ über „#include“, daher weist die Regel:
main.o: defs.h
make an, „main.o“ zu aktualisieren, wenn „defs.h“. 'Änderungen'. Wenn das Programm relativ groß ist, müssen viele solcher Regeln geschrieben werden und das Makefile muss jedes Mal sorgfältig aktualisiert werden, wenn „#include“ hinzugefügt oder gelöscht wird. Viele moderne Compiler können diese Regeln für Sie schreiben, normalerweise geschieht dies über die Option „-M“ des Compilers. Der Befehl:
cc -M main.c
gibt beispielsweise Folgendes aus:
main.o : main.c defs.h
Auf diese Weise müssen Sie diese Regeln nicht schreiben, der Compiler erledigt das für Sie.
Beachten Sie, dass „main.o“, das in einer solchen Abhängigkeitsbeziehung erwähnt wird, von der impliziten Regel nicht als Zwischendatei betrachtet wird, was bedeutet, dass make sie nach der Verwendung nicht löscht. Bei Verwendung des alten Programms „make“ besteht die übliche Praxis darin, den Befehl „make depend“ zu verwenden, um die Funktion des Compilers zum Generieren von Abhängigkeiten zu verwenden. Dieser Befehl generiert eine „depend“-Datei, die alle automatisch generierten Abhängigkeiten enthält, und verwendet dann „include“. ', um es einzulesen.
Bei Verwendung von GNUs Make macht die Möglichkeit, Makefiles neu zu generieren, diese Praxis überflüssig: Es gibt nie eine explizite Anforderung zum Aktualisieren von Abhängigkeiten, da veraltete Makefiles immer neu generiert werden.
Der empfohlene Ansatz für die automatische Abhängigkeitsgenerierung besteht darin, für jede Quelldatei ein Makefile zu erstellen. Für jede Quelldatei „NAME.c“ gibt es ein Makefile „NAME.d“, das alle Dateien auflistet, von denen die Zieldatei „NAME.o“ abhängt, sodass dies bei einer Aktualisierung der Quelldatei der Fall sein muss gescannt, um neue Abhängigkeiten zu generieren. Ein Beispiel ist eine Musterregel, die die Abhängigkeitsdatei „NAME.d“ aus „NAME.c“ generiert:
%.d: %.c
$(SHELL) -ec '$(CC) -M $( CPPFLAGS) $<
sed '''s/($*).o[ :]*/1 $@/g''' > Wenn der Befehl fehlschlägt (Exit-Status ist nicht 0), wird die Shell sofort beendet. Normalerweise ist der Rückgabewert der Shell der Rückgabewert des letzten Befehls (sed) in der Pipeline, sodass make den Compilerfehler nicht bemerkt.
Bei Verwendung des GNU C-Compilers (gcc) können Sie die Option „-MM“ anstelle der Option „-M“ verwenden und so die Abhängigkeit von der System-Header-Datei weglassen. Der Zweck des Befehls „sed“ besteht darin,
main.o : main.c defs.h
in
main.o main.d : main.c defs.h
umzuwandeln, sodass jeweils „Die .d“-Datei hängt von der entsprechenden Quelldatei und der Header-Datei der „.o“-Datei ab, und make kann die abhängigen Beziehungsdateien aktualisieren, wenn sich der Originaltext oder die Header-Datei ändert.
Wenn die Regeln zum Generieren von „.d“-Dateien definiert sind, können Sie mit der „include“-Direktive alle Dateien einlesen:
sources = foo.c bar.c
include $(sources:. c= .d)
In diesem Beispiel werden Substitutionsvariablen verwendet, um die Quelldateiliste „foo.c bar.c“ in eine Liste abhängiger Beziehungsdateien zu konvertieren. Da „.d“-Dateien wie andere Dateien sind und keine weitere Arbeit erfordern, werden sie von make bei Bedarf neu generiert.
4. Befehle schreiben
Die Befehle der Regeln bestehen aus Shell-Befehlen, die einzeln ausgeführt werden. Zusätzlich zu Befehlen, die nach durch Semikolon getrennten Abhängigkeiten geschrieben werden, muss jede Befehlszeile mit einem Tabulatorzeichen beginnen. Eine Leerzeile und eine Kommentarzeile können in der Befehlszeile erscheinen und werden während der Verarbeitung ignoriert (Hinweis: eine Leerzeile, die mit einem Tabulatorzeichen beginnt). ist nicht Die 'leere' Zeile ist ein leerer Befehl).
Im Befehl kann jedes Programm verwendet werden, diese Programme werden jedoch von $(SHELL) ausgeführt.
4.1. Echo
Normalerweise gibt make den auszuführenden Befehl aus, der als Echo bezeichnet wird. Dies ist das gleiche Phänomen, als würde man den Befehl selbst eingeben. Wenn einer Zeile ein „@“-Zeichen vorangestellt ist, wird der Befehl nicht mehr wiederholt und das „@“-Zeichen wird verworfen, bevor es an die Shell übergeben wird. Die typische Verwendung gilt nur für Druckbefehle, wie zum Beispiel den Befehl „echo“:
@echo About to make distribution files
Wenn make die Option „-n“ oder „--just-print“ verwendet, wird angezeigt, was wird alles passieren, aber der Befehl wird nicht ausgeführt. Nur in diesem Fall wird die Kommandozeile auch dann noch angezeigt, wenn der Befehl mit „@“ beginnt. Diese Option ist nützlich, um zu sehen, was make tatsächlich tut.
Die Option „-s“ oder „--silent“ verhindert alle Echos von make, genau wie alle Befehle, die mit „@“ beginnen; eine „.SILENT“-Regel ohne Abhängigkeiten hat den gleichen Effekt, aber „@“ ist mehr flexibel.
4.2. Ausführung
Wenn Sie einen Befehl ausführen müssen, um das Ziel zu aktualisieren, erstellt make für jede auszuführende Zeile eine Subshell. Dies bedeutet, dass Shell-Befehle wie „cd“, die lokale Variablen für einen Prozess festlegen (das aktuelle Verzeichnis des Prozesses ändern), keine Auswirkungen auf nachfolgende Befehle haben. Wenn Sie „cd“ benötigen, um den nächsten Befehl zu beeinflussen, fügen Sie sie durch Semikolons getrennt in eine Zeile ein, sodass make denkt, es handele sich um einen an das Shell-Programm übergebenen Befehl (Hinweis: Dies erfordert Shell-Unterstützung):
foo : bar/ lose
gobble lose > Eine andere Form verwendet das Zeilenfortsetzungszeichen:
foo : bar/lose
gobble lose ../ foo
Der Name des Shell-Programms wird über die Variable „SHELL“ ermittelt.
(*UNIX) Im Gegensatz zu den meisten Variablen wird die Variable „SHELL“ nicht durch die Umgebung festgelegt (das heißt, sie muss im Makefile festgelegt werden), da die Umgebung „SHELL“ eine persönliche Entscheidung ist, und wenn sie anders ist Die Entscheidungen der Leute wirken sich auf das Makefile aus. Was die Funktionalität betrifft, ist das schrecklich.
4.3. Parallele Ausführung
GNU make kann mehrere Befehle gleichzeitig ausführen. Normalerweise führt make jeweils einen Befehl aus, wartet auf seine Rückkehr und führt dann den nächsten aus. Verwenden Sie „-j“ oder „--jobs“, um mehrere Befehle gleichzeitig auszuführen. Wenn nach „-j“ eine positive Zahl steht, gibt sie die Anzahl der Befehle an, die gleichzeitig ausgeführt werden können. Wenn nach „-j“ kein Parameter steht, gibt es keine Begrenzung für die Anzahl der ausführbaren Befehle . Die Standardzahl ist eins.
Ein ärgerliches Problem besteht darin, dass bei der gleichzeitigen Ausführung mehrerer Befehle deren Ausgabe vermischt wird. Ein weiteres Problem besteht darin, dass zwei Prozesse keine Eingaben vom selben Gerät erhalten können.
4.4. Fehler
Wenn jeder Shell-Befehl zurückkehrt, überprüft make seinen Rückgabestatus. Wenn der Befehl erfolgreich ausgeführt wurde, wird der nächste Befehl ausgeführt. Nach der Ausführung des letzten Befehls endet die Regelausführung.
Wenn ein Fehler auftritt (gibt einen Status ungleich Null zurück), verwirft make die aktuelle Regel und möglicherweise alle Regeln.
Manchmal stellen Befehlsausführungsfehler kein Problem dar, z. B. die Verwendung des Befehls „mkdir“, um sicherzustellen, dass das Verzeichnis vorhanden ist: Wenn das Verzeichnis vorhanden ist, meldet „mkdir“ einen Fehler, Sie möchten jedoch trotzdem, dass make fortfährt.
Um Fehler mit einem Befehl zu ignorieren, verwenden Sie das Zeichen „-“ vor dem Befehl. Das Zeichen „-“ wird verworfen, bevor es an die Shell übergeben wird:
clean:
-rm -f *.o
Bei Verwendung mit der Option „-i“ oder „--ignore-errors“ ignoriert make Fehler, die von allen Befehlen generiert werden; eine „.IGNORE“-Regel ohne Abhängigkeiten hat den gleichen Effekt, aber „-“ ist flexibler.
Beim Ignorieren von Fehlern behandelt make den Fehler als Erfolg und benachrichtigt Sie lediglich über den Exit-Status des Befehls und der Fehler wird ignoriert. Wenn make Sie beim Auftreten des Fehlers nicht auffordert, den Fehler zu ignorieren, bedeutet dies, dass das Ziel nicht erfolgreich aktualisiert werden kann und die Ziele, die direkt oder indirekt davon abhängen, mit Sicherheit nicht erfolgreich sein werden ausgeführt, weil ihre Voraussetzungen nicht erfüllt sind.
Normalerweise wird make sofort mit einem Status ungleich Null beendet. Wenn jedoch die Option „-k“ oder „-keep-going“ angegeben ist, verarbeitet make andere Abhängigkeiten und führt vor dem Beenden die erforderlichen Aktualisierungen durch. Wenn beispielsweise beim Kompilieren einer Objektdatei ein Fehler auftritt, fährt „make -k“ mit der Kompilierung anderer Objektdateien fort.
Normalerweise geht man davon aus, dass Ihr Zweck darin besteht, das angegebene Ziel zu aktualisieren. Wenn make weiß, dass dies nicht möglich ist, meldet die Option „-k“ sofort, dass der eigentliche Zweck darin besteht, weitere Möglichkeiten zur Aktualisierung zu testen Programm: Vor dem Kompilieren weitere irrelevante Fragen finden.
Wenn der Befehl fehlschlägt, vorausgesetzt, er aktualisiert die Zieldatei, ist die Datei unvollständig und kann nicht verwendet werden – zumindest nicht vollständig aktualisiert. Die letzte Änderungszeit der Datei zeigt jedoch an, dass es sich bereits um die neueste handelt, und die Datei wird bei der nächsten Ausführung von make nicht aktualisiert. Diese Situation ist die gleiche wie beim Abbruch des Befehls. Normalerweise ist es richtig, das Ziel zu löschen, wenn der Befehl fehlschlägt. make erledigt dies für Sie, wenn „.DELETE_ON_ERROR“ das Ziel ist. Obwohl Sie immer möchten, dass make dies tut, ist dies nicht üblich; daher müssen Sie make ausdrücklich darum bitten (andere make tun dies automatisch).
4.5. Make unterbrechen
Wenn make beim Ausführen eines Befehls auf einen Fehler stößt, wird die durch den Befehl aktualisierte Zieldatei möglicherweise gelöscht: make prüft, ob sich die Änderungszeit der Datei geändert hat. Der Zweck des Entfernens des Ziels besteht darin, sicherzustellen, dass es bei der nächsten Ausführung von make neu generiert wird. Warum das tun? Angenommen, Sie drücken „Strg-C“, während der Compiler läuft. Zu diesem Zeitpunkt schreibt und generiert der Compiler die Objektdatei „foo.o“. „Strg-c“ beendet den Compiler und hinterlässt eine unvollständige Datei, deren Änderungszeit jedoch neuer ist als die der Quelldatei „foo.c“. Zu diesem Zeitpunkt empfängt make auch das Signal „Strg-c“, um diese unvollständige Datei zu löschen. Wenn make dies nicht tut, geht es davon aus, dass „foo.o“ bei der nächsten Ausführung von make nicht aktualisiert werden muss, und beim Verknüpfen treten seltsame Fehler auf.
Die Regel „.PRECIOUS“ kann verwendet werden, um zu verhindern, dass Zieldateien gelöscht werden. Wenn make das Ziel aktualisiert, erkennt es, ob es eine Abhängigkeit von „.PRECIOUS“ ist, und entscheidet, ob das Ziel gelöscht werden soll, wenn der Befehlsfehler oder die Unterbrechung auftritt. Wenn Sie möchten, dass die Aktualisierung des Ziels eine atomare Operation ist, die Änderungszeit aufzeichnet oder immer vorhanden sein muss, um andere Arten von Fehlern zu verhindern, müssen Sie dies aus diesen Gründen tun.
4.6. Rekursive Verwendung
Die rekursive Verwendung von make besteht darin, den Befehl make im Makefile zu verwenden. Diese Technik ist nützlich, wenn Sie ein großes System in mehrere Subsysteme aufteilen und für jedes Subsystem ein Makefile bereitstellen. Wenn es beispielsweise ein Unterverzeichnis „subdir“ mit einem eigenen Makefile gibt und Sie möchten, dass make im Selbstverzeichnis ausgeführt wird, können Sie Folgendes tun:
subsystem:
cd subdir; $(MAKE)
oder
Subsystem:
$(MAKE) -C Unterverzeichnis
Sie können dieses Beispiel kopieren, um make rekursiv zu verwenden
4.6.1.'MAKE'-Variable
Rekursives Make muss die 'MAKE ' Variable, kein expliziter Make-Befehl:
subsystem:
cd subdir $(MAKE)
Der Wert dieser Variable ist der Name des aufgerufenen Makes. Die Verwendung von „MAKE“ in einem Befehl bewirkt etwas Außergewöhnliches: Es ändert „-t“ („--touch“), „-n“ („--just-print“) und „-q“ („--question“). ') die Bedeutung der Option. Betrachten Sie anhand des obigen Beispiels den Befehl „make –t“ (die Option „-t“ markiert das Ziel als aktuell, führt den Befehl jedoch nicht aus). Darüber hinaus erstellt die Option „-t“ ein „Subsystem“. ' Datei, die eigentlich gewünscht wird, besteht darin, 'cd subdir;
Diese außergewöhnliche Funktion erfüllt die erwartete Aufgabe. Wenn die Befehlszeile die Variable „MAKE“ enthält, gelten die Optionen „-t“, „-n“ und „-q“ nicht. Unabhängig von diesen Flags, die dazu führen, dass der Befehl nicht ausgeführt wird, werden Befehle, die die Variable „MAKE“ enthalten, immer ausgeführt. Der normale „MAKEFLAGS“-Mechanismus übergibt diese Flags an den Submake, sodass Anforderungen für Druckbefehle an das Subsystem weitergeleitet werden.
4.6.2. Variablen an Sub-Make übergeben
Variablen im Make der oberen Ebene (Top-Level) können explizit über die Umgebung an das Sub-Make übergeben werden. In Submakes sind diese Variablen standardmäßig definiert, Definitionen in Submakefiles werden jedoch nicht überschrieben, es sei denn, die Option „-e“ wird verwendet.
Um Variablen weiterzugeben oder auszugeben, fügt make diese den Umgebungsvariablen hinzu, wenn der Befehl ausgeführt wird. Sie können Umgebungsvariablen verwenden, um die Variablentabelle zu initialisieren. Sofern nicht ausdrücklich angefordert, geben Sie nur Variablen aus, die in der Anfangsumgebung oder in der Befehlszeile festgelegt wurden, und Variablennamen bestehen nur aus Buchstaben, Zahlen und Unterstrichen. Einige Shells können Umgebungsvariablen mit anderen Zeichen nicht verarbeiten.
Spezielle Variablen „SHELL“ und „MAKEFLAGS“ werden immer ausgegeben. Wenn die Variable „MAKEFILE“ einen Wert hat, wird dieser auch ausgegeben. Make gibt automatisch über „MAKEFLAGS“ auf der Befehlszeile definierte Variablen aus.
Wenn Sie eine bestimmte Variable exportieren möchten, verwenden Sie den Befehl „export“:
Variable exportieren...
Wenn Sie verhindern möchten, dass eine Variable exportiert wird, verwenden Sie den Befehl „unexport“:
VARIABLE nicht exportieren..
Der Einfachheit halber können Sie eine Variable exportieren, wenn Sie sie definieren:
VARIABLE exportieren = Wert
und
VARIABLE = Wert
VARIABLE exportieren
haben den gleichen Effekt.
Wenn Sie alle Variablen exportieren möchten, verwenden Sie einfach den Befehl „export“.
Die Variable „MAKELEVEL“ ändert sich, wenn sie Ebene für Ebene übergeben wird. Der Wert dieser Variablen ist eine Zeichenfolge, die die Anzahl der Verschachtelungsebenen angibt. Der Wert der Variablen auf der obersten Ebene ist „0“. der Wert der Untermarke ist „1“, der Wert der Untermarke ist „2“ und so weiter.
Der Zweck von „MAKELEVEL“ besteht darin, es in einer bedingten Direktive zu testen und so ein Makefile zu schreiben, das sich bei rekursiver Ausführung anders verhält als bei direkter Ausführung.
Der folgende Inhalt wurde aus dem GNU Make-Handbuch kopiert
5. Befehlszeilenparameter
`-b'
`-m'
Diese Optionen werden aus Kompatibilitätsgründen mit anderen Versionen von`make '. `-C DIR'
`--directory=DIR'
Wechseln Sie in das Verzeichnis DIR, bevor Sie die Makefiles lesen. Wenn mehrere
`-C'-Optionen angegeben sind, wird jede relativ zu interpretiert das
vorherige: „-C / -C etc“ ist äquivalent zu „-C /etc“. Dies wird
typischerweise bei rekursiven Aufrufen von „make“ verwendet (*Hinweis
Rekursive Verwendung von „make“. ': Rekursion). -Zeiten werden verglichen und mit welchen
Ergebnissen, welche Dateien tatsächlich neu erstellt werden müssen, welche impliziten
Regeln berücksichtigt und welche angewendet werden – alles Interessante
darüber, wie „make“ entscheidet, was zu tun ist. `-e '
`--environment-overrides'
Geben Sie Variablen aus der Umgebung Vorrang vor
Variablen aus der Umgebung:
Umgebung.
` --file=FILE'
`--makefile=FILE'
Lesen Sie die Datei mit dem Namen `-h'
`--help'
Erinnern Sie sich daran Optionen, die „make“ versteht und dann beendet.
`-i'
`--ignore-errors'
Ignoriert alle Fehler in Befehlen, die ausgeführt werden, um Dateien neu zu erstellen `-I DIR'
`- -include- dir=DIR'
Gibt ein Verzeichnis DIR an, in dem nach eingebundenen Makefiles gesucht werden soll
um mehrere Verzeichnisse anzugeben, werden die Verzeichnisse
in der angegebenen Reihenfolge durchsucht -j [ JOBS]'
`--jobs=[JOBS]'
Gibt die Anzahl der Jobs (Befehle) an, die gleichzeitig ausgeführt werden sollen.
Ohne Argument führt `make' so viele Jobs gleichzeitig aus wie
möglich. Wenn es mehr als eine `-j'-Option gibt, ist die letzte
wirksam.
`-k'
`--keep-going'
Fahren Sie so weit wie möglich fort nach einem Fehler. Während das Ziel, das
fehlgeschlagen ist, und die davon abhängigen Ziele nicht wiederhergestellt werden können, können die anderen
Abhängigkeiten dieser Ziele trotzdem verarbeitet werden `-l [LOAD]'
`--load-average[=LOAD]'
`--max-load[=LOAD]'
Gibt an, dass keine neuen Jobs (Befehle) gestartet werden sollen, wenn
andere Jobs laufen und die Der Lastdurchschnitt beträgt mindestens LOAD (eine
Gleitkommazahl), entfernt eine vorherige Last
Beschränkung '
`--dry-run'
`--recon'
Drucken Sie die Befehle aus, die ausgeführt werden würden, aber führen Sie sie nicht aus.
`-o FILE'
`-- old-file =FILE'
`--assume-old=FILE'
Erstellen Sie die Datei FILE nicht neu, auch wenn sie älter als ihre
Abhängigkeiten ist, und erstellen Sie nichts aufgrund von Änderungen in
DATEI. Im Wesentlichen wird die Datei als sehr alt behandelt und ihre Regeln werden ignoriert. `-p'
`--print-data-base'
Drucken Sie die Datenbank (Regeln und Variablenwerte), die sich aus dem
Lesen der Makefiles ergeben; führen Sie sie dann wie gewohnt oder wie sonst angegeben aus. Dadurch werden auch die durch den Schalter „-v“ angegebenen Versionsinformationen gedruckt Datenbank ohne zu versuchen,
Dateien neu zu erstellen, verwenden Sie „make -p -f /dev/null“
`--question'
Führen Sie keine Befehle aus , oder drucken Sie etwas; geben Sie einfach einen Exit-Status zurück, der Null ist, wenn die angegebenen Ziele bereits aktuell sind, eins, wenn eine Neuerstellung erforderlich ist, oder zwei, wenn ein Fehler auftritt '
`--no-builtin-rules'
Beseitigen Sie die Verwendung der integrierten impliziten Regeln. Sie können weiterhin Ihre eigenen definieren, indem Sie
Musterregeln schreiben. Die Option „-r“ löscht auch die Standardliste
von Suffixen für Suffixregeln. Sie können jedoch weiterhin Ihre eigenen Suffixe mit einer
Regel für „.SUFFIXES“ definieren und dann Ihre eigenen Suffixregeln definieren. `-s'
`--silent'
`--quiet'
Stiller Betrieb; Druckt die Befehle nicht aus, während sie ausgeführt werden.
`-S'
`--no-keep-going'
`--stop'
Hebt die Wirkung der Option „-k“ auf . Dies ist nie notwendig
außer in einem rekursiven „make“, bei dem „-k“ möglicherweise von
dem „make“ der obersten Ebene über „MAKEFLAGS“ geerbt wird oder wenn Sie „-k“ in „MAKEFLAGS“ festlegen Ihre
Umgebung. `-t'
`--touch'
Berühren Sie Dateien (markieren Sie sie als aktuell, ohne sie wirklich zu ändern)
anstatt ihre Befehle auszuführen. Dies wird verwendet, um vorzutäuschen, dass
die Befehle ausgeführt wurden, um zukünftige Aufrufe von
„make“ zu täuschen. `-v'
`--version'
Drucken Sie die Version des `make'-Programms sowie ein Copyright, eine Liste
der Autoren und einen Hinweis, dass es keine Garantie gibt; dann beenden.
`-w'
`--print-directory'
Drucken Sie eine Nachricht mit dem Arbeitsverzeichnis sowohl vor als auch
nach der Ausführung des Makefiles. Dies kann nützlich sein, um Fehler aus komplizierten Verschachtelungen rekursiver „make“-Befehle aufzuspüren. `--no-print-directory'
Drucken des Arbeitsverzeichnisses unter `-w' deaktivieren. Diese Option
ist nützlich, wenn „-w“ automatisch aktiviert ist, Sie aber
die zusätzlichen Nachrichten nicht sehen möchten. `-W FILE'
`--what-if=FILE'
`--new-file=FILE'
`--assume-new=FILE'
Stellen Sie sich vor, dass die Zieldatei vorhanden ist wurde gerade geändert. Bei Verwendung
mit dem Flag „-n“ zeigt Ihnen dies, was passieren würde, wenn Sie
diese Datei ändern würden. Ohne „-n“ ist es fast dasselbe wie
das Ausführen eines „touch“-Befehls für die angegebene Datei vor dem Ausführen von „make“,
außer dass die Änderungszeit nur in der
Vorstellung von „ geändert wird machen'. `--warn-undefined-variables'
Gibt eine Warnmeldung aus, wenn `make' einen Verweis auf eine
undefinierte Variable sieht. Dies kann hilfreich sein, wenn Sie Makefiles debuggen möchten, die Variablen auf komplexe Weise verwenden. 6.参考
6.1.指令
`define VARIABLE'
`endef'
Definieren Sie eine mehrzeilige, rekursiv erweiterte Variable.
*Hinweissequenzen::. `ifdef VARIABLE'
`ifndef VARIABLE'
`ifeq (A,B)'
`ifeq "A" "B"'
`ifeq 'A' 'B''
` ifneq (A,B)'
`ifneq "A" "B"'
`ifneq 'A' 'B''
`else'
`endif'
Bewerte einen Teil davon bedingt das Makefile. `include FILE'
Fügen Sie ein weiteres Makefile hinzu. `override VARIABLE = VALUE'
`override VARIABLE := VALUE'
`override VARIABLE += VALUE'
`override define VARIABLE'
`endef'
Definieren Sie eine Variable und überschreiben Sie alle vorherigen Definition, sogar eine
von der Befehlszeile.
`export'
Sagen Sie `make', dass alle Variablen standardmäßig in untergeordnete Prozesse exportiert werden sollen. `export VARIABLE'
`export VARIABLE = VALUE'
`export VARIABLE := VALUE'
`export VARIABLE += VALUE'
`unexport VARIABLE'
Sagen Sie `make', ob oder nicht um eine bestimmte Variable in untergeordnete
Prozesse zu exportieren.
`vpath PATTERN PATH'
Geben Sie einen Suchpfad für Dateien an, die einem „%“-Muster entsprechen.
*Beachten Sie die „vpath“-Direktive: Selektive Suche. `vpath PATTERN'
Entfernt alle Suchpfade, die zuvor für PATTERN angegeben wurden. `vpath'
Entfernen Sie alle Suchpfade, die zuvor in einer `vpath'
Anweisung angegeben wurden.
6.2.函数
`$(subst FROM,TO,TEXT)'
Ersetzen Sie FROM durch TO in TEXT. `$(patsubst PATTERN,REPLACEMENT,TEXT)'
Ersetzen Sie Wörter, die mit PATTERN übereinstimmen, durch REPLACEMENT im TEXT. `$(strip STRING)'
Überschüssige Leerzeichen aus STRING entfernen. `$(findstring FIND,TEXT)'
Suchen Sie FIND in TEXT. `$(filter PATTERN...,TEXT)'
Wählen Sie Wörter in TEXT aus, die mit einem der PATTERN-Wörter übereinstimmen. `$(filter-out PATTERN...,TEXT)'
Wählen Sie Wörter in TEXT aus, die *mit keinem der PATTERN-Wörter übereinstimmen. `$(sort LIST)'
Sortieren Sie die Wörter in LIST lexikografisch und entfernen Sie Duplikate. `$(dir NAMES...)'
Extrahieren Sie den Verzeichnisteil jedes Dateinamens. `$(notdir NAMES...)'
Extrahieren Sie den Nicht-Verzeichnis-Teil jedes Dateinamens. `$(suffix NAMES...)'
Extrahieren Sie das Suffix (das letzte „.“ und die folgenden Zeichen) jedes
Dateinamens. `$(basename NAMES...)'
Extrahieren Sie den Basisnamen (Name ohne Suffix) jedes Dateinamens. `$(addsuffix SUFFIX,NAMES...)'
Hänge SUFFIX an jedes Wort in NAMES an. `$(addprefix PREFIX,NAMES...)'
Präfix jedem Wort in NAMES voranstellen. `$(join LIST1,LIST2)'
Verbinde zwei parallele Wortlisten. `$(word N,TEXT)'
TEXT의 N번째 단어(one-origin)를 추출합니다. `$(words TEXT)'
TEXT의 단어 수를 셉니다. `$(첫 번째 단어 NAMES...)'
NAMES의 첫 번째 단어를 추출합니다. `$(와일드카드 패턴...)'
셸 파일 이름 패턴과 일치하는 파일 이름을 찾습니다(`%'
패턴 *아님*). `$(shell COMMAND)'
쉘 명령을 실행하고 출력을 반환합니다. `$(origin VARIABLE)'
`make' 변수 VARIABLE이 정의된 방법을 설명하는 문자열을
반환합니다. `$(foreach VAR,WORDS,TEXT)'
WORDS의 각 단어에 바인딩된 VAR을 사용하여 TEXT를 평가하고
결과를 연결합니다.
6.3.自动变weight
`$@'
대상의 파일 이름입니다. `$%'
대상이 아카이브 멤버인 경우 대상 멤버 이름입니다. `$<'
첫 번째 종속성의 이름입니다. `$?'
대상보다 새로운 모든 종속성의 이름
사이에 공백이 있습니다. 아카이브
멤버인 종속성의 경우 이름이 지정된 멤버만
사이에 공백이 포함되어 사용됩니다. 아카이브
멤버인 종속성의 경우 이름이 지정된 멤버만 사용됩니다.
`$^'
`$+'
모든 종속성의 이름(사이에 공백 포함).
아카이브 멤버인 종속성의 경우 이름이 지정된 멤버만
사용됩니다. `$^' 값은 중복
종속성을 생략하는 반면, `$+'는 이를 유지하고 순서를 유지합니다. `$*'
암시적 규칙이 `$(@D)'와 일치하는 어간
`$(@F)'
`$@의 디렉토리 부분 및 디렉토리 내 파일 부분 '. `$(*D)'
`$(*F)'
`$*'의 디렉토리 부분과 디렉토리 내 파일 부분. `$(%D)'
`$(%F)'
`$%' `$(
`$(^F)'
`$^' `$(+D)'
`$(+의 디렉토리 부분과 디렉토리 내 파일 부분 F)'
`$+' `$(?D)'
`$(?F)'
디렉토리 부분과 디렉토리 내 파일 부분 `$+' -`$?'의 디렉토리 부분
6.4.비凡变weight
`MAKEFILES'
`make'를 호출할 때마다 읽을 Makefile입니다. `VPATH'
현재 디렉토리에서 찾을 수 없는 파일에 대한 디렉토리 검색 경로입니다. `SHELL'
시스템 기본 명령 해석기의 이름, 일반적으로
`/bin/sh'. makefile에서 `SHELL'을 설정하여
명령 실행에 사용되는 쉘을 변경할 수 있습니다.
`MAKE'
`make'가 호출된 이름입니다.
명령에서 이 변수를 사용하는 것은 특별한 의미를 갖습니다. `MAKELEVEL'
재귀 수준(하위 `make's) 수입니다. `MAKEFLAGS'
`make'에 부여되는 플래그입니다. 이를 환경이나
메이크파일에서 설정하여 플래그를 설정할 수 있습니다. `SUFFIXES'
`make'가 makefile을 읽기 전의 기본 접미사 목록입니다.
以上就是makefile规则的内容,更多敵关文章请关注PHP中文网(www.php.cn)!