# Variables
CC = gcc
CFLAGS += -W -I .
# Default target
all: simple_main
# Normal target
simple_main: simple_main.o simple_sub.o
# Normal target, with action
dummy.o: dummy.c
${CC} -c dummy.c -o dummy.o
.PHONY: clean
clean:
${RM} simple_main *.o *.a
Ein Ziel beschreibt normalerweise, was gebaut werden soll (z.B. das ausführbare Programm oder eine Bibliothek).
Syntax:
Ziel: Abhängigkeit1 Abhängigkeit2 Abhängigkeit3 …
[TAB] Aktion1
[TAB] Aktion2
Beispiel:
dummy.bin: dummy.o
gcc dummy.o -o dummy.bin
Die Aktionen dienen dazu, aus den Abhängigkeiten das Ziel zu erstellen. Dies sind Befehle, die nacheinander ausgeführt werden.
Das erste Ziel im Makefile hat eine Sonderrolle:
Wird beim Aufruf von Make kein Ziel angegeben, so wird automatisch dieses Ziel genommen (oft "all").
Es gibt Fälle, in denen ein Ziel immer neu erzeugt werden soll, egal von welchen Ziele diese abhängen. Solche Ziele werden als phony targets bezeichnet. Make würde in dem Beispiel unten ein "make clean" grundsätzlich ausführen, selbst wenn im Ordner eine Datei mit dem Namen "clean" existieren sollte.
OBJ = file1.o file2.o
BIN = simple_main
.PHONY: clean
clean:
rm -rf $(BIN) $(OBJ)
Man kann in Makefiles Variablen definieren und benutzen, wobei diese überlicherweise groß geschrieben werden.
Gebräuchlich sind unter anderem folgende Variablen:
Variablen können auch beim Aufruf von Make gesetzt werden:
make CC=gcc CFLAGS="-Wall"
Mit diesem Operator kann man einer Variablen Werte zuweisen. Beispiel:
CC := gcc
Bei einer einfachen Zuweisung wird der Wert ausgewertet und gespeichert, sobald die erste Definition gefunden wird.
Bei diesem Operator wird der Wert der Variablen nicht sofort ausgewertet, sonder jedes mal wenn dieser in einer Aktion benutzt wird. Beispiel:
CC = gcc
CFLAGS = -I . -Wall
dummy: dummy.c
${CC} ${CFLAGS} -c dummy.c -o dummy.o
Es würde zum Bauen also "gcc -I . -Wall -c dummy.c -o dummy.o" aufgerufen. Wenn z.B. CC später geändert würde, dann ändert sich der Aufruf entsprechend!
Bei diesem Operator wird der Wert der Variablen nur gesetzt, wenn diese vorher noch keinen Wert hatte. Beispiel:
DEBUGFLAGS ?= -DDEBUG
Die Variable DEBUGFLAGS wird nur auf dem Wert "-DDEBUG" gesetzt, wenn diese noch keinen Wert hatte.
Bei diesem Operator wird der Wert an den vorhanden Wert der Variablen angehängt. Beispiel:
CFLAGS = -I
CFLAGS += -Wall
CFLAGS hat im Beispiel jetzt den Wert "-I -Wall"
Wie bei den Regeln kann auch hier das %-Zeichen für Pattern Matching benutzt werden. Beispiel:
OBJ = dummy1.o dummy2.o dummy3.o
SRC = $(OBJ:%.o=%.c)
Die Variable SRC hat danach den Wert "dummy1.c dummy2.c dummy3.c".
Das Zeichen % kann als Joker-Zeichen für Pattern Matching benutzt werden, um allgemeine Ziele zu erstellen. Beispiel:
%.o: %.c
Aktionen
OBJ = dummy1.o dummy2.o dummy3.o dummy4.o dummy5.o
SRC = $(OBJ:%.o=%.c)
Sobald ein % in der Abhängigkeiten-Liste auftaucht wird dieses durch den selben String ersetzt, der benutzt wurde um die Ersetzung im Ziel durchzuführen.
Innerhalb von Aktionen können spezielle Variablen für die Angabe der Dateinamen benutzt werden. Einige davon sind:
Folgendes Makefile dient dazu, automatisch die Abhängigkeiten von den Header-Datei zu berücksichtigen:
OBJ = dummy1.o dummy2.o dummy3.o dummy4.o dummy5.o
SRC = $(OBJ:%.o=%.c)
DEPFILE = .depend
.PHONY: depends
dep: $(SRC)
$(CC) -MM $(SRC) > $(DEPFILE)
-include $(DEPFILE)
Durch die Option -MM gibt der Präprozessor eine Liste der #includes im passenden Format für make aus, welche dann in eine Datei umgelenkt wird.
Am Ende das Makefiles wird diese Datei eingebunden. Das -include sorgt dafür, dass es zu keinem Fehler kommt falls diese Datei fehlt. Durch folgenden Aufruf kann man diese Datei aktualisieren lassen:
make dep