Galileo Computing < openbook >
Galileo Computing - Bücher zur Programmierung und Softwareentwicklung
Galileo Computing - Bücher zur Programmierung und Softwareentwicklung


'Wie werde ich Unix-Guru' als Buch bestellen
A. Willemer
Wie werde ich UNIX-Guru
I  ANWENDUNG
Know-How für Unix/Linux-User: Einführung, Shell, Befehle, Hilfe, Arbeit mit Dateien, Editoren, Reguläre Ausdrücke, nützliche Tools, Hardware.

II  ADMINISTRATION
Tools, Systemstart, Benutzer verwalten, Hardware konfigurieren, Software installieren, Datensicherung, Tuning, Kernel

III  NETZWERK
Client/Server Systeme, TCP/IP, Routing, IPv6, Internet-Dienste, DHCP, Webserver, Firewalls

IV  DAS X-WINDOW SYSTEM
Die grafische Oberfläche von UNIX einrichten und nutzen

V  PROGRAMMIERUNG VON SHELLSKRIPTEN
Automatisieren von Tasks durch Shell-Skripte.

VI  PERL
Interpreter, Syntax, Variablen, Steuerung, Funktionen, UNIX-Aufrufe, GUIs mit Tk

VII  PROGRAMMIERWERKZEUGE
C-Compiler, Analyse-Tools, CVS, yacc, diff

VIII  UNIX-SYSTEMAUFRUFE
UNIX-Befehle in eigenen Programmen nutzen

IX  LITERATUR
Weiterführende Literatur zu UNIX und LINUX

 
Galileo Computing / <openbook> / "Wie werde ich UNIX-Guru ?"
« C-Compiler Programmierwerkzeuge Debugger »

make

Sobald ein Programm aus mehreren Dateien besteht, ist schnell der Punkt erreicht, wo es sinnvoll ist, sich einen kurzen Batch für das Compilieren zu schreiben. Statt dessen sollten Sie lieber ein Makefile schreiben. Das ist nicht viel aufwändiger, hat aber den Vorteil, dass das Programm make überwacht, welche Änderungen bei der neuesten Version zu berücksichtigen sind. Das heißt, dass make das Übersetzen nicht öfter veranlasst, als erforderlich ist.

Das Projekt meinprog besteht aus den Sourcedateien haupt.c, test.c und tools.c. Jede dieser Dateien hat eine Headerdatei (haupt.h, test.h und tools.h), die es jeweils selbst einbindet. Dazu bindet haupt.c jede andere Headerdatei ein und jedes Modul bindet die globalen Definitionen aus haupt.h ein.

Eine Datei Makefile wird angelegt und darin wird der Weg der Compilierung beschrieben. Das Programm meinprog hängt von den Dateien test.o, haupt.o und tools.o ab. Das formuliert man in einem Makefile folgendermaßen:

meinprog:  test.o haupt.o tools.o

Mit dieser Zeile wird die Abhängigkeit der Datei meinprog von den Dateien test.o, haupt.o und tools.o definiert. Man bezeichnet meinprog als Ziel oder englisch target. Die darauf folgenden Zeilen beschreiben, wie die Zieldatei hergestellt wird. Die Datei meinprog wird generiert, indem der Compiler mit den Objektdateien als Parameter aufgerufen wird. Mit Hilfe der Option -o legen Sie fest, dass das Ergebnis meinprog heißen soll. Der Compiler merkt von sich aus, dass er hier nur linken soll, da keine echten Quellcodedateien vorhanden sind. Solche Aktionszeilen müssen mit einem Tabulator beginnen. Es dürfen keine Leerzeichen verwendet werden.

meinprog:  test.o haupt.o tools.o
        cc -o meinprog test.o haupt.o tools.o

