# 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.