Makefile
Dieser Artikel wurde für die folgenden Ubuntu-Versionen getestet:
Dieser Artikel ist größtenteils für alle Ubuntu-Versionen gültig.
Zum Verständnis dieses Artikels sind folgende Seiten hilfreich:
Bei make
handelt es sich um ein Werkzeug, mit dem man die Abhängigkeiten eines Build-Prozesses auflösen kann, bzw. ein Build-System. Es wird in der Regel für die Kompilierung von in C/C++ geschriebenen Programmen genutzt. Dieses Stück Software ist schon sehr alt und in unterschiedlichsten Implementierungen verfügbar, die verbreitesten sind wohl GNU make 🇬🇧 und BSD make 🇬🇧 . Leider sind die verschiedenen Varianten untereinander nicht ganz kompatibel.
Dieser Artikel beschränkt sich auf GNU make
.
Installation¶
Das benötigte Paket lässt sich unter folgendem Namen installieren [1]:
make
Befehl zum Installieren der Pakete:
sudo apt-get install make
Kurze Beschreibung¶
make
kann sehr viel mehr, als hier beschrieben werden könnte, es folgt daher lediglich eine kurze Erläuterung, um was es eigentlich geht. In einem Makefile lassen sich Regeln beschreiben, wie bestimmte "Targets" (Ziele) erstellt werden können. Diese können von anderen Zielen oder Dateien abhängen. Das Praktische dabei ist, dass bei einem Wiederanstoßen des Bau-Prozesses nur die Quelldateien neu kompiliert bzw. Ziele ausgeführt werden, die sich verändert haben, was häufig eine sehr große Zeitersparnis zur Folge hat.
Beispielsweise erstellt man eine Objektdatei aus einer Sourcedatei, indem man sie kompiliert. Dazu muss aber natürlich die Sourcedatei vorhanden sein. Eine solche Regel könnte zum Beispiel so aussehen:
1 2 | hello.o: hello.c $(CC) -c $(CFLAGS) hello.c |
Die erste Zeile besagt, dass zum Erstellen von hello.o die Datei hello.c benötigt wird. Die Zweite sagt aus, wie das Erstellen von hello.o zu bewerkstelligen ist. Sie muss mit einem Tab eingerückt werden.
Variablen werden mit $ referenziert. Dabei kennt make
verschiedene Standard-Variablen und -Makros: so beinhaltet zum Beispiel das Makro CC
in der Regel den Namen des C-Compilers (CXX
für C++). Die Optionen für den C-Compiler stehen in CFLAGS
, während CPPFLAGS
die Optionen für den C-Präprozessor enthält (nicht zu verwechseln mit den Optionen für den C++-Compiler, dafür gibt es CXXFLAGS
). Mehr dazu unter Makefiletutorial, Abschnitt "implicit rules" 🇬🇧. Diese Makros können auch in der Kommandozeile definiert werden:
make CC=gcc
Derartige Regeln kann man auch mit Wildcards versehen, so kann man eine Regel erstellen, mit der man ausdrücken kann, wie generell aus einer *.c- eine *.o Datei zu erstellen ist:
1 2 | %.o: %.c $(CC) -c $(CFLAGS) $< |
Dabei steht die „automatische“ Variable $< für den Namen der tatsächlichen Quelldatei, wie zum Beispiel hello.c.
Beispiel¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | CC = gcc LIBS = -lcurl CFLAGS = -Wall -O2 # Selbst kompilierte Programme liegen in der Regel unter /usr/local/bin/ PREFIX = /usr/local # Objekt- und Binärdatei werden in eigenem Verzeichnis abgelegt BUILD_DIR = ./build # Name des Binärprogramms NAME = cbg # $@ steht für den Zielnamen # Automatische Variable $< enthält erste Abhängigkeit $(BUILD_DIR)/cbg: $(BUILD_DIR)/cbg.o $(CC) -o $@ $< $(LIBS) # Wildcard % steht für nicht leeren String $(BUILD_DIR)/%.o: %.c $(CC) -c $(CFLAGS) $< -o $@ # Die folgenden Ziele enthält für gewöhnlich jedes Makefile install: install -D --mode=755 $(BUILD_DIR)/$(NAME) $(DESTDIR)/$(PREFIX)/bin/$(NAME) clean: rm -r $(BUILD_DIR) uninstall: rm $(DESTDIR)/$(PREFIX)/bin/$(NAME) |
Damit ist es nun möglich, die einzelnen Ziele zu erstellen, wozu man ggf. Root-Rechte [4] benötigt:
make sudo make install make clean sudo make uninstall
Wird kein Ziel angegeben, so wird das erste Ziel erstellt, in obigen Beispiel also die Binärdatei cbg. Man kann sich auch lediglich die Befehle des Bau-Prozesses ausgeben lassen, indem man make
mit der Option -n
aufruft.
Links¶