Was ist Makefile in Linux? Wie funktioniert es?

Was ist Makefile in Linux? Wie funktioniert es?

Führen Sie Ihre Programme mit diesem praktischen Tool effizienter aus und kompilieren Sie sie
Makefile wird zum automatischen Kompilieren und Verknüpfen verwendet. Ein Projekt besteht aus vielen Dateien. Jede Änderung an einer Datei führt zum erneuten Verknüpfen des Projekts. Allerdings müssen nicht alle Dateien neu kompiliert werden. Makefile kann Dateiinformationen aufzeichnen und entscheiden, welche Dateien beim Verknüpfen neu kompiliert werden müssen!

Das Make-Tool wird normalerweise verwendet, wenn Sie eine Aufgabe ausführen oder aktualisieren müssen, nachdem sich einige Quelldateien geändert haben. Das Make-Tool muss eine Makefile-Datei (oder Makefile-Datei) lesen, die eine Reihe auszuführender Aufgaben definiert. Mit make können Sie Quellcode in ein ausführbares Programm kompilieren. Die meisten Open Source-Projekte verwenden make, um die endgültigen Binärdateien zu kompilieren, und führen dann die Installation mit dem Befehl make install durch.
Dieser Artikel zeigt anhand einiger grundlegender und fortgeschrittener Beispiele die Verwendung von make und Makefile. Bevor Sie beginnen, stellen Sie sicher, dass make auf Ihrem System installiert ist.

Das grundlegende Beispiel beginnt immer noch mit der Ausgabe von „Hallo Welt“. Erstellen Sie zunächst ein Verzeichnis mit dem Namen myproject und erstellen Sie im Verzeichnis eine Makefile-Datei mit folgendem Inhalt:

sag_hallo:
echo "Hallo Welt"

Führen Sie make im Verzeichnis myproject aus. Die folgende Ausgabe wird angezeigt:

$ machen
echo "Hallo Welt"
Hallo Welt

Im obigen Beispiel ähnelt „say_hello“ Funktionsnamen in anderen Programmiersprachen. Dies wird als Ziel bezeichnet. Auf das Ziel folgen die Voraussetzungen bzw. Abhängigkeiten. Der Einfachheit halber haben wir in diesem Beispiel keine Vorbedingungen definiert. Der Echo-Befehl „Hallo Welt“ wird als Rezept bezeichnet. Diese Schritte richten sich nach den Voraussetzungen zur Zielerreichung. Ziel, Voraussetzungen und Schritte ergeben zusammen eine Regel.

Zusammenfassend lautet die Syntax einer typischen Regel:

Ziel: Voraussetzungen
<TAB> Schritte

Ein Ziel kann beispielsweise eine Binärdatei sein, die auf einer Vorbedingung (Quellcode) basiert. Andererseits kann eine Vorbedingung auch ein Ziel sein, das von anderen Vorbedingungen abhängt.

endgültiges_Ziel: Unterziel endgültiges_Ziel.c
Rezept_zum_Erstellen_des_Endziels
untergeordnetes Ziel: untergeordnetes Ziel.c
Rezept_zum_Erstellen_eines_Subziels

Das Ziel muss keine Datei sein, es kann auch einfach der Name eines Schrittes sein, wie in unserem Beispiel. Wir nennen dies ein „Pseudoziel“

Um auf das obige Beispiel zurückzukommen: Wenn make ausgeführt wird, wird der gesamte Befehl echo „Hello World“ angezeigt, gefolgt vom eigentlichen Ausführungsergebnis. Wenn Sie nicht möchten, dass der Befehl selbst gedruckt wird, müssen Sie vor dem Echo ein @ hinzufügen.

sag_hallo:
@echo "Hallo Welt"

Führen Sie make erneut aus und Sie sehen die folgende Ausgabe:

$ machen
Hallo Welt

Als nächstes fügen Sie dem Makefile die folgenden Pseudoziele hinzu: generate und clean:

sag_hallo:
@echo "Hallo Welt"
erzeugen:
@echo "Erstelle leere Textdateien …"
Touch-Datei-{1..10}.txt
sauber:
@echo "Aufräumen..."
rm *.txt

Wenn wir „make“ später ausführen, wird nur das Ziel „say_hello“ ausgeführt. Dies liegt daran, dass das erste Ziel in einem Makefile das Standardziel ist. Normalerweise wird das Standardziel aufgerufen, das in den meisten Projekten als erstes Ziel angezeigt wird: „all“. all ist für den Aufruf seines Ziels verantwortlich. Wir können das Standardverhalten außer Kraft setzen, indem wir das spezielle Pseudoziel .DEFAULT_GOAL verwenden.

Fügen Sie am Anfang des Makefiles .DEFAULT_GOAL hinzu:

