Makefile bearbeitet unzählige Quelldateien in einem Projekt, die je nach Typ, Funktion und Modul in mehreren Verzeichnissen abgelegt werden. Das Makefile definiert eine Reihe von Regeln, um anzugeben, welche Dateien zuerst kompiliert und sogar aktualisiert werden müssen , denn das Makefile ist wie ein Shell-Skript, das auch Betriebssystembefehle ausführen kann.
Das auszufüllende Makefile beschreibt die Kompilierung, Verbindung und andere Regeln des gesamten Projekts. Dazu gehören: Welche Quelldateien im Projekt müssen kompiliert werden und wie werden sie kompiliert, welche Bibliotheksdateien müssen erstellt werden und wie werden diese Bibliotheksdateien erstellt und wie schließlich die gewünschte ausführbare Datei generiert. Obwohl es wie eine komplizierte Angelegenheit erscheinen mag, liegt der Vorteil des Schreibens eines Makefiles für ein Projekt in der Möglichkeit, einen einzeiligen Befehl zu verwenden, um die „automatische Kompilierung“ abzuschließen, sobald ein (normalerweise mehrere für ein Projekt) korrektes Makefile bereitgestellt wird. Um das gesamte Projekt zu kompilieren, müssen Sie lediglich den Befehl „make“ am Shell-Prompt eingeben. Das gesamte Projekt wird vollständig automatisch kompiliert, was die Effizienz erheblich steigert.
make ist ein Befehlstool, das die Anweisungen (man sollte sie als Regeln bezeichnen) im Makefile interpretiert. Das Makefile beschreibt die Kompilierungsreihenfolge und Kompilierungsregeln aller Dateien im gesamten Projekt. Makefile verfügt über ein eigenes Schreibformat, eigene Schlüsselwörter und Funktionen. Genauso wie die Sprache C ihr eigenes Format, ihre eigenen Schlüsselwörter und Funktionen hat. Und im Makefile können Sie jeden von der System-Shell bereitgestellten Befehl verwenden, um die gewünschte Arbeit abzuschließen. Makefile (auf anderen Systemen kann es sich um einen anderen Dateinamen handeln) wird in den meisten IDE-Entwicklungsumgebungen verwendet und ist zu einer Projektkompilierungsmethode geworden.
Der Vorteil von Makefile ist die „automatisierte Kompilierung“. Nach dem Schreiben ist nur ein Make-Befehl erforderlich und das gesamte Projekt wird vollständig automatisch kompiliert, was die Effizienz der Softwareentwicklung erheblich verbessert. make ist ein Befehlstool, das die Anweisungen im Makefile interpretiert. Im Allgemeinen verfügen die meisten IDEs über diesen Befehl, z. B. make von Delphi, nmake von Visual C und make von GNU unter Linux. Es ist ersichtlich, dass Makefile zu einer Kompilierungsmethode im Engineering geworden ist.
Die wichtigste und grundlegendste Funktion des Make-Tools besteht darin, die Beziehung zwischen Quellprogrammen durch Makefile-Dateien zu beschreiben und die Kompilierungsarbeit automatisch aufrechtzuerhalten. Die Makefile-Datei muss gemäß einer bestimmten Syntax geschrieben werden. Die Datei muss erklären, wie jede Quelldatei kompiliert und verbunden wird, um eine ausführbare Datei zu generieren, und es ist erforderlich, die Abhängigkeiten zwischen den Quelldateien zu definieren. Die Makefile-Datei ist für viele Compiler – auch unter Windows NT – eine gängige Methode zum Verwalten von Kompilierungsinformationen. In der integrierten Entwicklungsumgebung ändern Benutzer die Makefile-Datei nur über eine benutzerfreundliche Schnittstelle. In UNIX-Systemen ist es üblich, Makefile als Makefile-Datei zu verwenden. Wenn Sie andere Dateien als Makefiles verwenden möchten, können Sie die Makefile-Datei mit einer Make-Befehlsoption ähnlich der folgenden angeben:
$ make -f Makefile.debug _Zum Beispiel besteht ein Programm namens prog aus drei C Die Quelldateien filea.c, fileb.c und filec.c sowie die Bibliotheksdatei LS werden kompiliert und generiert. Diese drei Dateien enthalten auch ihre eigenen Header-Dateien a.h, b.h und c.h. Normalerweise gibt der C-Compiler drei Objektdateien filea.o, fileb.o und filec.o aus. Nehmen Sie an, dass filea.c und fileb.c beide die Verwendung einer Datei namens defs deklarieren, filec.c jedoch nicht. Das heißt, es gibt solche Anweisungen in filea.c und fileb.c:
include "defs"
Dann beschreibt das folgende Dokument die Verbindung zwischen diesen Dateien:
0 #Es ist ein Beispiel für die Beschreibung der Makefile-Kommentarzeile
1 prog: filea.o fileb.o filec.o #Geben Sie an, dass prog aus drei Zieldateien filea.o, fileb.o und filec o besteht. Linkgenerierung
2 cc filea.o fileb.o filec.o -LS -o prog #Wie man aus den Dateien prog eine ausführbare Datei erstellt, hängt von
3 filea.o : ca.h defs ab #Geben Sie die Zieldatei filea.o sowie die .c- und .h-Dateien und Defs-Dateien an, von denen sie abhängen
4 cc -c filea.c #So erstellen Sie das Ziel aus den Dateien, von denen das Ziel abhängt on, das ist So erstellen Sie filea.o aus filea.c
5 fileb.o : fileb.c b.h defs #Geben Sie die fileb.o-Zieldatei sowie die .c- und .h-Dateien an und Defs-Dateien, von denen sie abhängen
6 cc -c fileb.c #So erstellen Sie ein Ziel aus den Dateien, von denen das Ziel abhängt, das heißt, wie erstellen Sie fileb.o aus fileb.c
7 filec.o : filec.c c.h #Geben Sie filec oZieldateien und die .c- und .h-Dateien an, von denen sie abhängen
8 cc -c filec.c #So erstellen Sie das Ziel aus dem Dateien, von denen das Ziel abhängt, d. h. wie man filec.o aus filec.c erstellt
Dieses Beschreibungsdokument ist ein einfaches Makefile, das das Tiefenprinzip verwendet, um Kompilierungsbefehle auszuführen. Lassen Sie uns einige grundlegende Erklärungen zum Code im obigen Beispiel geben: CC ist eine globale Variable, die den von Ihrem Makefile verwendeten Compiler angibt. Im Allgemeinen ist die .o-Datei unter Unix eine Zwischencode-Zieldatei In Windows wird der Prozess des Generierens von .o-Dateien unter Unix wie bei den .obj-Dateien unter Unix als Kompilieren bezeichnet, und der Prozess des Sammelns unzähliger .o-Dateien zum Generieren ausführbarer Dateien wird manchmal als Verknüpfen bezeichnet Unix-Schnittstelle. Datei, also Archivdatei, die der Bibliotheksdatei unter Windows entspricht. Die Funktion der .a-Datei ist: weil es zu viele Quelldateien gibt (das obige Beispiel bezieht sich auf zu viele .c- und .h-Dateien). ), die durch die Kompilierung generierte Zwischenzieldatei ( Es gibt zu viele .o-Dateien) und der Name der Zwischenzieldatei muss beim Verknüpfen klar angegeben werden, was für die Kompilierung sehr unpraktisch ist. Daher müssen wir sie packen Zwischenzieldatei, und dieses Paket ist die .a-Datei.
Wenn die Datei filea.c oder a.h nach der Kompilierung geändert wird, kann das Make-Tool filea.o automatisch neu kompilieren, wenn filea.c und a.h zwischen den beiden Kompilierungen nicht geändert wurden und wenn filea.o immer noch vorhanden ist, ist keine Neukompilierung erforderlich. Diese Abhängigkeit ist besonders wichtig bei der Programmkompilierung mit mehreren Quelldateien. Durch die Definition dieser Abhängigkeit kann das Make-Tool eine Menge unnötiger Kompilierungsarbeit vermeiden. Natürlich können Sie auch Shell-Skripte verwenden, um automatische Kompilierungseffekte zu erzielen. Shell-Skripte kompilieren jedoch alle Quelldateien, einschließlich der Quelldateien, die nicht neu kompiliert werden müssen, während das Make-Tool auf der Grundlage der letzten Kompilierung des Ziels kompilieren kann kompiliert und wovon das Ziel abhängt. Bestimmen Sie automatisch, welche Quelldatei basierend auf der Aktualisierungszeit der Quelldatei kompiliert werden soll. _
Werfen wir einen groben Blick auf die Regeln von Makefile. [3] Ziel ...: Voraussetzungen ... Befehl ... ... Ziel: Abhängigkeitsausführungsbefehl ... Ziel ist eine Zieldatei, die eine Objektdatei oder eine Ausführungsdatei sein kann. Es kann auch ein Etikett sein. ① Voraussetzungen sind die Dateien oder Ziele, die zum Generieren dieses Ziels erforderlich sind. ② Befehl ist der Befehl, den make ausführen muss. (Beliebiger Shell-Befehl) Dies ist eine Dateiabhängigkeit, d. h. eine oder mehrere Zieldateien des Ziels hängen von den Dateien in den Voraussetzungen ab und ihre Generierungsregeln werden im Befehl definiert. Um es ganz klar auszudrücken: Wenn mehr als eine Datei in den Voraussetzungen vorhanden ist, die neuer als die Zieldatei ist, wird der durch Befehl definierte Befehl ausgeführt (der Befehl muss mit der Tabulatortaste beginnen, sonst erkennt der Compiler den Befehl nicht), was die Reduzierung verringert Die wiederholte Kompilierung hat die Effizienz des Software-Engineering-Managements verbessert.
Makefile ermöglicht die Verwendung einfacher Makros, um auf Quelldateien und die zugehörigen Kompilierungsinformationen zu verweisen. Makros werden unter Linux auch Variablen genannt. Wenn Sie ein Makro zitieren, müssen Sie vor der Variablen nur das $-Symbol hinzufügen. Beachten Sie jedoch, dass Sie beim Zitieren Klammern () hinzufügen müssen, wenn der Variablenname länger als ein Zeichen ist. Gültige Makroverweise sind $(CFLAGS) $Z $(Z), wobei die letzten beiden Verweise identisch sind. Es ist zu beachten, dass sich in Unix-Systemen die Werte der vier speziellen Makros $*, $@, $? und $< entsprechend ändern Weitere vordefinierte Variablen sind in definiert. Was die Details vordefinierter Variablen betrifft, kann uns die Verwendung von Makrodefinitionen diese mühsamen Kompilierungsoptionen ersparen und das Schreiben von Makefile-Dateien erheblich vereinfachen.
Hauptvordefinierte Variablen von GNU make Vordefinierte Variablen Bedeutung $* Der Name der Zieldatei ohne Erweiterung. $ Alle abhängigen Dateien, getrennt durch Leerzeichen, in der Reihenfolge ihres Erscheinens, können doppelte abhängige Dateien enthalten. $< Der Name der ersten abhängigen Datei. $? Alle abhängigen Dateien, getrennt durch Leerzeichen, deren Änderungsdatum nach dem Erstellungsdatum des Ziels liegt. $@ Der vollständige Name des Ziels. $^ Alle abhängigen Dateien, getrennt durch Leerzeichen, enthalten keine doppelten abhängigen Dateien. $% Wenn das Ziel ein Archivmitglied ist, stellt diese Variable den Archivmitgliedsnamen des Ziels dar. Wenn der Zielname beispielsweise (image.o) lautet, dann ist $@ und $% ist image.o. AR Der Name des Archivwartungsprogramms. Der Standardwert ist ar. ARFLAGS Optionen für das Archivwartungsprogramm. AS Der Name des Assemblers, der Standardwert ist as. ASFLAGS-Assembler-Optionen. CC Der Name des C-Compilers, Standard ist cc. CFLAGS C-Compiler-Optionen. CPP Der Name des C-Precompilers, Standardwert ist $(CC) -E. CPPFLAGS C-Vorkompilierungsoptionen. CXX Der Name des C-Compilers, Standard ist g . CXXFLAGS C-Compiler-Optionen. FC Der Name des FORTRAN-Compilers. Der Standardwert ist f77. FFLAGS FORTRAN-Compileroptionen. Makefile vergleicht die Datei auf der rechten Seite des Doppelpunkts in Form von Dateiname: Dateiname, um festzustellen, ob sie neuer als die Datei auf der linken Seite ist. Wenn sie aktualisiert wird, wird die nächste Zeile Programmcode ausgeführt. Daher kann Makefile Dateien zuordnen