Im Katalog suchen

Linux - Wegweiser zur Installation & Konfiguration, 3. Auflage

Online-Version

Copyright © 2000 by O'Reilly Verlag GmbH & Co.KG

Bitte denken Sie daran: Sie dürfen zwar die Online-Version ausdrucken, aber diesen Druck nicht fotokopieren oder verkaufen. Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

Wünschen Sie mehr Informationen zu der gedruckten Version des Buches Linux - Wegweiser zur Installation & Konfiguration oder wollen Sie es bestellen, dann klicken Sie bitte hier.


vorheriges Kapitel Inhaltsverzeichnis Stichwortverzeichnis nächstes Kapitel

Makefiles

Irgendwann in Ihrem Zusammenleben mit Linux werden Sie wahrscheinlich auf make stoßen - selbst wenn Sie gar nicht programmieren möchten. Sicherlich werden Sie einmal den Kernel ändern und neu erstellen, und dazu brauchen Sie make. Wenn Sie Glück haben, müssen Sie sich nicht durch die Makefiles wühlen - wir wollten uns mit diesem Buch allerdings auch an die Pechvögel wenden. In diesem Abschnitt wollen wir Ihnen deshalb so viel von der feinsinnigen make-Syntax vermitteln, daß ein Makefile Sie nicht mehr einschüchtern kann.

Icon

[55] make

In einigen unserer Beispiele werden wir das aktuelle Makefile für den Linux-Kernel benutzen. Darin sind viele der mächtigen Erweiterungen enthalten, die zur GNU-Version von make gehören; das gibt uns Gelegenheit, sowohl einige dieser Erweiterungen als auch das Standard-make zu beschreiben. In Managing Projects with make von Andrew Oram und Steve Talbott finden Sie eine gute Einführung in make.

Icon

[56] GNU make

Die GNU-Erweiterungen werden in der Manpage zu GNU-make ausführlich beschrieben.

Die meisten Benutzer betrachten make als ein Hilfsmittel, um aus Quelltexten Objektdateien und Bibliotheken zu erzeugen sowie Objektdateien zu ausführbaren Dateien zu machen. Wenn man es abstrakter betrachtet, ist make ein vielseitiges Programm, das aus gewissen Abhängigkeiten (prerequisites) bestimmte Ziele (targets) erzeugt. Das Ziel kann eine ausführbare Datei sein, ein PostScript-Dokument oder was auch immer. Die Abhängigkeiten können C-Code, eine Textdatei im -Format usw. sein.

Es ist nicht schwierig, einfache Shell-Skripten zu schreiben, die gcc-Befehle aufrufen, um ausführbare Programme zu erzeugen. make dagegen kann noch mehr: Es weiß, welche Ziele neu erstellt werden müssen und welche nicht. So muß beispielsweise eine Objektdatei nur dann erneut kompiliert werden, wenn die zugrundeliegende Quelldatei geändert wurde.

Ein Beispiel: Nehmen wir an, daß ein Programm aus drei C-Quelltexten besteht. Sie könnten nach jeder Änderung in einer der Quelldateien mit dem Befehl

papaya$ gcc -o foo foo.c bar.c baz.c

alle drei Dateien erneut kompilieren, um eine neue ausführbare Datei zu erzeugen. Das wäre allerdings eine große Zeitverschwendung, da Sie ja nur eine Quelldatei geändert haben. (Dies gilt ganz besonders dann, wenn das fragliche Programm aus mehr als nur einer Handvoll von Quelldateien besteht.) Was Sie wirklich erreichen möchten, ist die Neukompilierung der einen geänderten Datei zu einer Objektdatei sowie das erneute Binden aller Objektdateien zur ausführbaren Datei. make kann diesen Vorgang für Sie automatisieren.

Was make macht

Grundsätzlich unterstützt make Sie dabei, eine Zieldatei in kleinen Schritten zu erzeugen. Wenn ein Programm aus vielen Quellcodedateien besteht, können Sie eine davon ändern und eine neue ausführbare Datei erzeugen, ohne alle Quelldateien neu kompilieren zu müssen. make erreicht diese Flexibilität, indem es sich merkt, welche Dateien zu Ihrem Ziel gehören.

Hier zeigen wir Ihnen ein triviales Makefile. Nennen Sie es makefile oder Makefile, und speichern Sie die Datei in dem Verzeichnis ab, in dem auch die Quellcodedateien stehen.

edimh: main.o edit.o gcc -o edimh main.o edit.o main.o: main.c gcc -c main.c edit.o: edit.c gcc -c edit.c

