From 5a2e4b56cffd28b72e506238d5b17882a79075ad Mon Sep 17 00:00:00 2001
From: Orestis <orestis.malaspinas@pm.me>
Date: Wed, 10 Mar 2021 00:30:07 +0100
Subject: [PATCH] maj slides, et makefile exemple

---
 exemples/make/Makefile |  46 +++++++++++---
 slides/make_avance.md  | 140 ++++++++++++++++++++++++++++++++---------
 2 files changed, 148 insertions(+), 38 deletions(-)

diff --git a/exemples/make/Makefile b/exemples/make/Makefile
index 4389dc8..b47513b 100644
--- a/exemples/make/Makefile
+++ b/exemples/make/Makefile
@@ -1,26 +1,52 @@
+# galaxy: galaxy.o stars.o vec.o
+# 	gcc -o galaxy galaxy.o stars.o vec.o
+
+# galaxy.o: galaxy.c stars.h
+# 	gcc -c galaxy.c
+
+# stars.o: stars.c stars.h vec.h
+# 	gcc -c stars.c
+
+# vec.o: vec.c vec.h
+# 	gcc -c vec.c
+
+# clean:
+# 	rm -f *.o galaxy
+
 CC = gcc
-CFLAGS = -g -Wall -O0 -std=c11
+CFLAGS = -g -Wall -Wextra -pedantic -O0 -std=c11
 LDFLAGS = -lm
 
-# SOURCES = main.c foo.c bar.c
+x = foo
+y = $(x) bar
+x = later
+
+######### advanced v1 ############
+SOURCES = galaxy.c stars.c vec.c
+##################################
+
+######### advanced v2 ############
+# SOURCES = $(wildcard *.c)
 # means *.c
-SOURCES = $(wildcard *.c)
+##################################
+
+# OK pour v1 et v2
 # OBJECTS contient SOURCES avec .c -> .o
 OBJECTS = $(SOURCES:.c=.o)
 
+######### advanced v3 ############
 # OBJECTS := $(patsubst %.c,%.o,$(wildcard *.c))
+##################################
 
 # galaxy sera l'exécutable (galaxy.c contient le main)
-TARGET = main
+TARGET = galaxy
 $(TARGET) : $(OBJECTS)
+	@echo $(x) $(y)
 	$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
 
-# main: main.o foo.o bar.o
-# 	cc -o $@ $^ $(CFLAGS) $(LDFLAGS)
-# 
-# foo.o: foo.h
-# bar.o: bar.h
-# main.o: foo.h
+# galaxy.o: stars.h vec.h
+# stars.o: *.h
+# vec.o: vec.h
 
 .PHONY: clean
 
diff --git a/slides/make_avance.md b/slides/make_avance.md
index a5a503e..035659e 100644
--- a/slides/make_avance.md
+++ b/slides/make_avance.md
@@ -13,28 +13,28 @@ date: 2021-03-03
   - Création du code objet à partir des sources.
   - Création de l'exécutable à partir du code objet.
 - Tout "gros" projet utilise `make` (pas uniquement en `C`).
+- Un `Makefile` bien écrit ne recompile que ce qui est **nécessaire**![^1]
 - Il existe d'autres outils pour le `C` et d'autres langages (`cmake`, `meson`, `maven`, `cargo`, ...).
 
-# Utilisation de `make`
+[^1]: Par pitié arrêtez de faire un `rebuild` ou un `clean` à chaque compilation.
 
-## `Makefile` simple
+# Utilisation de `make`
 
 ::::::::::::::  {.columns}
 ::: {.column width="60%"}
 
+## `Makefile` simple
+
 ```bash
 galaxy: galaxy.o stars.o vec.o
-    gcc -o galaxy galaxy.o stars.o vec.o
-
-galaxy.o: galaxy.c
+    gcc -o galaxy galaxy.o stars.o \
+        vec.o
+galaxy.o: galaxy.c stars.h
     gcc -c galaxy.c
-
 stars.o: stars.c stars.h vec.h
     gcc -c galaxy.c
-
 vec.o: vec.c vec.h
     gcc -c vec.c
-
 clean:
     rm -f *.o galaxy
 ```
@@ -42,8 +42,6 @@ clean:
 :::
 ::: {.column width="40%"}
 
-**Dessinez le diagramme de dépendances de ce `Makefile`**.
-
 ## Terminal
 
 ```bash
@@ -51,13 +49,16 @@ $ make
 gcc -c galaxy.c
 gcc -c stars.c
 gcc -c vec.c
-gcc -o galaxy galaxy.o stars.o vec.o
+gcc -o galaxy galaxy.o
+    stars.o vec.o
 $ make clean
 rm -f *.o galaxy
 ```
 :::
 ::::::::::::::
 
+**Dessinez le diagramme de dépendances de ce `Makefile`**.
+
 # Diagramme de dépendances
 
 ~~~{.mermaid format=png}
@@ -101,7 +102,7 @@ LDFLAGS = -lm
 
 # Définition des sources
 SOURCES = galaxy.c stars.c vec.c
-# OBJECTS contient SOURCES avec .c -> .o
+# OBJECTS contient SOURCES avec .c qui devient .o
 OBJECTS = $(SOURCES:.c=.o)
 # galaxy sera l'exécutable (galaxy.c contient le main)
 TARGET = galaxy
