Verwendung von Makros

Eine Möglichkeit, das makefile vielseitiger zu machen und leichter pflegen zu können, ist die geschickte Verwendung von Makros.

Beispielsweise ist es eleganter, nur an einer Stelle im makefile festzulegen, wie der Compiler heißt, und mit welchen Optionen er zum Kompilieren aufgerufen werden soll.

Gerade für solche allgemeinen Fälle gibt es bereits vordefinierte Makros, die man ohne Neudefinieren verwenden kann, oder mit eigenem Inhalt überschrieben kann.

Einige vom GNU-make vordefinierten Variablen und ihre Standardwerte sind:
AR Archivprogramm; Standard: ar.
ARFLAGS Weitere Programmargumente dafür; Standard: rv.
AS Assembler; Standard: as.
ASFLAGS Weitere Programmargumente dafür (für .s or .S Dateien).
CC Compiler für C-Quelltexte; Standard: cc.
CFLAGS Weitere Programmargumente dafür.
CXX Compiler für C++; Standard: g++.
CXXFLAGS Weitere Programmargumente dafür.
CO extrahieren einer RCS-Datei; Standard: co.
COFLAGS Weitere Programmargumente dafür.
CPP Aufruf des C-Präprozessors; Standard: $(CC) -E.
CPPFLAGS Weitere Programmargumente dafür.
FC Compiler für Fortran- und Ratfor; Standard: f77.
FFLAGS Weitere Programmargumente dafür.
RFLAGS Weitere Programmargumente dafür (wenn Ratfor kompiliert wird).
LDFLAGS Weitere Programmargumente für alle Compiler, wenn sie zum Linken aufgerufen werden.
GET Programm, um eine SCCS-Datei zu extrahieren; Standard: get.
GFLAGS Weitere Programmargumente dafür.
LEX Konvertieren einer Lex-Grammatik nach C oder Ratfor; Standard: lex.
LFLAGS Weitere Programmargumente dafür.
PC Compiler für Pascal; Standard: pc.
PFLAGS Weitere Programmargumente dafür.
YACC Konvertieren einer Yacc-Grammatik nach C; Standard: yacc.
YFLAGS Weitere Programmargumente dafür.
YACCR Konvertieren einer Yacc-Grammatik nach Ratfor; Standard: yacc -r.
MAKEINFO Konvertieren einer Texinfo-Datei nach Info; Standard: makeinfo.
TEX Programm zum Konvertieren von TEX nach DVI; Standard: tex.
TEXI2DVI Programm zum Konvertieren von TeXinfo nach DVI; Standard: texi2dvi.
WEAVE Programm zum Konvertieren von Web nach TeX; Standard: weave.
CWEAVE Programm zum Konvertieren von C Web nach TeX; Standard: cweave.
TANGLE Programm zum Konvertieren von Web nach Pascal; Standard: tangle.
CTANGLE Programm zum Konvertieren von C Web nach C; Standard: ctangle.
RM Löschkommando; Standard: rm -f.
 

Weiterhin können in impliziten ebenso wie in expliziten Regeln Makros verwendet werden, die zu den jeweiligen target- und prerequisite-Namen expandieren:
$* ,,stem``; das ist der gemeinsame Teil des Namens von Target und prerequisite (beispielsweise haupt für haupt.cpp und haupt.o)
$(*D) Der Teil des Namens in $*, der das Verzeichnis bildet (ohne /)
$(*F) Der eigentliche Dateiname in $* ohne das Verzeichnis
$@ Das Target einer Regel
$(@D) Der Teil des Namens in $@, der das Verzeichnis bildet (ohne /)
$(@F) Der eigentliche Dateiname in $@ ohne das Verzeichnis
$% Das Target einer Regel
$(%D) Der Teil des Namens in $%, der das Verzeichnis bildet (ohne /)
$(%F) Der eigentliche Dateiname in $% ohne das Verzeichnis
$< Der Name der ersten Abhängigkeit (prerequisite)
$(<D) Der Teil des Namens in $<, der das Verzeichnis bildet (ohne /)
$(<F) Der eigentliche Dateiname in $< ohne das Verzeichnis
$? Alle prerequisites, die neuer sind als das Target
$(?D) Liste der Teile der Namen in $?, die das jeweilige Verzeichnis bilden (ohne /)
$(?F) Liste der Dateinamen in $? ohne die Verzeichnisse
$^ Alle prerequisites, mit Leerzeichen getrennt (mehrfach vorkommende tauchen hier nur einmal auf)
$(^D) Liste der Verzeichnisse der Namen in $^ (ohne /)
$(^F) Liste der Dateinamen in $^ ohne die Verzeichnisse
$+ Alle prerequisites, mit Leerzeichen getrennt (mehrfach vorkommende tauchen gegebenenfalls mehrfach auf)
 

Damit könnte man das makefile auch so schreiben:

CXX = g++             # der zu verwendende C++-Compiler
CXXFLAGS = -c         # Optionen zum Kompilieren von C++

CC = gcc              # Compiler für C und gleichzeitig Linker

haupt: haupt.o up.o db.o
        $(CXX) $^ -o $@

haupt.o: haupt.cpp up.h db.h
        $(CXX) $(CFLAGS) $<

up.o: up.cpp up.h db.h
        $(CXX) $(CFLAGS) $<

db.o: db.cpp db.h
        $(CXX) $(CFLAGS) $<
, beziehungsweise mit einer impliziten Regel:
CXX = g++             # der zu verwendende C++-Compiler
CXXFLAGS = -c         # Optionen zum Kompilieren von C++

CC = gcc              # Compiler für C und gleichzeitig Linker

haupt: haupt.o up.o db.o
        $(CXX) $^ -o $@

haupt.o: haupt.cpp up.h db.h

up.o: up.cpp up.h db.h

db.o: db.cpp db.h

.c.o:
        $(CXX) $(CFLAGS) $<

Der Vorteil ist bei so wenigen Zeilen nicht offensichtlich; aber bei größeren Projekten kann man so mit weniger Änderungen an der Datei (und dementsprechend weniger Fehlern) das makefile pflegen, und leichter Teile eines makefile in einem anderen weiter verwenden.

Neben der impliziten Regel und einigen Makrodefinitionen enthält die Datei nur noch Abhängigkeiten, sowie das Kommando zum Linken.

Im folgenden Abschnitt wird gezeigt, wie man das Erstellen der Abhängigkeiten automatisieren kann.

AnyWare@Wachtler.de