Dieses Makefile erzeugt aus den beiden Quelldateien main.c und edit.c ein Programm namens edimh. Sie können ein Makefile nicht nur für die C-Programmierung einsetzen; es können beliebige Befehle enthalten sein.

Das Makefile besteht aus drei Einträgen. Jeder davon enthält eine Abhängigkeiten-Zeile, aus der hervorgeht, wie eine Datei erzeugt wird. Die erste Zeile besagt also, daß edimh (der Name vor dem Doppelpunkt) aus den beiden Objektdateien main.o und edit.o (den Namen hinter dem Doppelpunkt) erzeugt wird. Für make bedeutet das, daß es die folgende gcc-Zeile immer dann ausführen soll, wenn eine dieser beiden Objektdateien geändert wurde. Die Zeilen, in denen Befehle stehen, müssen mit einem Tabulator beginnen (und nicht mit Leerzeichen).

Der Befehl

papaya$ make edimh

führt die gcc-Zeile aus, wenn derzeit keine Datei namens edimh vorhanden ist. Diese Zeile wird aber auch dann ausgeführt, wenn edimh existiert, aber eine der Objektdateien neuer ist. In diesem Fall ist edimh das Ziel. Die Dateien hinter dem Doppelpunkt nennt man entweder Abhängigkeiten oder Vorbedingungen.

Die nächsten beiden Einträge erfüllen denselben Zweck für die Objektdateien. Die Datei main.o wird erzeugt, wenn sie noch nicht existiert oder wenn die zugehörige Quelldatei main.c neuer ist. edit.o wird aus edit.c erzeugt.

Woher weiß make, ob eine Datei neu ist? Es liest den Zeitstempel, den das Dateisystem jeder Datei zuordnet. Mit dem Befehl ls -l können Sie sich den Zeitstempel anzeigen lassen. Da diese Zeiten auf eine Sekunde genau sind, kann make zuverlässig ablesen, ob Sie eine Quelldatei nach dem letzten Compiler-Lauf geändert haben oder ob Sie eine Objektdatei kompiliert haben, nachdem die letzte Version der ausführbaren Datei erzeugt wurde.

Lassen Sie uns dieses Makefile testen und beobachten, was passiert:

papaya$ make edimh gcc -c main.c gcc -c edit.c gcc -o edimh main.o edit.o

Wenn wir jetzt main.c editieren und den Befehl noch einmal aufrufen, werden nur die notwendigen Dateien neu erzeugt, und wir sparen etwas Zeit:

papaya$ make edimh gcc -c main.c gcc -o edimh main.o edit.o

Es spielt keine Rolle, in welcher Reihenfolge die drei Einträge im Makefile stehen. make findet heraus, welche Dateien von welchen anderen Dateien abhängig sind, und führt die Befehle in der richtigen Reihenfolge aus. Es ist bequemer, den Eintrag für edimh an die erste Stelle zu setzen, weil das die Datei ist, die per Voreinstellung erzeugt wird. Mit anderen Worten: Wenn Sie make aufrufen, erhalten Sie dasselbe Ergebnis wie mit make edimh.

Sehen wir uns ein etwas längeres Makefile an. Versuchen Sie herauszubekommen, was darin passiert:

install: all mv edimh /usr/local mv readimh /usr/local all: edimh readimh readimh: read.o edit.o gcc -o readimh main.o read.o edimh: main.o edit.o gcc -o edimh main.o edit.o main.o: main.c gcc -c main.c edit.o: edit.c gcc -c edit.c read.o: read.c gcc -c read.c

Als erstes sehen wir das Ziel install. Daraus wird nie eine Datei erzeugt werden; man nennt das ein unechtes Ziel (phony target), weil dieser Eintrag nur existiert, damit die Befehle darunter ausgeführt werden können. Bevor install ausgeführt wird, muß zuerst all aufgerufen werden, weil install von all abhängig ist. (Erinnern Sie sich, daß die Reihenfolge der Einträge keine Rolle spielt.)

Als nächstes wendet sich make also dem Ziel all zu. Dahinter stehen keine Befehle (das ist in Ordnung so), aber all ist abhängig von edimh und readimh. Dabei handelt es sich um echte Dateien; es sind zwei ausführbare Programme. make geht also die Liste der Abhängigkeiten so lange durch, bis es zu den .c-Dateien kommt, die von nichts weiter abhängig sind. Anschließend wird make jedes einzelne Ziel gewissenhaft neu erzeugen.

