627 Stimmen

Was bedeuten die makefile-Symbole $@ und $<?

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 bedeuten die $@ y $< was genau tun?

800voto

bdonlan Punkte 213545

$@ ist der Name des zu erzeugenden Ziels, und $< die erste Voraussetzung (normalerweise eine Quelldatei). Eine Liste all dieser speziellen Variablen finden Sie in der GNU Make-Handbuch .

Betrachten Sie zum Beispiel die folgende Erklärung:

all: library.cpp main.cpp

In diesem Fall:

  • $@ wertet aus zu all
  • $< wertet aus zu library.cpp
  • $^ wertet aus zu library.cpp main.cpp

147voto

alex Punkte 10227

Desde Projekte verwalten mit GNU Make, 3. Auflage, S. 16 (es ist unter GNU-Lizenz für freie Dokumentation ):

Automatische Variablen werden festgelegt durch make nachdem eine Regel erfüllt wurde. Sie ermöglichen den Zugriff auf Elemente aus den Ziel- und Vorbedingungslisten, so dass müssen Sie keine Dateinamen explizit angeben. Sie sind sehr nützlich, um Code-Duplizierung zu vermeiden, sind aber entscheidend bei der Definition allgemeineren Musterregeln.

Es gibt sieben automatische "Kern"-Variablen:

  • $@ : Der Dateiname, der das Ziel darstellt.

  • $% : Das Element filename einer Archivmitgliedsangabe.

  • $< : Der Dateiname der ersten Voraussetzung.

  • $? : Die Namen aller Voraussetzungen, die neuer sind als das Ziel, durch Leerzeichen getrennt.

  • $^ : Die Dateinamen aller Voraussetzungen, getrennt durch Leerzeichen. Diese Liste wurden doppelte Dateinamen entfernt, da für die meisten Verwendungen, wie Kompilieren, Kopieren usw., sind Duplikate nicht erwünscht.

  • $+ : Ähnlich wie $^ Hier sind die Namen aller Voraussetzungen getrennt durch Leerzeichen getrennt, außer dass $+ enthält Duplikate. Diese Variable wurde für spezielle Situationen geschaffen, wie z.B. für Argumente an Linker, bei denen doppelte Werte eine Bedeutung haben.

  • $* : Der Stamm des Zieldateinamens. Ein Stamm ist normalerweise ein Dateiname ohne seine Endung. Von seiner Verwendung außerhalb von Musterregeln wird entmutigt.

Darüber hinaus hat jede der oben genannten Variablen zwei Varianten für Kompatibilität mit anderen Herstellern. Eine Variante gibt nur den Verzeichnis Teil des Wertes zurück. Dies wird durch Anhängen eines "D" an das Symbol, $(@D) , $(<D) , usw. Die andere Variante gibt nur den Datei Teil des Wertes zurück. Dies wird durch Anhängen eines "F" an das Symbol, $(@F) , $(<F) , usw. Beachten Sie, dass diese Variantennamen mehr als ein Zeichen lang sind und daher in Klammern gesetzt werden müssen. GNU make bietet eine besser lesbare Alternative mit den Funktionen dir und notdir Funktionen.

103voto

dexterous Punkte 6004

El $@ y $< werden genannt automatische Variablen . Die Variable $@ steht für den Namen des Ziels und $< ist die erste Voraussetzung für die Erstellung der Ausgabedatei.
Zum Beispiel:

hello.o: hello.c hello.h
         gcc -c $< -o $@

Hier, hello.o ist die Ausgabedatei. Das ist es, was $@ erweitert sich zu. Die erste Abhängigkeit ist hello.c . Das ist es, was $< erweitert sich auf.

El -c Flagge erzeugt die .o Datei; siehe man gcc für eine ausführlichere Erklärung. Die -o gibt die zu erstellende Ausgabedatei an.

Weitere Einzelheiten können Sie lesen dieser Artikel auf linoxide über Linux Makefiles .

Sie können auch die GNU make Handbücher . Dadurch wird es einfacher, Makefiles zu erstellen und sie zu debuggen.

Wenn Sie diesen Befehl ausführen, wird die Makefile-Datenbank ausgegeben:

make -p

45voto

Eric Punkte 2082

El $@ y $< sind spezielle Makros.

Wo:

$@ ist der Dateiname des Ziels.

$< ist der Name der ersten Abhängigkeit.

29voto

Stephen Quan Punkte 16456

Das Makefile baut die hello ausführbar, wenn einer der folgenden Punkte zutrifft main.cpp , hello.cpp , factorial.cpp geändert. Das kleinstmögliche Makefile zum Erreichen dieser Spezifikation hätte lauten können:

hello: main.cpp hello.cpp factorial.cpp
    g++ -o hello main.cpp hello.cpp factorial.cpp
  • Pro: sehr leicht zu lesen
  • Nachteile: Wartungsalptraum, Verdoppelung der C++-Abhängigkeiten
  • Nachteil: Effizienzproblem, wir kompilieren alle C++ neu, auch wenn nur eines geändert wurde

Um dies zu verbessern, kompilieren wir nur die C++-Dateien, die bearbeitet wurden. Dann verknüpfen wir einfach die resultierenden Objektdateien miteinander.

OBJECTS=main.o hello.o factorial.o

hello: $(OBJECTS)
    g++ -o hello $(OBJECTS)

main.o: main.cpp
    g++ -c main.cpp

hello.o: hello.cpp
    g++ -c hello.cpp

factorial.o: factorial.cpp
    g++ -c factorial.cpp
  • Pro: Behebung des Effizienzproblems
  • Nachteile: neuer Wartungsalptraum, möglicher Tippfehler bei den Regeln für Objektdateien

Um dies zu verbessern, können wir alle Objektdatei-Regeln durch eine einzige ersetzen .cpp.o Regel:

OBJECTS=main.o hello.o factorial.o

hello: $(OBJECTS)
    g++ -o hello $(OBJECTS)

.cpp.o:
    g++ -c $< -o $@
  • pro: zurück zu einem kurzen Makefile, das einigermaßen leicht zu lesen ist

Hier wird die .cpp.o Regel definiert, wie man anyfile.o de anyfile.cpp .

  • $< entspricht in diesem Fall der ersten Abhängigkeit, anyfile.cpp
  • $@ in diesem Fall mit dem Ziel übereinstimmt, anyfile.o .

Die anderen Änderungen im Makefile sind:

  • Erleichterung des Compilerwechsels von g++ zu einem beliebigen C++-Compiler.
  • Erleichterung der Änderung der Compiler-Optionen.
  • Erleichterung der Änderung der Linker-Optionen.
  • Erleichterung der Änderung der C++-Quelldateien und der Ausgabe.
  • Es wurde eine Standardregel "all" hinzugefügt, die als Schnellprüfung dient, um sicherzustellen, dass alle Quelldateien vorhanden sind, bevor versucht wird, die Anwendung zu erstellen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X