Neben dem Expandieren von selbstdefinierten und den vordefinierten
Makros kann man weiterhin Funktionen aufrufen, die zumindest im
GNU-make eingebaut sind. Dazu schreibt man wie bei Makros
$(
...)
; allerdings kommen in die Klammern der Funktionsname und gegebenenfalls nach einem Leerzeichen die Argumente
an die Funktion, getrennt mit Kommata.
Die Argumente können wiederum Funktionsaufrufe oder Makroexpansionen
enthalten. Allerdings darf in den Argumenten die Klammerung, die für
das umgebende Makro verwendet wird (also {}
oder ()
) nur
paarweise auftreten, weil sich make sonst bei der Suche nach dem
Ende des Funktionsaufrufs verläuft.
Die Funktion wird ausgeführt, und liefert als Ergebnis einen Text, der genau wie eine Makroexpansion in den umgebenden Kontext eingefügt wird. Ein Funktionsaufruf darf ebenso wie eine Makroverwendung sowohl in den Abhängigkeiten als auch in den Kommandos von expliziten und impliziten Regeln auftauchen.
Hier eine Liste der Funktionen:
$(subst
ALT,
NEU,
TEXT)
liefert den TEXT, aber jedes
Vorkommen von ALT ist durch NEU ersetzt.
Beispiel:$(subst Verona,Naddel,Liebe Verona)
liefert Liebe Naddel
$(patsubst
ALT,
NEU,
TEXT)
liefert den TEXT, aber jedes
Vorkommen ALT ist durch NEU ersetzt; dabei kann ALT
ein Suchmuster sein.
Der TEXT wird wortweise betrachtet, und die einzelnen Worte
tauchen im Ergebnis jeweils mit einem Leerzeichen getrennt auf.
In dem Suchmuster steht ein %
für eine beliebige Folge von Zeichen. In NEU darf ebenfalls ein %
stehen; an dessen Stelle wird dann der zum %
in ALT passende Text eingesetzt.
Beispiel:$(patsubst V%a,V_%_a,Liebe Verona ! Liebe Viktoria)
expandiert zu Liebe V_eron_a ! Liebe V_iktori_a
Ein reales Beispiel wäre die Ersetzung von Dateiendungen:
$(patsubst %.c,%.o,a.c b.c c.c)
liefert
a.o b.o c.o
.
Will man ein %
in ALT oder NEU haben, dann muß man es mit einem
vorangestellten \
markieren. Ein beabsichtigtes \
wird dementsprechend als \\
geschrieben.
$(strip
STRING)
entfernt von STRING alle führenden und schließenden white space
(also im Wesentlichen Tabulatoren, Leerzeichen, Zeilenvorschub), und
ersetzt innerhalb von STRING jede white space-Folge
durch genau ein Leerzeichen.
$(findstring
SUCHTEXT,
STRING)
liefert SUCHTEXT, falls SUCHTEXT in
STRING vorkommt; ansonsten einen leeren String.
$(filter
MUSTER1 MUSTER2...,
STRING)
liefert alle Worte aus STRING, die einem der MUSTER
entsprechen, und unterdrückt alle anderen Worte.
Beispiel:
ALLEDATEIEN = a.c b.c c.cpp a.h b.h
ZUKOMPILIERENDEDATEIEN = $(filter %.c %.cpp,$(ALLEDATEIEN))
$(filter-out
MUSTER1 MUSTER2...,
STRING)
liefert alle Worte aus STRING, die keinem der MUSTER
entsprechen, und unterdrückt alle anderen Worte, also genau das
Gegenteil von filter.
$(sort
LISTE)
liefert eine sortierte Liste der Wörter in LISTE, wobei
mehrfach vorkommende Wörter unterdrückt werden. Im Ergebnis sind die
Wörter jeweils durch genau ein Leerzeichen getrennt.
$(dir
LISTE)
extrahiert von allen Dateinamen in LISTE die Verzeichnisangabe
(falls vorhanden) ohne /
, und liefert diese als Liste zurück.
Wenn ein Dateiname keine Verzeichnisangabe hat, dann wird dafür
./
vermutet und geliefert.
Beispiel:
$(dir /boot/vmlinuz printcap ./a.c)
liefert /boot ./ ./
$(notdir
LISTE)
extrahiert von allen Dateinamen in LISTE die Namen ohne
Verzeichnisangabe, und liefert diese als Liste zurück.
Beispiel:
$(notdir /boot/vmlinuz printcap ./a.c)
liefert vmlinuz printcap a.c
$(suffix
LISTE)
extrahiert von allen Dateinamen in LISTE die Dateiendungen
(falls vorhanden), und liefert diese als Liste zurück.
Beispiel:
$(suffix /boot/vmlinuz printcap ./a.c)
liefert .c
$(basename
LISTE)
extrahiert von allen Dateinamen in LISTE die vollen Namen,
aber ohne Dateiendungen
(falls vorhanden), und liefert die Namen als Liste zurück.
Beispiel:
$(basename /boot/vmlinuz printcap ./a.c)
liefert /boot/vmlinuz printcap ./a
$(addsuffix
SUFFIX,
LISTE)
hängt an jeden Namen in LISTE das SUFFIX an.
Damit kann das Beispiel-makefile noch wartungsfreundlicher formuliert werden:
CXX = g++ # der zu verwendende C++-Compiler CXXFLAGS = -c # Optionen zum Kompilieren von C++ CC = gcc # Compiler für C und gleichzeitig Linker MODULE = haupt up db haupt: $(addsuffix .o,$(MODULE)) # expandiert zu: haupt.o up.o db.o $(CXX) $^ -o $@ dep.make: $(CXX) $(CFLAGS) -MM $(addsuffix .cpp,$(MODULE)) > $@ include dep.make clean: rm -f haupt rm -f $(addsuffix .o,$(MODULE)) rm -f *.bak *~ # emacs erzeugt *~ als SicherheitskopieWenn jetzt ein Modul dazukommt, muß nur noch sein Name an MODULE angehängt werden. Die restliche Datei bleibt unverändert!
$(addprefix
PREFIX,
LISTE)
hängt vor jeden Namen in LISTE das PREFIX.
$(join
LISTE1,
LISTE2)
liefert eine Liste mit den Kombinationen der beiden ersten Wörter aus
LISTE1 und LISTE2, den jeweils zweiten Wörtern, usw..
Beispiel: $(join db up,.cpp .h)
liefert db.cpp up.h
$(word
N,
LISTE)
liefert das N-te Wort aus LISTE; N beginnt bei
1. Zu hohe Werte von N liefern einen leeren String.
$(words
LISTE)
liefert die Anzahl Worte in LISTE.
$(wordlist
N1,
N2,
LISTE)
liefert aus LISTE die Teilliste vom Index N1 bis N2.
$(firstword
LISTE)
liefert das erste Wort aus LISTE, ist also identisch mit
$(word 1,
LISTE)
$(wildcard
PATTERN)
expandiert zu einer Liste existierender Dateien, die dem PATTERN
entsprechen (in PATTERN werden wild cards wie in der Shell
üblich verwendet, also *
, ?
und [
...]
).
$(foreach
VARIABLE,
LISTE,
VORLAGE)
expandiert zuerst VARIABLE und LISTE. Dann wird für
jedes Wort LISTE einmal an die Variable mit dem aus
VARIABLE enstandenen Namen das Wort zugewiesen, und damit
VORLAGE expandiert. Rückgabe der Funktion ist eine Liste der
so entstandenen Expandierungen von VORLAGE.
Beispiel: $(suffix .c,a b c)
liefert a.c b.c b.c
,
und könnte gleichwertig durch $(foreach v,a b c,$(v).c)
ersetzt werden.
$(if
BEDINGUNG,
THEN-TEXT)
$(if
BEDINGUNG,
THEN-TEXT,
ELSE-TEXT)
entfernt von BEDINGUNG führende und schließende
white space und expandiert den Rest . Falls dies einen nicht-leeren String
liefert, dann wird der THEN-TEXT expandiert und
zurückgeliefert; ansonsten der ELSE-TEXT (falls angegeben).
Es gibt auch noch eine direkte Unterstützung von Fallunterscheidungen; siehe Fallunterscheidung.
$(call
VARIABLE,
P1,
P2...)
expandiert die Parameter P1, P2... und definiert damit die
Makros $(1)
, $(2)
, .... Zudem erhält $(0)
den Inhalt von VARIABLE. Damit wird dann die VARIABLE
expandiert (die zweckmäßigerweise
$(1)
, $(2)
, ... enthalten sollte).
Beispiel:
concat = $1$2 ... $(call concat,abc,def)expandiert zu
abcdef
.
$(origin
VARIABLENNAME)
liefert einen String, der angibt, woher der Wert der angegebenen
Variable stammt:
-e
aufgerufen
-e
aufgerufen
$*
).
$(shell
KOMMANDO)
führt das angegebene KOMMANDO aus, und erzeugt aus
der Ausgabe eine Liste, indem die einzelne Zeilen mit jeweils einem
Leerzeichen aneinandergehängt werden.
Beispiel: $(shell find . -name "*.cpp")
liefert eine Liste aller *.cpp-Dateien im aktuellen Verzeichnis
sowie in allen Unterverzeichnissen.
AnyWare@Wachtler.de