Lassen Sie uns einen Testlauf starten (eventuell brauchen Sie root-Berechtigung, um die Dateien im Verzeichnis /usr/local installieren zu können):

papaya$ make install gcc -c main.c gcc -c edit.c gcc -o edimh main.o edit.o gcc -c read.c gcc -o readimh main.o read.o mv edimh /usr/local mv readimh /usr/local

Dieses Makefile bewältigt also einen kompletten Durchlauf zur Erzeugung und Installation aller Dateien. Es erzeugt zuerst die Dateien, die für edimh benötigt werden. Dann erzeugt es die Objektdatei, die zusätzlich für die Erzeugung von readimh gebraucht wird. Wenn diese beiden ausführbaren Dateien erstellt sind, ist das Ziel all erfüllt. Anschließend kann make mit dem Ziel install weitermachen, also die ausführbaren Dateien an ihren endgültigen Speicherort verschieben.

Viele Makefiles - darunter auch die, die Linux erzeugen - enthalten eine ganze Reihe unechter Ziele, mit denen Routineaufgaben erledigt werden. Das Makefile für den Linux-Kernel enthält zum Beispiel Befehle, die temporäre Dateien löschen:

clean: archclean rm -f kernel/ksyms.lst rm -f core `find . -name '*.[oas]' -print` . . .

Dort finden Sie auch Befehle, um eine Liste mit Objektdateien samt den Header-Dateien, von denen sie abhängig sind, zu erzeugen. (Dies ist eine komplizierte und wichtige Aufgabe - wenn eine Header-Datei geändert wird, soll sichergestellt werden, daß die Objektdateien, die davon abhängig sind, neu kompiliert werden.)