Wer nun einfach make aufruft, erhält überraschenderweise bereits ein komplett übersetztes Programm. Auf dem Bildschirm erscheinen folgende Zeilen:
gaston> make
cc    -c -o test.o test.c
cc    -c -o haupt.o haupt.c
cc    -c -o tools.o tools.c
cc -o meinprog test.o haupt.o tools.o
gaston>

Tatsächlich »weiß« make, wie man aus c-Dateien o-Dateien macht und da er mit den Regeln des Makefiles die o-Dateien nicht erzeugen kann, sieht make im aktuellen Verzeichnis nach, ob es Dateien gibt, aus denen er o-Dateien generieren kann.

Ändern Sie die Datei test.c, so wird nur test.c übersetzt und meinprog neu gebunden. Ändern Sie allerdings test.h, passiert nichts. make kennt die Abhängigkeiten der Header nicht. Damit make auch Änderungen der Headerdateien überwacht, ist folgende Änderung im Makefile notwendig.

test.o : test.c test.h haupt.h

tools.o : tools.c tools.h haupt.h

haupt.o : haupt.c haupt.h test.h tools.h

Eine vollständige Aktionszeile müsste hier eigentlich etwa so lauten:

test.o : test.c test.h haupt.h
        cc -c -o test.o test.c

Da aber make die erforderliche Aktion bereits kennt, braucht man sie nicht zu erwähnen.

Das Programm make ist also ein Tool, um Zieldateien aus den Quelldateien mit minimalem Aufwand zu generieren. Dazu wird in einer Datei namens makefile oder Makefile, die Abhängigkeiten der Dateien beschrieben und die Programmaufrufe festgelegt, die aus den jeweiligen Quellen die Ziele generieren. make erkennt, wenn eine der Quelldateien neuer als die Zieldatei ist, und ruft die Generierungsprogramme auf, bis die Zieldateien neuer als die jeweiligen Quellen sind oder eine Aktion scheitert.

Ein Makefile hat Einträge der folgenden Grundstruktur:

Ziel : Abhängigkeiten
Generierungskommando

Diese Grundstruktur nennt man Regel. Eine neue Regel muss mit einer Leerzeile von der vorherigen getrennt werden. Der Leerraum vor dem Generierungskommando muss ein Tabulatorzeichen sein. Es können auch mehrere Kommandozeilen nacheinander angegeben werden. Alle müssen mit Tabulator eingerückt sein. Die Kommandozeilen werden jeweils in einer separaten Shell abgearbeitet. In manchen Situationen gibt das Seiteneffekte, die Sie berücksichtigen müssen. Beispiel:

try :
       cd .. ; pwd
       pwd

Die Ergebnisse der beiden Aufrufe von pwd sind nicht gleich. Der Wechsel mit cd .. gilt nur für die aktuelle Zeile. In der nächsten Zeile wird wieder aus dem bisherigen Verzeichnis gearbeitet.

cd .. ; pwd
/home/arnold/my/src/unix
pwd
/home/arnold/my/src/unix/make

Hängen also Kommandos so zusammen, dass sie in einer gemeinsamen Shell bearbeitet werden müssen, sollten sie in dieselbe Zeile geschrieben werden und mit Semikola getrennt werden. Bei langen Zeilen kann mit einem Backslash die Zeile in der nächsten Zeile fortgesetzt werden.

Als Kommentarzeichen gilt das # in der ersten Spalte.

Makros im Makefile

Durch die Verwendung von Makros können die Makefiles besser strukturiert und flexibler gestaltet werden. Makros sind Variablen, denen Zeichenketten zugewiesen werden und dann durch Voranstellen eines $-Zeichens ausgewertet werden. Durch das Zusammenfassen von Dateinamen oder Optionen kann ein Makefile kürzer und vor allem besser lesbar werden.

Im Beispiel werden die Objektdateien zusammen behandelt und zweimal aufgezählt, einmal in der Abhängigkeitsbeschreibung von meinprog und dann im Compileaufruf.

meinprog:  test.o haupt.o tools.o
        cc -o meinprog test.o haupt.o tools.o