@@ -111,15 +112,15 @@ TARGET = galaxy
 # `Makefile` plus complexe (3/3)
 
 ```makefile
-# TARGET est la première cible et sera donc exécuté à l'invocation de `make`
-# Elle dépend de OBJECTS
+# TARGET est la première cible et sera donc exécuté à 
+# l'invocation de `make`. Elle dépend de OBJECTS
 $(TARGET) : $(OBJECTS)
     $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
 # $@ : la cible, $ˆ : la liste des dépendances
 
-# PHONY signifie qu'on ne crée rien avec les cibles mentionnées
-# Ici clean est la cible utilisée pour enlever tous les fichier .o
-# et l'exécutable
+# PHONY signifie qu'on ne crée rien avec les cibles
+# mentionnées. Ici clean est la cible utilisée pour 
+# enlever tous les fichier .o et l'exécutable
 
 .PHONY: clean
 
@@ -127,12 +128,11 @@ clean: # aucune dépendance
     rm -f $(TARGET) $(OBJECTS)
 ```
 
-# Gestion implicites (1/2)
+# Gestion implicite (1/2)
 
 ## Question
 
-Comment cela se fait-il qu'on ait pas besoin de générer les `OBJECTS`
-dans le `Makefile` précédent?
+Pourquoi n'a-t-on pas besoin de générer les `OBJECTS`?
 
 ## Réponse
 
@@ -140,17 +140,17 @@ dans le `Makefile` précédent?
 
 ## Fonctionnement
 
-Quand `make` rencontre une dépendance sans règle, il va voir dans sa liste de règles implicites pour la générer.
+Si `make` rencontre une dépendance sans règle, il va voir dans sa liste de règles implicites pour la générer.
 Ainsi
 
 ```makefile
-foo: foo.o bar.o
-    gcc -o foo foo.o bar.o $(CFLAGS) $(LDFLAGS)
-# implicitement pour foo.c et bar.c
-    $(CC) -c $(CFLAGS)
+galaxy: galaxy.o stars.o vec.o
+    gcc -o galaxy galaxy.o stars.o vec.o $(CFLAGS) $(LDFLAGS)
+# implicitement pour galaxy.c, stars.c et vec.c
+    $(CC) -c $< $(CFLAGS) -o $@
 ```
 
-# Gestion implicites (2/2)
+# Gestion implicite (2/2)
 
 ## Question
 
@@ -166,7 +166,91 @@ Quand `make` rencontre une dépendance sans règle, il va voir dans sa liste de
 Ainsi
 
 ```makefile
-foo.o: foo.h
-bar.o: foo.h bar.h
+# pas besoin des .c qui sont implicites
+galaxy.o: stars.h vec.h
+stars.o: *.h
+vec.o: vec.h
 ```
 
+# On peut faire mieux
+
+Il est possible de prendre **tous** les fichiers `.c`
+
+```makefile
+SOURCES = $(wildcard *.c)
+OBJECTS = $(SOURCES:.c=.o)
+```
+
+Ou encore mieux
+
+```makefile
+OBJECTS := $(patsubst %.c,%.o,$(wildcard *.c))
+```
+
+# That escalated quickly: `*`, `%`, `:=`, ...
+
+Let's take one step at a time:
+
+* Les `*`,
+* Les `%`, et leurs différences.
+* Les fonctions, ici `wildcard` et `patsubst`.
+* Le symbole `:=` vs `=`.
+
+# Le symbole `*`
+
+## `make` peut "développer" (expand) des `wildcards` (`*`)
+
+* dans les recettes le `*` est géré par le shell
+    
+    ```makefile
+    clean:
+        rm -f *.o galaxy
+    ```
+* dans les dépendances
+
+    ```makefile
+    galaxy.o: *.h
+    ```
+    mais des fichiers `.h` doivent exister sinon il interprète `*.h` le nom du fichier.
+
+## Par contre ile ne peut pas
+
+```makefile
+OBJECTS = *.o
+# il faut utiliser
+OBJECTS := $(wildcard *.o) # retourne tous les fichier .o
+```
+
+# Le symbole `:=` vs `=` (1/2)
+
+Deux façon (flavors) d'assigner des variables (voir [ce lien](https://www.gnu.org/software/make/manual/html_node/Flavors.html#Flavors)):
+
+## Le symbole `=`
+
+* Façon **récursive**:
+
+    ```makefile
+    foo = $(bar)
+    bar = $(ugh)
+    ugh = Huh?
+    ```
+    ici `foo` vaut `Huh?`.
+* Valeurs remplacées "récursivement".
+* Variables remplacées à chaque appel (lent + impredictible!).
+
+# Le symbole `:=` vs `=` (2/2)
+
+Deux façon (flavors) d'assigner des variables (voir [ce lien](https://www.gnu.org/software/make/manual/html_node/Flavors.html#Flavors)):
+
+## Le symbole `:=`
+
+* Façon **simplement développée** (`Simply expanded variable`):
+
+    ```makefile
+    x := foo
+    y := $(x) bar
+    x := later
+    ```
+    ici `y` vaut `foo bar` et `x` vaut `later` (avec des `=`, `y` vaudrait `later bar`).
+* Les variables se comportent comme en `C`.
+* En particulier dans les *longs* `Makefile` le comportement est plus prédictible.
-- 
GitLab