Das Kompilieren von Quelltext-Dateien kann mit dem Programm make gesteuert werden. Dies ist vor allem dann sinnvoll, wenn es sich um ein großes Projekt handelt bei dem die Kompilierung aus vielen einzelnen Schritten und Abhängigkeiten besteht. Die einzelnen Schritte können zum Beispiel separate Kompilierungen oder andere Dateioperationen wie Kopieren und Löschen sein. Abhängigkeiten können zum Beispiel bedingte Kompilierungen sein. Diese Schritte und Abhängigkeiten werden in ein Makefile zusammengefasst, welches dann vom Programm make verarbeitet wird.
Compiler und Linker
Hier sehen wir eine Veranschaulichung der Verwendung von Makefiles – mehrere Dateien tragen zur kompilierten Programm bei. Quelltext-Dateien werden vom Compiler in Objektdateien bzw. Programmmodule übersetzt. Der Linker verbindet die Programmmodule zu einem Programm.
Makefile erstellen
Zum nachvollziehen des obigen Beispiels erstellt man die drei Dateien main.c, foo.c und bar.c mit beliebigen C-Code, Funktionsnamen sollten sich aber nicht in die Quere kommen (Beispiel). Dazu schreiben wir jetzt als vierte Datei noch das Makefile, diese trägt immer den Namen makefile.
Im Makefile werden sogenannte Ziele definiert, auch target genannt, welche mit einem Doppelpunkt dargestellt werden. Das erste Ziel ist immer das Hauptziel, wir finden es hier in der ersten Zeile: prog besteht aus den Objektdateien main.o, foo.o und bar.o. Darunter findet mit gcc die Kompilierung dieser Dateien statt; die Ausgabe erfolgt in die Datei prog. Darunter sind noch die benötigten Ziele für die Objektdateien, zum Beispiel wird main.o aus main.c erstellt. Der Compiler wird hierbei mit dem Parameter -c gestartet, d.h. es wird nur kompiliert und nicht gelinkt. Das Linken geschieht im Hauptziel.
Wichtig ist hier, dass die Compiler-Aufrufe mit einem Tabulator eingerückt werden müssen.
prog: main.o foo.o bar.o gcc -o prog main.o foo.o bar.o main.o: main.c gcc -c main.c foo.o: foo.c gcc -c foo.c bar.o: bar.c gcc -c bar.c
Das Makefile speichern wir mit dem Namen makefile im gleichen Verzeichnis wie die Quelltext-Dateien. Ein Aufruf des Programms make genügt. Hier sehen wir die Bildschirmausgabe zu den folgenden Aktionen:
- Verzeichnis-Inhalt vor make
- Aufruf von make
- Verzeichnis-Inhalt nach make mit Objektdateien und Programm-Datei
- Aufruf der Programm-Datei prog (Ausgabe analog der Beispieldateien)
# ls -al total 24 drwxr-xr-x 2 4096 2008-01-14 01:41 . drwxr-xr-x 3 4096 2008-01-14 00:35 .. -rw-r--r-- 1 51 2008-01-14 01:19 bar.c -rw-r--r-- 1 51 2008-01-14 01:19 foo.c -rw-r--r-- 1 79 2008-01-14 01:18 main.c -rw-r--r-- 1 144 2008-01-14 01:17 makefile # make gcc -c main.c gcc -c foo.c gcc -c bar.c gcc -o prog main.o foo.o bar.o # ls -al total 44 drwxr-xr-x 2 4096 2008-01-14 01:41 . drwxr-xr-x 3 4096 2008-01-14 00:35 .. -rw-r--r-- 1 51 2008-01-14 01:19 bar.c -rw-r--r-- 1 832 2008-01-14 01:41 bar.o -rw-r--r-- 1 51 2008-01-14 01:19 foo.c -rw-r--r-- 1 832 2008-01-14 01:41 foo.o -rw-r--r-- 1 79 2008-01-14 01:18 main.c -rw-r--r-- 1 928 2008-01-14 01:41 main.o -rw-r--r-- 1 144 2008-01-14 01:17 makefile -rwxr-xr-x 1 6884 2008-01-14 01:41 prog # ./prog main foo bar