SelfLinux Programmierung Make Abschnitt 4 | SelfLinux-0.13.0

| Make | Autor Formatierung GFDL

#### 5 Kommandos

Da die Kommandos in einer eigenen (Unter-) Shell ausgeführt werden, stehen alle Möglichkeiten einer Shell wie Wildcards, Ein-/Ausgabe-Umlenkung, ... zur Verfügung.

#### 5.1 Wildcards

Wildcards (im Deutschen auch als Jokerzeichen bezeichnet) können innerhalb von Kommandos verwendet werden, aber auch in den Abhängigkeiten einer Regel auftauchen:

    print : *.c
            lpr *.c

Leider haben diese Wildcards eine leicht unterschiedliche Bedeutung: das erste Wildcard *.c innerhalb der Abhängigkeit wird von make aufgelöst, das Wildcard im Kommando (lpr *.c) von der Shell. Während bei der Shell die Hidden Files (das sind diejenige Dateien wie zum Beispiel .bashrc, die mit einem . anfangen) nicht dazugehören, ist hier das make-Kommando anderer Auffassung.

#### 5.2 Mehrere Kommandos

Jede Zeile im Aktions-Teil wird in einer eigenen Unter- Shell gestartet. Will man mehrere Kommados auf einmal absetzen, werden diese hintereinander aufgereiht und jeweils durch einen Strichpunkt (;) voneinander getrennt:

    clean :
            cd obj ; rm *.o

Bei diesem Beispiel ist zu bedenken, dass das zweite Kommando (rm *.o) auch dann ausgführt wird, wenn der erste Teil (cd obj) nicht geklappt hat. Deswegen können Kommandos auch über && (UND) verknüpft werden:

    clean :
            cd obj && rm *.o

Vorteil der UND-Verknüpfung: Schlägt das erste Kommando (cd obj) fehl, wird das zweite Kommando (rm *.o) auf keinen Fall ausgeführt.

Man kann die Kommandos auch auf mehrere Zeilen verteilen, indem man sie mit dem Backslash (\) als allerletztes Zeichen in der Zeile verbindet:

    clean :
            cd obj &&       \
            rm *.o

Dabei ist darauf zu achten, dass der Backslash (\) wirklich das letzte Zeichen in der Zeile ist -- er hebt nämlich die Bedeutung des nächsten Zeichens (in diesem Fall das Zeilenende) auf. Steht hier ein Leerzeichen, wird die (nicht vorhandene) Sonderbedeutung des Leerzeichens aufgehoben.

#### 5.3 Skript-Programmierung

Für komplexere Aufgaben kann man eigene Skripte schreiben oder aber auch direkt im Makefile Programmierkonstrukte der (Bourne-)Shell verwenden (das indent-Kommando formartiert C-Quellen nach den GNU-C-Konventionen):

    indent :
            for file in $(C_FILES) ; do     \
                indent $$file ;             \
            done

Hier ist darauf zu achten, dass die einzelnen Konstrukte durch einen Strichpunkt (;) voneinander getrennt werden. Erstrecken sich die Kommandos über mehrere Zeilen, ist dies durch ein Backslash (\) am Zeilenende zu kennzeichnen.

Der Zugriff auf Shell-interne Variablen wird durch ein zusätzliches Dollar-Zeichen ($) bewerkstelligt (siehe $$file im Beispiel).

#### 5.4 Fehlercode

Wenn ein Kommando einen Fehlercode zurückliefert, wird make an dieser Stelle abgebrochen. Dabei ist unter Unix alles, was einen Rückgabewert ungleich 0 zurückliefert, ein Fehlercode.

Meistens ist dieses Verhalten ja gewünscht, zum Beispiel beim Kompilieren (was der Normalfall sein dürfte). Aber es gibt auch Situationen, in dem der Rückgabewert eines Kommandos egal ist, zum Beispiel in

    clean :
            - rm core
            - rm *.o

ist es nicht weiter tragisch, wenn rm core nicht erfolgreich war (weil es nicht existiert). Der Abbruch im Fehlerfall wird durch ein vorangestelltes Minus (-) vermieden.

Manche Kommandos, wie zum Beispiel das rm-Kommando, können meist über die Option -f gezwungen werden, fehlende Dateien oder andere Ungereimtheiten zu ignorieren. Damit lässt sich das vorige Beispiel auch folgendermassen formulieren:

    clean :
            rm -f core
            rm -f *.o

#### 5.5 Ausgabe unterdrücken

Normalerweise wird jedes Kommando, das ausgeführt wird, vorher ausgegeben. Mit einem vorangestellten @ kann man das unterdrücken:

    statistic :
            @ echo ""
            @ echo "      S T A T I S T I C S"
            @ echo ""
            @ echo "   Lines   Words   Bytes Modul"
            @ echo "   --------------------------------"
            @ wc ${SRC_FILES}
            @ echo ""

Vor Allem beim echo-Kommando macht es keinen Sinn, dass vor der eigentlichen Ausgabe das echo-Kommando samt Ausgabe-String ausgegeben wird.