.DEFAULT_GOAL := generate

Make verwendet „generate“ als Standardziel:

$ machen
Leere Textdateien erstellen...
Touch-Datei-{1..10}.txt

Wie der Name schon sagt, kann das Pseudoziel .DEFAULT_GOAL nur ein Ziel definieren. Aus diesem Grund enthalten viele Makefiles das Ziel „all“, das mehrere Ziele aufrufen kann.
Löschen Sie als Nächstes .DEFAULT_GOAL und fügen Sie das gesamte Ziel hinzu:

alle: say_hello generieren
sag_hallo:
@echo "Hallo Welt"
erzeugen:
@echo "Erstelle leere Textdateien …"
Touch-Datei-{1..10}.txt
sauber:
@echo "Aufräumen..."
rm *.txt

Lassen Sie uns vor dem Ausführen einige spezielle Pseudoziele hinzufügen. .PHONY wird verwendet, um Ziele zu definieren, die keine Dateien sind. Standardmäßig ruft make die Schritte unter diesen Pseudozielen auf, ohne die Existenz des Dateinamens oder des letzten Änderungsdatums zu überprüfen. Das vollständige Makefile lautet wie folgt:

.PHONY: alle say_hello generieren sauber
alle: say_hello generieren
sag_hallo:
@echo "Hallo Welt"
erzeugen:
@echo "Erstelle leere Textdateien …"
Touch-Datei-{1..10}.txt
sauber:
@echo „Aufräumen …“
rm *.txt

Der Befehl make ruft say_hello auf und generiert:

$ machen
Hallo Welt
Leere Textdateien erstellen...
Touch-Datei-{1..10}.txt

clean sollte nicht in „all“ oder in das erste Ziel eingefügt werden. clean sollte manuell aufgerufen werden, wenn eine Reinigung erforderlich ist. Die aufrufende Methode lautet make clean

$ sauber machen
Aufräumen...
rm *.txt

Nachdem Sie nun ein grundlegendes Verständnis von Makefile haben, schauen wir uns einige fortgeschrittene Beispiele an.

Erweiterte Beispiele Variablen In den vorherigen Beispielen waren die meisten Ziele und Voraussetzungen festgelegt, in realen Projekten werden sie jedoch normalerweise durch Variablen und Muster ersetzt.

Der einfachste Weg, eine Variable zu definieren, ist die Verwendung des =-Operators. So weisen Sie beispielsweise der Variablen CC den Befehl gcc zu:

CC = gcc

Dies wird als rekursive Variablenerweiterung bezeichnet und in Regeln wie diesen verwendet:

hallo: hallo.c
${CC} hallo.c -o hallo

Wie zu erwarten, werden diese Schritte wie folgt erweitert:

gcc hello.c -o hello

Sowohl ${CC} als auch $(CC) können sich auf gcc beziehen. Wenn eine Variable jedoch versucht, sich selbst zuzuweisen, entsteht eine Endlosschleife. Lassen Sie uns dies überprüfen:

CC = gcc
CC = ${CC}
alle:
@echo ${CC}

Das Ausführen von „make“ an dieser Stelle führt zu:

$ machen
Makefile:8: *** Rekursive Variable „CC“ verweist (eventuell) auf sich selbst. Stopp.

Um dies zu vermeiden, können Sie den Operator := verwenden (dies wird als einfache Variablenerweiterung bezeichnet). Der folgende Code verursacht das obige Problem nicht:

CC := gcc
CC := ${CC}
alle:
@echo ${CC}

Modi und Funktionen Das folgende Makefile verwendet Variablen, Modi und Funktionen, um den gesamten C-Code zu kompilieren. Lassen Sie es uns Zeile für Zeile analysieren:

# Verwendung:
# make # alle Binärdateien kompilieren
# sauber machen # ALLE Binärdateien und Objekte entfernen
.PHONY = alles sauber
CC = gcc # zu verwendender Compiler
LINKERFLAG = -lm
SRCS := $(Platzhalter *.c)
BINS := $(SRCS:%.c=%)
alle: ${BINS}
%: %.o
@echo "Überprüfe..."
${CC} ${LINKERFLAG} $< -o $@
%.o: %.c
@echo "Objekt wird erstellt..."
${CC} -c $<
sauber:
@echo „Aufräumen …“
rm -rvf *.o ${BINS}

