make erledigt das, in dem in einer Konfigurationsdatei Ziele und Abhängigkeiten definiert werden. Das Ziel einer solchen Datei ist die Kompilierung eines Programms. Dieses Programm hängt ab von den Objekt-Dateien, die wiederum abhängen von den jeweiligen Quellcode-Dateien. Der Vorteil bei der Verwendung von make ist unter anderem, daß die Änderungszeit von bereits bestehenden Objektdateien mit den jeweiligen Quellcode-Dateien verglichen werden. Normalerweise sind die Objektdateien immer jünger als die Quellcode-Dateien. In diesem Fall werden die Quellcode-Dateien nicht noch einmal kompiliert. Ist die Quellcode-Datei aber jünger als die Objektdatei, so wurde sie wahrscheinlich seit dem letzten Kompiliervorgang verändert und wird deshalb bei diesem Lauf erneut kompiliert. Dadurch sparen Sie enorm viel Zeit, da bei kleinen Änderungen keine komplette Neukompilierung notwendig ist.
Am Beispiel des Programms aus Abschnitt 14.1.2 möchte ich Ihnen den Aufbau einer solchen Make-Datei zeigen.
Das Ziel ist die Erstellung des Programms gruss. Dieses besteht aus den Objekt-Dateien start.o und hallo.o. Wir können also die Beziehung zwischen dem Programm und den Objekt-Dateien so bezeichnen:
gruss: start.o hallo.o
Die Objektdateien start.o und hallo.o hängen mit den Quellcode-Dateien start.c und hallo.c zusammen. In Kurzform ausgedrückt ergibt das:
start.o: start.c hallo.o: start.c
Zu diesen Abhängigkeiten gehören die ausführenden Kommandos, die hinzugefügt werden müssen.
gcc -c start.c gcc -c hallo.c gcc -o gruss start.o hallo.o
Um die Make-Datei etwas unabhängiger vom Kompiler zu gestalten, kann sein Name durch eine Variable ersetzt werden.
comp=gcc
Wenn wir alles kombinieren, erhalten wir unsere Konfigurationsdatei Makefile. Achten Sie auf jeden Fall darauf, daß die Einrückung durch einen Tabulator erfolgt.
1: comp = gcc 2: 3: gruss: start.o hallo.o 4: $(comp) -o gruss start.o hallo.o 5: 6: start.o: start.c 7: $(comp) -c start.c 8: 9: hallo.o: hallo.c 10: $(comp) -c hallo.c
Nach der Erstellung der Datei Makefile, nach der make im Normalfall sucht, führen wir den Befehl make aus. Dabei sollten eventuell vorhandene Dateien gruss, start.o und hallo.o vorher entfernt worden sein.
barclay@enterprise:~/cprog> vi Makefile barclay@enterprise:~/cprog> make gruss gcc -c start.c gcc -c hallo.c gcc -o gruss start.o hallo.o barclay@enterprise:~/cprog> make gruss make: `gruss' is up to date. barclay@enterprise:~/cprog>
Beim erneuten Ausführen von make erkennt das Programm, daß keine Änderungen vorgenommen worden und meldet dies dem Benutzer. Werden allerdings Quellcode-Dateien bearbeitet, so ist ihr Änderungsdatum jünger als das der Objekt-Datei. In diesem Fall wird neu kompiliert. Allerdings werden nur die Abhängigkeiten abgearbeitet, die von den Änderungen betroffen waren.
barclay@enterprise:~/cprog> vi hallo.c barclay@enterprise:~/cprog> ls -l insgesamt 48 -rw-r--r-- 1 barclay users 146 Jan 22 22:09 Makefile -rw-r--r-- 1 barclay users 13719 Jan 22 22:09 gruss -rw-r--r-- 1 barclay users 94 Jan 22 22:18 hallo.c -rw-r--r-- 1 barclay users 980 Jan 22 22:09 hallo.o -rw-r--r-- 1 barclay users 31 Jan 22 21:15 start.c -rw-r--r-- 1 barclay users 812 Jan 22 22:09 start.o barclay@enterprise:~/cprog> make gruss gcc -c hallo.c gcc -o gruss start.o hallo.o barclay@enterprise:~/cprog>
Dieses Makefile ist nur ein schwaches Beispiel für die Möglichkeiten, die in dem Programm make stecken. Diese Möglichkeiten sprengen aber den Rahmen des Levels 1 der LPI-Prüfung und dieses Kapitels.