Makefile-Syntax verstehen: Häufige Probleme und Lösungen (einschließlich „Fehlender Operator“ und „Einstiegspunkt nicht gefunden“)

Makefile Syntax Verstehen Haufige Probleme Und Losungen Einschliesslich Fehlender Operator Und Einstiegspunkt Nicht Gefunden



So wie eine Codedatei eine oder mehrere Codezeilen als Inhalt enthält, damit sie sinnvoll ist, wird das grundlegende Makefile aus Variablen, Regeln und Zielen erstellt. Abgesehen davon gibt es noch andere Faktoren, die notwendig sind, um ein vollständiges Makefile ohne Probleme zu erstellen. In diesem Leitfaden besprechen wir die grundlegende Makefile-Syntax und die häufigsten Probleme beim Schreiben eines Makefiles und bieten Lösungen zur Behebung dieser Probleme.

Grundlegendes zur Makefile-Grundsyntax

Um mit der Erstellung eines Makefiles zu beginnen, erklären wir die grundlegenden Eigenschaften eines Makefiles anhand des Makefile-Codebeispiels. Um eine ausführbare Datei zu erhalten, müssen die folgenden Syntaxeigenschaften in den Makefile-Inhalt aufgenommen werden:





Variable s: Basisdaten zum Speichern von Objekten, die für die Verwendung im Makefile erforderlich sind. Diese Variablen werden verwendet, um einen Compiler, Flags, Quelldateien, Objektdateien und Zieldateien anzugeben. Im folgenden Beispiel-Makefile gibt es insgesamt fünf Variablen: CXX (zum Festlegen eines C++-Compilers), CXXFLAGSc (Compiler-Flags), TARGET (zum Festlegen des Namens einer ausführbaren Zieldatei) und SRCS (zum Festlegen einer Quellcodedatei). , OBJS (um die Objektdateien zu enthalten, die über die Quellcodedatei generiert werden).



Ziele: Eine erwartete Ausgabe, die aus der Quelle erstellt werden soll. Es kann sich um eine Zieldatei oder einen beliebigen symbolischen Namen handeln: „all“ ist das Standardziel, das über die Variable „TARGET“ erstellt werden soll, „$TARGET“ hängt von den Variablen „OBJS“ ab und „clean“ target entfernt das Ziel und Objektdateien aus dem Arbeitsverzeichnis.



Regeln und Build-Befehle: Satz grundlegender Anweisungen, die ausgeführt werden müssen, um ein Ziel aus der Quelldatei oder Abhängigkeiten zu erstellen. Beispielsweise zeigt die Regel „%.o: %.cpp“ an, dass die Datei mit der Erweiterung „cpp“ zum Erstellen einer Objektdatei mit der Erweiterung „o“ verwendet wird, während beide Dateien denselben Namen enthalten. Andererseits der Build-Befehl $(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJS) wird verwendet, um eine Objektdatei und eine neue Zieldatei miteinander zu verknüpfen. Auf die gleiche Weise erfolgt der Build-Befehl $(CXX) $(CXXFLAGS) -c $< -o $@ Kompiliert die Quelldatei in eine Objektdatei.





Abhängigkeiten: Abhängigkeiten sind immer vorhanden, wenn Sie ein Makefile erstellen möchten. Beispielsweise hängt das Ziel „alle“ von der Variablen „TARGET“ ab, während „TARGET“ von der Variablen „OBJS“ abhängt. Gleichzeitig ist die Variable „OBJS“ über die Variable „SRCS“ von der Quelldatei abhängig.

Kommentare: Für den Fall, dass Sie eine Datei nach längerer Zeit verwenden, werden in der Regel menschenverständliche Anweisungen verwendet, um den Zweck der Codezeile zu erläutern. Im folgenden Makefile verwenden wir die Kommentare, die mit dem „#“-Zeichen beginnen, um jede Zeile zu erklären.



CXX = g++
CXXFLAGS = -std =c++ elf -Wand
ZIEL = Neu
SRCS = main.cpp
OBJS = $ ( SRCS:.cpp=.o )
alle: $ ( ZIEL )
$ ( ZIEL ) : $ ( OBJS )
$ ( CXX ) $ ( CXXFLAGS ) $ ( ZIEL ) $ ( OBJS )
% .Ö: % .cpp
$ ( CXX ) $ ( CXXFLAGS ) -C $ < $ @
sauber:
rm -F $ ( ZIEL ) $ ( OBJS )

Häufige Probleme und Lösungen

Beim Schreiben eines Makefiles ist es notwendig, jedes noch so kleine Detail zu berücksichtigen, um am Ende die gewünschte Ausgabe zu erhalten. Beim Erstellen einer Makefile-Datei stoßen Benutzer häufig auf einige häufige Probleme. In diesem Abschnitt werden wir diese Probleme diskutieren und die möglichen Lösungen wie folgt vorschlagen:

1: Keine Variablen verwenden

Die Verwendung der Variablen in einem Makefile ist ein Muss, da sie zum Festlegen der Compiler, Ziele, Quelldateien usw. erforderlich ist. Das häufigste Problem, das auftreten kann, ist die Verwendung keiner Variablen in einem Makefile. Stellen Sie daher sicher, dass Sie die wesentlichen Variablen wie CXX, CXXFLAGSc (Compiler-Flags), TARGET, SRCS und OBJS im vorherigen Beispiel-Makefile verwenden.

