Warum Makefiles Sie vor dem Kopieren und Einfügen von GCC-Befehlen bewahren

12

Seien wir ehrlich. Das manuelle Eintippen langer „gcc“-Kompilierungsbefehle ist mühsam. Es wird schnell schlimmer, wenn Ihre Codebasis wächst, mehrere Bibliotheken importiert und Sie ständig Dinge optimieren. Am Ende haben Sie einen Kopier-Einfüge-Albtraum, der verschwindet, wenn Sie eine Flagge verpassen.

Geben Sie makefiles ein.

Sie existieren aus einem Grund: um zu verhindern, dass Sie immer wieder dieselbe Kompilierungssequenz manuell eingeben. Anstatt sich die genauen Flags und die Reihenfolge der Objektdateien zu merken, schreiben Sie ein Rezept. Dann geben Sie einfach „make“ ein.

Wie ein Makefile tatsächlich funktioniert

Sie beginnen mit der Erstellung einer Datei mit dem wörtlichen Namen „makefile“. Keine Verlängerung. Nur der Name. Im Inneren definieren Sie Abhängigkeiten.

Hier ist eine Grundstruktur für ein kleines C-Projekt:

„makefile
main: main.o util.o
gcc -o main main.o util.o

main.o: main.c util.h
gcc -c -g main.c

util.o: util.c util.h
gcc -c -g util.c

Beachten Sie die Einrückung. Hier stolpern Anfänger. Das Leerzeichen vor „gcc“? Es muss ein Tabulatorzeichen sein. Nicht acht Leerzeichen. Eine Registerkarte. Wenn Sie Leerzeichen verwenden, gibt „make“ einen kryptischen Fehler aus und Sie werden sich zehn Minuten lang fragen, warum Ihre Syntax für das menschliche Auge gut aussieht, für die Maschine jedoch nicht. Jede Befehlszeile unter einer Abhängigkeit muss mit einem Tabulator beginnen. Die Abhängigkeitsdefinitionen selbst müssen linksbündig sein. Keine Ausnahmen.

Die Logik der Abhängigkeiten

Ein Makefile hat zwei Arten von Zeilen. Die ersten sind Abhängigkeitslinien. Diese sehen aus wie „Ziel: Voraussetzungen“.

main.o: main.c util.h

Das bedeutet: „Ich brauche „main.o“. Um es zu bekommen, brauche ich „main.c“ und „util.h“.

Der zweite Typ ist die ausführbare Zeile. Es befindet sich unter der Abhängigkeit und beginnt mit einem Tab. Es ist der Befehl, der ausgeführt wird, wenn „make“ entscheidet, dass eine Neuerstellung erforderlich ist.

Das System funktioniert nach einem einfachen Prinzip: Wenn eine Datei auf der rechten Seite des Doppelpunkts neuer ist als die Datei auf der linken Seite, führen Sie die folgenden Befehle aus. „util.h“ ändern? „make“ sieht es, weiß, dass „main.o“ und „util.o“ davon abhängen, und erstellt sie neu. Es automatisiert die Logik.

Die Zielregel

Es gibt eine goldene Regel für den Anfang Ihres Makefiles. Das erste aufgeführte Ziel ist das, das „make“ standardmäßig zu erstellen versucht.

Im obigen Beispiel ist „main“ die erste Zeile. Wenn Sie also „make“ ohne Argumente ausführen, wird die endgültige ausführbare Datei erstellt.

main: main.o util.o
gcc -o main main.o util.o

Wenn Sie „main.o“ ändern, wird die Neuerstellung von „main“ ausgelöst. Wenn Sie „main.c“ ändern, löst es „main.o“ aus, das dann „main“ auslöst. Es ist eine Kettenreaktion. Sie müssen es nicht verwalten. Sie bearbeiten einfach Ihren Quellcode und führen „make“ aus.

Was ist, wenn ich kein Unix verwende?

Wenn Sie Windows verwenden oder eine IDE wie Visual Studio oder Xcode verwenden, wird möglicherweise kein „Makefile“ im herkömmlichen Sinne angezeigt. Keine Panik. Ihr Compiler verfügt wahrscheinlich über eine entsprechende Funktionalität.

Integrierte Entwicklungsumgebungen verfügen oft über Build-Systeme unter der Haube. Suchen Sie nach „Build-Konfigurationen“ oder „Projekteigenschaften“. Sie machen dasselbe: Abhängigkeiten verfolgen und nur das neu kompilieren, was sich geändert hat. Wenn Sie jedoch bei der Befehlszeile bleiben, ist „make“ der Standard.

Das größere Bild

Die Verwendung von „make“ ist nicht der Fall