# 15May24: Beispiel Makefile (und Template) für die Datien welche # heute erarbeitet wurden. # Make ist ein Programm welches in einer Datenbank -- diese Datei -- # nach Befehlen nachschlagt welcher Befehl eine Datei baut. # # Man gibt in der Shell # # $ make foo # # um die Datei "foo" zu bauen, oder nur # # $ make # # um die "default" Datei zu bauen. In beiden Fällen führt es die # notwendigen Befehle aus dieser "Makefile" aus. ### AUFBAU # Eine Makefile besteht im wesentlichen aus zwei Bestandteilen: # # 1. Makro-Definitionen, welche die Form # # FOO = ... # # haben, und später Instanzen von $(FOO) mit ... ersetzen. # # 2. Übersetzungsregeln, welche die Form # # [out]: [in1 in2 in3 ...] # [Shell Befehl] # # haben. Wenn [out] neuer ist als "in1" oder "in2", ... wird # [Shell Befehl] ausgeführt. Der [Shell Befehl] sollte ans # Nebeneffekt die Datei [out] erstellen. # # Zeilen welche mit einer Raute (#) Anfangen sind Kommentare. ### INHALT # Diese zwei Definitionen sind konventionell, und sollten immer # angegeben werden: # Der "_C_ _C_ompiler" ist nur der Programm-Name des Übersetzers: CC = gcc # Die "C Flags" führen allgemeine Optionen auf, welche bei Übersetzen # von C Code vom Interesse sind. In unserem Fall geben wir die SP # Flags von der Webseite an: CFLAGS = -Wall -Werror -D_XOPEN_SOURCE=700 -std=c11 -pedantic # Die erste Regel wird immer ausgeführt, wenn wir "make" ohne weitere # Argumente aufrufen. Konvention ist hier wieder da ein Target namens # "all" anzugeben. # # Bei "all" handelt es sich jedoch /nicht/ um eine Datei welche # übersetzt werden soll, sondern um einen Art Pseudo-Befehl welches # alles Bauen soll, was die Makefile unterstützen soll. .PHONY: all # Diese Regel braucht daher keinen Shell Befehl, sondern gibt nur # Abhängigkeiten an: all: list-run fork-basic # Hier die erste Regel: Um die Datei "list-run" zu bauen, brauchen wir # zwei .o Dateien. Wenn diese nicht existieren, wird Make erst # versuchen dafür zu sorgen. Ansonsten fuhrt es denn nachfolgenden # Befehl aus: list-run: list-run.o exec1.o $(CC) -o list-run list-run.o exec1.o # Da wir bei diesem Befehl direkt eine ausführbare Datei aus einer C # Datei übersetzen, muss die Datei "fork-basic.c" bereits existieren. # Ist das nciht der Fall, gibt es einen Fehler. fork-basic: fork-basic.c $(CC) $(CFLAGS) -o fork-basic fork-basic.cv # Hier ist eine Regel für die rekursive Abhängigkeit von "list-run". # Die Objekt Datei "list-run.o" wird aus der .c Datei und dem Header # gebaut, welches in der Datei #include'et wurde. Ändert sich eines # von den beiden, wollen wir die .o Datei neu bauen lassen. list-run.o: list-run.c exec1.h $(CC) $(CFLAGS) -c list-run.c -o list-run.o exec1.o: exec1.c exec1.h $(CC) $(CFLAGS) -c exec1.c -o exec1.o # Am Ende noch eine Phony/Pseudo-Regel die man konventionell immer # vorfindet. Man soll "clean" als die inverse Operation von "all" # verstehen, welche alles löscht was die Datei erstellen konnte (aber # nicht die Eingaben). .PHONY: clean clean: rm -rf exec1.o list-run.o fork-basic list-run ### Default Datenbank # Man kann bei den .o Regeln kein Befehl hinschreiben, denn Make kommt # mit einer eingebauten Datenbank. Man kann diese mit # # $ make -p # # ausgeben. Darin ist unter anderem eine generische Regel, für das # Übersetzen von einer .c zu einer .o Datei. Wir wollen diese # >>NICHT<< in SP benutzen. Aus didaktischen Gründen, sollen alle # Regeln in der Makefile selbst stehen. Wenn man make mit den # Optionen "-r -R" oder kurz "-rR" aufruft, deaktiviert man die # eingebaute Datenbank und überprüft ob die Makefile richtig # geschrieben ist.