2: Problem mit fehlendem Trennzeichen

Beim Schreiben eines Makefiles ist es notwendig, die Einrückungsregeln sehr sorgfältig zu berücksichtigen, da die Verwendung von Leerzeichen anstelle von Tabulatoren zu einem Problem mit „fehlenden Trennzeichen“ während der Ausführung der „make“-Anweisung führt. Beispielsweise fügen wir das Leerzeichen am Anfang einer Regel in Zeile 13 hinzu und entfernen den Tabulator.

$ ( ZIEL ) : $ ( OBJS )
$ ( CXX ) $ ( CXXFLAGS ) $ ( ZIEL ) $ ( OBJS )

Bei der Ausführung der „make“-Abfrage erhalten wir in Zeile 13 die Fehlermeldung „fehlendes Trennzeichen“ und die Datei wird nicht mehr ausgeführt. Um dieses Problem zu vermeiden, achten Sie darauf, „Tabulator“ anstelle von Leerzeichen zu verwenden.

machen

Um dieses Problem zu vermeiden, stellen Sie sicher, dass Sie „Tabulator“ anstelle von Leerzeichen verwenden, wie in der folgenden Abbildung dargestellt:

$ ( ZIEL ) : $ ( OBJS )
$ ( CXX ) $ ( CXXFLAGS ) $ ( ZIEL ) $ ( OBJS )

3: Problem „Einstiegspunkt nicht gefunden“.

Dieser Fehler tritt meist aufgrund der Quelldatei auf und nicht aufgrund des Makefiles, wie zum Beispiel, wenn Sie die Verwendung der Funktion „main()“ in der Quellcodedatei verpassen. Beispielsweise ersetzen wir die Funktionsdefinition main() durch eine einfache benutzerdefinierte Funktionsdeklaration.

#include
int zeigen ( ) {
char v;
std::cout << „Geben Sie einen Wert ein:“ ;
std::cin >> In;
std::cout << In << std::endl;
zurückkehren 0 ;
}

Beim Ausführen der „make“-Anweisung an der Eingabeaufforderung von Windows stoßen wir auf den „undefinierten Verweis auf ‚WinMain‘“. Dies liegt daran, dass der Compiler keinen Einstiegspunkt findet, um mit der Ausführung der C++-Datei zu beginnen. Um dieses Problem zu beheben, ersetzen Sie „show“ durch „main“.

4: Verwendung falscher Erweiterungen

Manchmal verwendet ein Benutzer unbeabsichtigt die falschen Erweiterungen für eine Quelldatei, die im Makefile verwendet werden soll. Die Verwendung der falschen Erweiterung führt zu Laufzeitfehlern, d. h. es gibt keine Regel zum Erstellen eines Ziels. Wir erstellen ein Makefile, um die ausführbare Datei und die Objektdatei für die C++-Datei zu erstellen. In der siebten Zeile versehen wir die Quelldatei mit der Erweiterung „c“.

CXX := g++
CXXFLAGS := -std =c++ elf -Wand
ZIEL = neu
SRCS = main.c
OBJS = $ ( SRCS:.cpp=.o )
Alle: $ ( ZIEL )
$ ( ZIEL ) : $ ( OBJS )

Das Ausführen der Anweisung „make“ führt zum Fehler „Keine Regel zum Erstellen des Ziels ‚main.c‘“. Um dieses Problem zu vermeiden, stellen Sie sicher, dass Sie die richtige Quelldateierweiterung verwenden.

machen

5: Fehlende Abhängigkeiten

Beim Schreiben eines Makefiles sollten Sie alle Abhängigkeiten für eine Quelldatei einbeziehen, um die gewünschte Ausgabe zu erhalten. Unsere C++-Codedatei verwendet beispielsweise die Datei „myheader.h“ als Abhängigkeit. Daher erwähnen wir es in der C++-Codedatei wie folgt:

#include
#include „myheader.h“
int zeigen ( ) {
char v;
std::cout << „Geben Sie einen Wert ein:“ ;
std::cin >> In;
std::cout << In << std::endl;
zurückkehren 0 ;
}

Innerhalb der Makefile ignorieren wir absichtlich die Verwendung der Datei „myheader.h“ innerhalb der Build-Regel, die in Zeile 9 geschrieben wird.

% .Ö: % .cpp
$ ( CXX ) $ ( CXXFLAGS ) -C $ < $ @

Wenn wir nun die Anweisung „make“ verwenden, stoßen wir auf den Fehler „Für ‚alle‘ ist nichts zu tun“.

machen

% .Ö: % .cpp myheader.h
$ ( CXX ) $ ( CXXFLAGS ) -C $ < $ @

Um das besagte Problem zu vermeiden und den Quellcode erfolgreich auszuführen, erwähnen Sie den Dateinamen „myheader.h“ in der neunten Zeile des Makefiles, wie im Folgenden dargestellt:

Abschluss

In diesem Handbuch haben wir die Syntax von Makefile anhand der erforderlichen Inhalte wie Variablen, Build-Befehle, Regeln usw. ausführlich erklärt. Das Codebeispiel ist enthalten, um die Syntax klarer zu erläutern. Am Ende haben wir einige regelmäßige Probleme und deren Lösungen besprochen, auf die ein Benutzer beim Erstellen eines Makefiles stoßen kann.