CC=g++
CFLAGS=-c -Wall
LDFLAGS=
SOURCES=main.cpp hello.cpp factorial.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@
.cpp.o:
$(CC) $(CFLAGS) $< -o $@
Was machen die $@
und $<
machen genau?
Antworten:
$@
ist der Name der zu generierenden Datei und$<
die erste Voraussetzung (normalerweise die Quelldatei). Eine Liste all dieser speziellen Variablen finden Sie im Handbuch GNU Make .Betrachten Sie beispielsweise die folgende Erklärung:
In diesem Fall:
$@
bewertet zuall
$<
bewertet zulibrary.cpp
$^
bewertet zulibrary.cpp main.cpp
quelle
$@
dies nicht unbedingt eine Datei sein muss, sondern auch der Name eines.PHONY
Ziels.$@s
Befehlszeilenoptionen Folgendes hinzufügen: um Assembly-Ausgaben wie name.os zu generieren?Die
$@
und$<
werden automatische Variablen genannt . Die Variable$@
stellt den Namen der erstellten Datei dar (dh das Ziel) und$<
stellt die erste Voraussetzung dar, die zum Erstellen der Ausgabedatei erforderlich ist.Zum Beispiel:
Hier
hello.o
ist die Ausgabedatei. Darauf$@
erweitert sich. Die erste Abhängigkeit isthello.c
. Darauf$<
erweitert sich.Das
-c
Flag generiert die.o
Datei. sieheman gcc
für eine detailliertere Erklärung. Das-o
gibt die Ausgabedatei an, die erstellt werden soll.Weitere Informationen finden Sie in diesem Artikel über Linux-Makefiles .
Sie können auch die GNU-
make
Handbücher überprüfen . Dies erleichtert das Erstellen und Debuggen von Makefiles.Wenn Sie diesen Befehl ausführen, wird die Makefile-Datenbank ausgegeben:
quelle
$<
sich aufhello.c hello.h
(beide) auszudehnen . Bitte klären Sie.$<
ist nur der erste Punkt. Verwenden Sie, um alle einzuschließen$^
.Aus Verwalten von Projekten mit GNU Make, 3. Ausgabe, S. 22. 16 (unter der GNU Free Documentation License ):
quelle
Die
$@
und$<
sind spezielle Makros.Wo:
$@
ist der Dateiname des Ziels.$<
ist der Name der ersten Abhängigkeit.quelle
Das Makefile baut die
hello
ausführbare Datei , wenn einermain.cpp
,hello.cpp
,factorial.cpp
geändert. Das kleinstmögliche Makefile, um diese Spezifikation zu erreichen, könnte gewesen sein:Um dies zu verbessern, kompilieren wir nur die C ++ - Dateien, die bearbeitet wurden. Dann verknüpfen wir einfach die resultierenden Objektdateien miteinander.
Um dies zu verbessern, können wir alle Objektdateiregeln durch eine einzige
.cpp.o
Regel ersetzen :Hier ist die
.cpp.o
Regel definiert , wie der Bauanyfile.o
vonanyfile.cpp
.$<
stimmt mit der ersten Abhängigkeit überein, in diesem Fallanyfile.cpp
$@
entspricht dem Ziel in diesem Fallanyfile.o
.Die anderen Änderungen im Makefile sind:
quelle
Zum Beispiel, wenn Sie Quellen kompilieren möchten, aber Objekte in einem anderen Verzeichnis haben:
Sie müssen tun:
Bei den meisten Makros sind das Ergebnis jedoch alle Objekte, denen alle Quellen folgen, wie z.
Dies wird also nichts kompilieren ^^ und Sie werden nicht in der Lage sein, Ihre Objektdateien in ein anderes Verzeichnis zu stellen :(
Die Lösung besteht darin, diese speziellen Makros zu verwenden
Dadurch wird für jede .c-Datei in SRC (src / file.c) eine .o-Datei (obj / file.o) generiert.
es bedeutet :
aber Zeilen für Zeilen STATT aller Zeilen von OBJ, gefolgt von allen Zeilen von SRC
quelle