depend dep: touch tools/version.h for i in init/*.c;do echo -n "init/";$(CPP) -M $$i;done > .tmpdepend . . .

Einige dieser Shell-Befehle werden ziemlich komplex; wir werden uns im Abschnitt »Mehrfachbefehle« später in diesem Kapitel noch mit den Befehlen in Makefiles befassen.

Einige Syntaxregeln

Die größten Probleme rund um die Makefiles verursacht immer die Syntax - jedenfalls für Neulinge. Also gut, wir sagen es geradeheraus: Die Syntax von make ist ganz einfach idiotisch. Wenn Sie Leerstellen einfügen, wo Tabulatoren stehen sollten (oder umgekehrt), geht das Ding in die Hose; die Fehlermeldungen dazu sind eher verwirrend.

Icon

Setzen Sie vor eine Befehlszeile immer einen Tabulator - keine Leerstellen. Setzen Sie niemals einen Tabulator vor irgendeine der anderen Zeilen.

Sie können an beliebiger Stelle in einer Zeile ein Doppelkreuz (#) schreiben, um einen Kommentar einzuleiten. Alles hinter dem Zeichen wird ignoriert.

Wenn Sie ein Backslash an das Ende einer Zeile setzen, wird die nächste Zeile eine Fortsetzungszeile. Das funktioniert mit besonders langen Befehlen ebenso wie für alle anderen Zeilen in Makefiles.

Lassen Sie uns einige der mächtigen Fähigkeiten von make betrachten, die insgesamt eine Art Programmiersprache darstellen.

Makros

Wenn Programmierer einen Dateinamen oder sonstigen String innerhalb eines Makefiles mehr als einmal benutzen, tendieren sie dazu, daraus ein Makro zu machen. Das ist einfach eine Zeichenfolge, die mit Hilfe von make zu einer anderen Zeichenfolge expandiert. Sie könnten zum Beispiel den Anfang unseres trivialen Makefiles so formulieren:

OBJECTS = main.o edit.o edimh: $(OBJECTS) gcc -o edimh $(OBJECTS)

Wenn make loslegt, wird es einfach überall da main.o edit.o einsetzen, wo Sie $(OBJECTS) angegeben haben. Wenn Sie dem Projekt eine weitere Objektdatei hinzufügen möchten, brauchen Sie dies nur in der ersten Zeile der Datei anzugeben. Die Zeile mit den Abhängigkeiten und die Befehle werden dementsprechend angepaßt.

Vergessen Sie die Klammern nicht, wenn Sie $(OBJECTS) ansprechen. Makros sehen vielleicht ein wenig wie Shell-Variablen aus (etwa $HOME oder $PATH), aber sie sind doch anders.

Sie können ein Makro innerhalb einer anderen Makrodefinition einsetzen. Ein Beispiel:

ROOT = /usr/local HEADERS = $(ROOT)/include SOURCES = $(ROOT)/src

In diesem Fall wird HEADERS zum Verzeichnis /usr/local/include expandiert, und SOURCES wird zu /usr/local/src. Falls Sie ein Programmpaket auf Ihrem System installieren, das nicht in /usr/local stehen soll, müssen Sie nur ein anderes Verzeichnis finden und dieses in der ROOT-Zeile eintragen.

Sie müssen übrigens für die Namen von Makros keine Großbuchstaben verwenden, aber diese Konvention hat sich überall durchgesetzt.

Ein Zusatz zum GNU-make gibt Ihnen die Möglichkeit, eine Makrodefinition zu erweitern. Benutzen Sie dazu den String := statt des Gleichheitszeichens:

DRIVERS =drivers/block/block.a ifdef CONFIG_SCSI DRIVERS := $(DRIVERS) drivers/scsi/scsi.a endif

Die erste Zeile enthält eine normale Makrodefinition, die dem Makro DRIVERS den Wert drivers/block/block.a zuweist. Die nächste Definition erweitert das Makro um die Datei drivers/scsi/scsi.a; diese Erweiterung findet allerdings nur dann statt, wenn auch CONFIG_SCSI definiert ist. Die komplette Zuweisung lautet in diesem Fall:

drivers/block/block.a drivers/scsi/scsi.a

Wie aber definieren Sie CONFIG_SCSI? Fügen Sie es einfach in das Makefile ein, und weisen Sie ihm einen beliebigen Wert zu:

CONFIG_SCSI = yes

Wahrscheinlich ist es aber einfacher, die Definition auf der Befehlszeile von make vorzunehmen - und so wird's gemacht:

papaya$ make CONFIG_SCSI=yes ziel

Eine subtile Anwendung von Makros bietet das undefinierte Makro. Wenn ein Makro nicht definiert wird, bekommt es eine leere Zeichenfolge zugewiesen (das heißt, es steht nichts an der Stelle, an der das Makro stehen sollte). Damit haben Sie aber auch die Möglichkeit, ein Makro als Umgebungsvariable zu definieren. Wenn Sie also CONFIG_SCSI nicht im Makefile definieren, könnten Sie folgendes in Ihre Datei .bashrc einfügen (wenn Sie bash benutzen):

export CONFIG_SCSI=yes

Für die csh oder tcsh schreiben Sie folgendes in die Datei .cshrc:

setenv CONFIG_SCSI yes

Damit haben Sie für alle Compiler-Läufe das Makro CONFIG_SCSI definiert.

Suffixregeln und Pattern-Regeln

Natürlich wollen Sie bei solchen Routineaufgaben wie der Erzeugung einer Objektdatei aus einer Quelldatei in Ihrem Makefile nicht jede Abhängigkeit einzeln definieren. Dazu besteht auch kein Grund. Die Unix-Compiler bestehen auf einer einfachen Vereinbarung (eine Datei mit der Endung .c wird kompiliert, um eine Datei mit der Endung .o zu erzeugen); make benutzt Suffixregeln, um alle vorkommenden Dateien zu erfassen.

Sie könnten folgende einfache Suffixregel in Ihr Makefile schreiben, um eine C-Quelldatei zu kompilieren:

.c.o: gcc -c $(CFLAGS) $<

Die Zeile .c.o: bedeutet: »Mache aus einer .c-Datei eine .o-Datei.« Das Makro CFLAGS besteht aus den gewünschten Compiler-Optionen - etwa -g zum Debuggen oder -O für die Optimierung. Die Zeichenfolge $< steht für »die Eingabedatei«. An dieser Stelle wird also der Name Ihrer .c-Datei eingesetzt, wenn make diese Anweisung ausführt.

Lassen Sie uns diese Suffixregel testen. Die Befehlszeile übergibt die beiden Optionen -g und -O:

papaya$ make CFLAGS="-O -g" edit.o gcc -c -O -g edit.c

In Wirklichkeit brauchen Sie diese Suffixregel gar nicht in Ihr Makefile einzubauen, weil make bereits etwas ganz Ähnliches enthält. Es benutzt außerdem die CFLAGS, so daß Sie die Compiler-Optionen bestimmen können, indem Sie einfach diese Variable definieren. Das Makefile, das bei der Kompilierung des Kernels benutzt wird, enthält derzeit eine ganze Reihe von Optionen für den gcc:

CFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe

Da wir uns gerade mit Compiler-Optionen beschäftigen, wollen wir eine besonders erwähnen, die man sehr häufig zu sehen bekommt - das ist die Option -D, mit der Symbole im Quellcode definiert werden. Es kann sein, daß Sie eine ganze Menge solcher Optionen an Ihr Makefile übergeben müssen, weil einige davon in den #ifdef-Zeilen recht häufig auftauchen; zum Beispiel -DDEBUG oder -DBSD. Wenn Sie diese Optionen in der Befehlszeile übergeben, sollten Sie auf jeden Fall die komplette Reihe der Optionen mit Anführungszeichen oder Apostrophen klammern; daraufhin wird Ihre Shell alle Optionen als ein einziges Argument an Ihr Makefile übergeben:

papaya$ make CFLAGS="-DDEBUG -DBSD" ...

Das make von GNU benutzt außerdem etwas, das man Pattern-Regeln (Musterregeln) nennt. Damit haben Sie weitergehende Möglichkeiten als mit den Suffixregeln. In einer Pattern-Regel ist das Prozentzeichen ein Platzhalter für »einen beliebigen String«. Mit folgender Regel können Sie also C-Quellen kompilieren:

%.o: %.c gcc -c -o $@ $(CFLAGS) $<

In diesem Fall steht die Ergebnisdatei an erster Stelle, und die Eingabedatei erscheint hinter dem Doppelpunkt. Eine Pattern-Regel sieht also aus wie eine normale Abhängigkeiten-Zeile, enthält aber Prozentzeichen statt der Dateinamen.

Der String $< ist der Platzhalter für die Eingabedatei, und das $@ steht für die zu erzeugende Datei; hier wird also der Name der .o-Datei eingesetzt. Beide sind interne Makros, die make jedesmal definiert, wenn es eine Anweisung ausführt.

Ein anderes internes Makro ist $*, das den Namen der Eingabedatei ohne das Suffix erzeugt. Wenn die Eingabedatei also edit.c heißt, wird der String $*.s zu edit.s expandiert (eine Assembler-Codedatei).

Ein Beispiel für eine nützliche Anwendung, das mit der Pattern-Regel, aber nicht mit einer Suffixregel funktioniert: Hängen Sie die Zeichenfolge _dbg an den Namen der Ausgabedatei an, damit Sie später noch wissen, daß dieses Programm mit Debugging-Informationen kompiliert wurde:

%_dbg.o: %.c gcc -c -g -o $@ $(CFLAGS) $< DEBUG_OBJECTS = main_dbg.o edit_dbg.o edimh_dbg: $(DEBUG_OBJECTS) gcc -o $@ $(DEBUG_OBJECTS)

Jetzt können Sie alle Objektdateien einmal mit und einmal ohne Debugging-Informationen kompilieren. Weil die Dateinamen unterschiedlich sind, können Sie alle Versionen in einem Verzeichnis halten.

papaya$ make edimh_dbg gcc -c -g -o main_dbg.o main.c gcc -c -g -o edit_dbg.o edit.c gcc -o edimh_dbg main_dbg.o edit_dbg.o

Mehrfachbefehle

In einem Makefile können beliebige Shell-Befehle ausgeführt werden. Die Lage wird allerdings dadurch kompliziert, daß make jeden Befehl in einer anderen Shell ausführt. So gelangen Sie also nicht ans Ziel:

target: cd obj HOST_DIR=/home/e mv *.o $HOST_DIR

Icon

Weder der Befehl cd noch die Definition der Variable HOST_DIR wirken sich auf die folgenden Befehle aus. Sie müssen das Ganze zu einem einzigen Befehl zusammenfassen. Die Shell benutzt das Semikolon als Trennzeichen zwischen Befehlen; die Befehlszeile sieht dann so aus:

target: cd obj ; HOST_DIR=/home/e ; mv *.o $$HOST_DIR

Noch eine Änderung: Wenn Sie innerhalb des Befehls eine Shell-Variable definieren und benutzen, müssen Sie zwei Dollarzeichen voranstellen. make erkennt daran, daß hier eine Shell-Variable und nicht ein Makro gemeint ist.

Vielleicht ist die Datei einfacher zu lesen, wenn Sie die einzelnen Bestandteile eines Mehrfachbefehls jeweils in eine neue Zeile schreiben. Schließen Sie dann jede Zeile mit einem Backslash ab, damit make das Ganze als eine zusammenhängende Zeile betrachtet:

target: cd obj ; \ HOST_DIR=/home/e ; \ mv *.o $$HOST_DIR

Manche Makefiles enthalten wiederum einen make-Befehl; das nennt man rekursives make. So sieht es aus:

linuxsubdirs: dummy set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i; done

Das Makro $(MAKE) ruft make auf. Es gibt mehrere Anwendungen für geschachtelte makes. Unser Beispiel zeigt eine Möglichkeit - einen Compiler-Lauf, der sich auf verschiedene Verzeichnisse erstreckt (dabei muß jedes dieser Verzeichnisse ein eigenes Makefile enthalten). Eine andere Anwendung ist die Definition von Makros in der Befehlszeile, so daß Compiler-Läufe mit unterschiedlichen Makrodefinitionen stattfinden können.

GNU-make bietet als Erweiterung ein weiteres mächtiges Interface mit der Befehlszeile. Sie können einen Shell-Befehl aufrufen und einem Makro das Ergebnis des Aufrufs zuweisen. Im Makefile zum Linux-Kernel wird diese Methode benutzt, aber wir wollen Ihnen hier ein einfaches Beispiel zeigen:

HOST_NAME = $(shell uname -n)

Damit weisen Sie dem Makro HOST_NAME den Namen Ihres Rechners im Netzwerk zu (nämlich die Ausgabe des Befehls uname -n).

make befolgt ein paar Konventionen, die manchmal ganz praktisch sind. So erreichen Sie zum Beispiel mit dem Klammeraffen (@) vor einem Befehl, daß make bei der Ausführung den Befehl selbst anzeigt:

@if [ -x /bin/dnsdomainname ]; then \ echo #define LINUX_COMPILE_DOMAIN \"`dnsdomainname`\"; \ else \ echo #define LINUX_COMPILE_DOMAIN \"`domainname`\"; \ fi >> tools/version.h

Eine andere Möglichkeit besteht darin, einen Bindestrich vor einen Befehl zu setzen; damit weisen Sie make an, selbst dann fortzufahren, wenn der Befehl nicht ausgeführt werden konnte. Das kann zum Beispiel dann nützlich sein, wenn make auch nach einem fehlgeschlagenen mv oder cp weiterarbeiten soll:

- mv edimh /usr/local - mv readimh /usr/local

Andere Makefiles einbinden

Bei großen Projekten hat man es oft mit vielen Makefiles zu tun. Das erleichtert zum Beispiel die gemeinsame Nutzung von Makrodefinitionen durch etliche Makefiles in verschiedenen Verzeichnissen. Mit der Anweisung

include dateiname

lesen Sie den Inhalt von dateiname ein. Auch dies wird im Makefile des Linux-Kernels benutzt. Ein Beispiel:

include .depend

Wenn Sie sich die Datei .depend ansehen, finden Sie dort einige Makefile-Einträge; genauer gesagt Zeilen, in denen erklärt wird, daß Objektdateien von Header-Dateien abhängen. (Es könnte übrigens sein, daß .depend noch nicht existiert - diese Datei wird durch einen weiteren Eintrag im Makefile erzeugt.)

Manchmal beziehen sich include-Zeilen auf Makros statt auf Dateinamen, etwa so:

include ${INC_FILE}

In diesem Fall muß INC_FILE entweder als Umgebungsvariable oder als ein Makro definiert sein. Auf diese Weise können Sie noch genauer bestimmen, welche Datei benutzt wird.

Autoconf und Automake

Das Schreiben von Makefiles für ein größeres Projekt ist normalerweise eine langweilige und langwierige Aufgabe, insbesondere, wenn die Programme auf mehreren Plattformen kompiliert werden sollen. Aus dem GNU-Projekt stammen zwei Werkzeuge namens Autoconf und Automake, die sehr schwer zu erlernen sind, aber die Erzeugung portabler Makefiles drastisch vereinfachen, wenn man sie erst einmal beherrscht. Dazu gibt es noch libtool, das die Erzeugung von Shared Libraries sehr viel einfacher macht. Es würde den Rahmen dieses Buches sprengen, die Benutzung dieser Programme zu beschreiben. Sie finden sie unter ftp://ftp.gnu.org/pub/gnu .



vorheriges Kapitel Inhaltsverzeichnis Stichwortverzeichnis nächstes Kapitel


Weitere Informationen zum Linux - Wegweiser zur Installation & Konfiguration

Weitere Online-Bücher & Probekapitel finden Sie in unserem Online Book Center


O'Reilly Home | O'Reilly-Partnerbuchhandlungen | Bestellinformationen | Kontaktieren Sie uns
International | Über O'Reilly | Tochterfirmen

© 2000, O'Reilly Verlag