Hier können Sie eine Variable OBJS definieren, die die Objekte bezeichnet. Durch Einsetzen von OBJS ergibt sich die folgende Makedatei.

OBJS = test.o haupt.o tools.o

meinprog: $(OBJS)
      cc -o meinprog 

Die Variablen müssen nicht im Makefile selbst definiert werden. make kann auf Umgebungsvariablen zurückgreifen, die von der aufrufenden Shell festgelegt wurden.

Vordefinierte Makros

Es ist möglich, mehrere Ziele mit einer Regel zu behandeln. So könnte beispielsweise $(OBJS) als Ziel verwendet werden. Die einzelnen Ziele werden nacheinander aufgelöst. Im Generierungskommando kann auf das aktuelle Ziel Bezug genommen werden. Dazu gibt es vordefinierte Makros, die hier am Beispiel haupt.o aufgezeigt werden.

[Vordefinierte make-Makros]L|L Makro & Bedeutung
$@ & Dateiname des Ziels (haupt.o)
$* & Basisnamen des Ziels (haupt)

Suffixregeln

Die Suffixregeln beschreiben den Übergang einer Dateiendung zu einer anderen. Eine solche Regel erkennen Sie daran, dass das Ziel die zwei Dateiendungen mit dem jeweiligen Punkt am Anfang direkt hintereinander stehen hat.

.quell.ziel:

Der typischste Übergang ist sicher der von C-Sourcen zu Objekten. Die Sourcen enden auf c und die Objektdateien auf o. Die entsprechende Suffixregel lautet dann:

.c.o:
         cc -c $<

Das interne Makro $< darf nur bei Suffixregeln verwendet werden und bezeichnet das aktuelle Ziel.

Mehrere Ziele

Ein Makefile kann mehrere Programme generieren. Das wird eingesetzt, wenn gleiche Quelltexte für mehrere Projekte gebraucht werden, die vielleicht sogar noch voneinander abhängig sind. Ein typisches Beispiel sind Client- und Serverprogramme, die in den Headern gleiche Datenstrukturen verwenden.

all: client server

client: (COMMONOBJS) 
 $(CLTOBJS)
        ...
\par server:$
 (SENDHEADER) (SRVOBJS)
        ...

Das erste Ziel ist immer das Ziel des gesamten Makefiles. In diesem Fall würde also beim Aufruf von make erst das Ziel all generiert werden. Da es keinerlei verbundene Aktion gibt, wird lediglich geprüft, ob die Abhängigkeiten erfüllt sind. Entsprechend wird als nächstes das Ziel client und dann das Ziel server gebildet. Es ist nicht zwingend, aber üblich, das Pseudoziel, das alle Programme eines Makefile generiert, all zu nennen.

Oft werden Makefiles auch zur Installation verwendet. Dazu wird ein Pseudoziel install eingeführt, das überprüft, ob alle Dateien des Projektes an den richtigen Stellen vorhanden sind und ansonsten als Aktion einfache Kopierbefehle absetzen. Aufgerufen wird so eine Installation mit make und als Parameter das Ziel install.

make install



Unterabschnitte
    • Makros im Makefile
    • Vordefinierte Makros
    • Suffixregeln
    • Mehrere Ziele


« C-Compiler | Programmierwerkzeuge | Debugger »
 
 Zum Katalog
Zum Katalog
Wie werde ich UNIX-Guru?
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 UNIX/Linux

PHP 4-Workshop

Einstieg in Python

Perl fürs Web

MySQL 4

GNOME 2.0
 Empfehlung

Einstieg in XML
 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
Info

 MyGalileo
Der Service für registrierte Leser:
Zu MyGalileo
Info



Copyright © Galileo Press GmbH 2003
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen wie die gebundene Ausgabe: 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.
[Galileo Computing]

Galileo Press GmbH, Gartenstraße 24, 53229 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de