# Kommentare können so geschrieben werden. # Dateien sollten Makefile heißen, denn dann können sie als `make ` # aufgerufen werden. Ansonsten muss `make -f "dateiname" ` verwendet # werden. # Warnung - Es sollten nur TABULATOREN zur Einrückung im Makefile verwendet # werden. Niemals Leerzeichen! #----------------------------------------------------------------------- # Grundlagen #----------------------------------------------------------------------- # Eine Regel - Diese Regel wird nur abgearbeitet, wenn die Datei file0.txt # nicht existiert. file0.txt: echo "foo" > file0.txt # Selbst Kommentare in der 'Rezept' Sektion werden an die Shell # weitergegeben. Versuche `make file0.txt` oder einfach `make` # die erste Regel ist die Standard-Regel. # Diese Regel wird nur abgearbeitet, wenn file0.txt aktueller als file1.txt ist. file1.txt: file0.txt cat file0.txt > file1.txt # Verwende die selben Quoting-Regeln wie die Shell @cat file0.txt >> file1.txt # @ unterdrückt die Ausgabe des Befehls an stdout. -@echo 'hello' # - bedeutet, dass Make die Abarbeitung fortsetzt, auch wenn Fehler # passieren. # Versuche `make file1.txt` auf der Kommandozeile. # Eine Regel kann mehrere Ziele und mehrere Voraussetzungen haben. file2.txt file3.txt: file0.txt file1.txt touch file2.txt touch file3.txt # Make wird sich beschweren, wenn es mehrere Rezepte für die gleiche Regel gibt. # Leere Rezepte zählen nicht und können dazu verwendet werden weitere # Voraussetzungen hinzuzufügen. #----------------------------------------------------------------------- # Phony-Ziele #----------------------------------------------------------------------- # Ein Phony-Ziel ist ein Ziel, das keine Datei ist. # Es wird nie aktuell sein, daher wird Make immer versuchen, es abzuarbeiten all: maker process # Es ist erlaubt Dinge außerhalb der Reihenfolge zu deklarieren. maker: touch ex0.txt ex1.txt # Um das Fehlschlagen von Phony-Regeln zu vermeiden wenn eine echte Datei den # selben Namen wie ein Phony-Ziel hat: .PHONY: all maker process # Das ist ein spezielles Ziel. Es gibt noch ein paar mehr davon. # Eine Regel mit einem Phony-Ziel als Voraussetzung wird immer abgearbeitet ex0.txt ex1.txt: maker # Häufige Phony-Ziele sind: all make clean install ... #----------------------------------------------------------------------- # Automatische Variablen & Wildcards #----------------------------------------------------------------------- process: file*.txt # Eine Wildcard um Dateinamen zu vergleichen @echo $^ # $^ ist eine Variable die eine Liste aller # Voraussetzungen enthält. @echo $@ # Namen des Ziels ausgeben. #(Bei mehreren Ziel-Regeln enthält $@ den Verursacher der Abarbeitung #der Regel.) @echo $< # Die erste Voraussetzung aus der Liste @echo $? # Nur die Voraussetzungen, die nicht aktuell sind. @echo $+ # Alle Voraussetzungen inklusive Duplikate (nicht wie üblich) #@echo $| # Alle 'order only' Voraussetzungen # Selbst wenn wir die Voraussetzungen der Regel aufteilen, $^ wird sie finden. process: ex1.txt file0.txt # ex1.txt wird gefunden werden, aber file0.txt wird dedupliziert. #----------------------------------------------------------------------- # Muster #----------------------------------------------------------------------- # Mit Mustern kann man make beibringen wie Dateien in andere Dateien # umgewandelt werden. %.png: %.svg inkscape --export-png $^ # Muster-Vergleichs-Regeln werden nur abgearbeitet, wenn make entscheidet das # Ziel zu erzeugen # Verzeichnis-Pfade werden normalerweise bei Muster-Vergleichs-Regeln ignoriert. # Aber make wird versuchen, die am besten passende Regel zu verwenden. small/%.png: %.svg inkscape --export-png --export-dpi 30 $^ # Make wird die letzte Version einer Muster-Vergleichs-Regel verwenden, die es # findet. %.png: %.svg @echo this rule is chosen # Allerdings wird make die erste Muster-Vergleicher-Regel verwenden, die das # Ziel erzeugen kann. %.png: %.ps @echo this rule is not chosen if *.svg and *.ps are both present # Make hat bereits ein paar eingebaute Muster-Vergleichs-Regeln. Zum Beispiel # weiß Make wie man aus *.c Dateien *.o Dateien erzeugt. # Ältere Versionen von Make verwenden möglicherweise Suffix-Regeln anstatt # Muster-Vergleichs-Regeln. .png.ps: @echo this rule is similar to a pattern rule. # Aktivieren der Suffix-Regel .SUFFIXES: .png #----------------------------------------------------------------------- # Variablen #----------------------------------------------------------------------- # auch Makros genannt. # Variablen sind im Grunde genommen Zeichenketten-Typen. name = Ted name2="Sarah" echo: @echo $(name) @echo ${name2} @echo $name # Das funktioniert nicht, wird als $(n)ame behandelt. @echo $(name3) # Unbekannte Variablen werden als leere Zeichenketten behandelt. # Es gibt 4 Stellen um Variablen zu setzen. # In Reihenfolge der Priorität von höchster zu niedrigster: # 1: Befehls-Zeilen Argumente # 2: Makefile # 3: Shell Umgebungs-Variablen - Make importiert diese automatisch. # 3: Make hat einige vordefinierte Variablen. name4 ?= Jean # Setze die Variable nur wenn es eine gleichnamige Umgebungs-Variable noch # nicht gibt. override name5 = David # Verhindert, dass Kommando-Zeilen Argumente diese Variable ändern können. name4 +=grey # Werte an eine Variable anhängen (inkludiert Leerzeichen). # Muster-Spezifische Variablen Werte (GNU Erweiterung). echo: name2 = Sara # Wahr innerhalb der passenden Regel und auch innerhalb # rekursiver Voraussetzungen (außer wenn es den Graphen zerstören # kann, wenn es zu kompliziert wird!) # Ein paar Variablen, die von Make automatisch definiert werden. echo_inbuilt: echo $(CC) echo ${CXX} echo $(FC) echo ${CFLAGS} echo $(CPPFLAGS) echo ${CXXFLAGS} echo $(LDFLAGS) echo ${LDLIBS} #----------------------------------------------------------------------- # Variablen 2 #----------------------------------------------------------------------- # Der erste Typ von Variablen wird bei jeder Verwendung ausgewertet. # Das kann aufwendig sein, daher existiert ein zweiter Typ von Variablen. # Diese werden nur einmal ausgewertet. (Das ist eine GNU make Erweiterung) var := hello var2 ::= $(var) hello #:= und ::= sind äquivalent. # Diese Variablen werden prozedural ausgewertet (in der Reihenfolge, in der sie # auftauchen), die stehen daher im Widerspruch zum Rest der Sprache! # Das funktioniert nicht var3 ::= $(var4) and good luck var4 ::= good night #----------------------------------------------------------------------- # Funktionen #----------------------------------------------------------------------- # Make verfügt über eine Vielzahl von Funktionen. sourcefiles = $(wildcard *.c */*.c) objectfiles = $(patsubst %.c,%.o,$(sourcefiles)) # Das Format ist $(func arg0,arg1,arg2...) # Ein paar Beispiele ls: * src/* @echo $(filter %.txt, $^) @echo $(notdir $^) @echo $(join $(dir $^),$(notdir $^)) #----------------------------------------------------------------------- # Direktiven #----------------------------------------------------------------------- # Inkludiere andere Makefile, sehr praktisch für plattformspezifischen Code include foo.mk sport = tennis # Konditionale Kompilierung report: ifeq ($(sport),tennis) @echo 'game, set, match' else @echo "They think it's all over; it is now" endif # Es gibt auch ifneq, ifdef, ifndef foo = true ifdef $(foo) bar = 'hello' endif