Zeilen, die mit # beginnen, sind Kommentare
Die Zeile .PHONY = all clean definiert zwei Pseudoziele, all und clean.
Die Variable LINKERFLAG definiert die Parameter, die der gcc-Befehl in diesem Schritt verwenden muss.
SRCS := $(wildcard *.c): $(wildcard pattern) ist eine Funktion, die sich auf den Dateinamen bezieht. In diesem Beispiel werden alle Dateien mit der Endung „.c“ in der Variable SRCS gespeichert.
BINS := $(SRCS:%.c=%): Dies wird als Substitutionsreferenz bezeichnet. Wenn in diesem Beispiel der Wert von SRCS „foo.c bar.c“ ist, dann ist der Wert von BINS „foo bar“.
Die Zeile all: ${BINS}: Das Pseudoziel all ruft alle Werte in der Variable ${BINS} als Unterziele auf.
Regel:

%: %.o
@echo "Überprüfe..."
${CC} ${LINKERFLAG} $< -o $@

Um diese Regel zu verstehen, verwenden wir ein Beispiel. Angenommen, foo ist ein Wert in der Variable ${BINS}. % entspricht foo (% entspricht jedem Ziel). So sehen die Regeln nach der Erweiterung aus:

foo: foo.o
@echo "Überprüfe..."
gcc -lm foo.o -o foo

Wie oben gezeigt wird % durch foo ersetzt. $< wird durch foo.o ersetzt. $< wird verwendet, um die voreingestellte Bedingung zu erfüllen, $@ entspricht dem Ziel. Diese Regel wird einmal für jeden Wert in ${BINS} aufgerufen.
Regel:

%.o: %.c
@echo "Objekt wird erstellt..."
${CC} -c $<

Jede Vorbedingung in der vorherigen Regel wird in dieser Regel als Ziel behandelt. So sieht es nach der Erweiterung aus:

foo.o: foo.c
@echo "Objekt wird erstellt..."
gcc -c foo.c

Schließlich werden im bereinigten Ziel alle Binärdateien und kompilierten Dateien entfernt.
Hier ist das neu geschriebene Makefile, das in einem Verzeichnis mit einer foo.c-Datei abgelegt werden sollte:

# Verwendung:
# make # alle Binärdateien kompilieren
# sauber machen # ALLE Binärdateien und Objekte entfernen
.PHONY = alles sauber
CC = gcc # zu verwendender Compiler
LINKERFLAG = -lm
SRCS := foo.c
BINS := foo
alle: foo
foo: foo.o
@echo "Überprüfe..."
gcc -lm foo.o -o foo
foo.o: foo.c
@echo "Objekt wird erstellt..."
gcc -c foo.c
sauber:
@echo „Aufräumen …“
rm -rvf foo.o foo

Zusammen bilden diese ein Makefile. Natürlich sind diese Funktionen zu wenig und es können noch viele weitere Projekte hinzugefügt werden. Der Zweck besteht jedoch darin, dem Compiler mitzuteilen, auf welche anderen Dateien er zum Kompilieren einer Datei angewiesen ist. Wenn diese abhängigen Dateien geändert werden, stellt der Compiler automatisch fest, dass die endgültig generierte Datei veraltet ist, und kompiliert das entsprechende Modul neu.

Zusammenfassen

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Lernwert für Ihr Studium oder Ihre Arbeit hat. Vielen Dank für Ihre Unterstützung von 123WORDPRESS.COM. Wenn Sie mehr darüber erfahren möchten, schauen Sie sich bitte die folgenden Links an

Das könnte Sie auch interessieren:
  • Definition und Verwendung von Makefile-Befehlspaketen in Linux
  • Verständnis von Makefile unter Linux
  • Detaillierte Erklärung zum Schreiben und Verwenden von Makefile unter Linux

<<:  JavaScript generiert zufällige Grafiken durch Klicken

>>:  Installations-Tutorial zur neuesten stabilen Version von MySQL 5.7.17 unter Linux

Artikel empfehlen

Dieser Artikel zeigt Ihnen, wie Sie mit CSS-Kombinationsselektoren spielen

CSS-Kombinationsselektoren umfassen verschiedene ...

Lösen Sie das Problem der Verwendung von weniger in Vue

1. Installieren Sie weniger Abhängigkeiten: npm i...

Detaillierte Erläuterung der Verarbeitung der drei Docker Nginx-Protokolle

Da die Kollegen im Unternehmen die Standardausgab...

Detaillierte Erläuterung des Vuex-Gesamtfalls

Inhaltsverzeichnis 1. Einleitung 2. Vorteile 3. N...

So installieren Sie Composer unter Linux

1. Laden Sie das Installationsskript - composer-s...

Lernen Sie, wie Sie Uniapps und Miniprogramme (Bilder und Text) untervergeben

Inhaltsverzeichnis 1. Subunternehmer für Miniprog...

Praxis der Vue Global Custom-Anweisung Modal Drag

Inhaltsverzeichnis Hintergrund Umsetzungsideen Er...

Vollständige Schritte zur Deinstallation der MySQL-Datenbank

Der Vorgang zur vollständigen Deinstallation der ...