# La variable LDFLAGS contient les flags pour l'éditeur
# de liens:
# -lm dit d'éditer les liens avec la lib math
# -lSDL2 dit d'éditer les liens avec la lib SDL2
LDFLAGS=-lm-lSDL2
# Définition des sources
SOURCES= galaxy.c stars.c vec.c
# OBJECTS contient SOURCES avec .c qui devient .o
OBJECTS=$(SOURCES:.c=.o)
# galaxy sera l'exécutable (galaxy.c contient le main)
TARGET= galaxy
#Jusqu'icionaaucunecible.
```
# `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) :$(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
# exécute toujours clean, même si un ficher `clean` existe
.PHONY:clean
clean:# aucune dépendance
rm-f$(TARGET)$(OBJECTS)
```
# Gestion implicite (1/2)
## Question
Pourquoi n'a-t-on pas besoin de générer les `OBJECTS`?
## Réponse
`make` possède une série de règles implicites (voir [ce lien](https://ftp.gnu.org/old-gnu/Manuals/make-3.79.1/html_chapter/make_10.html#SEC95) pour une liste).
## Fonctionnement
Si `make` rencontre une dépendance sans règle, il va voir dans sa liste de règles implicites pour la générer.
Et pour les dépendances des cibles implicites ça se passe comment?
## Réponse
On peut définir individuellement les dites dépendances!
## 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.
```makefile
# 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: `*`, `%`, `:=`, ...
```makefile
# version "longue"
SOURCES=$(wildcard *.c)
OBJECTS=$(SOURCES:.c=.o)
# version "courte"
OBJECTS:=$(patsubst %.c,%.o,$(wildcard *.c))
```
Let's take one step at a time:
* Les `*`{.makefile},
* Les `%`{.makefile}, et leurs différences.
* Les fonctions, ici `wildcard`{.makefile} et `patsubst`{.makefile} (voir respectivement [ce lien](https://www.gnu.org/software/make/manual/html_node/Wildcard-Function.html) et [ce lien](https://www.gnu.org/software/make/manual/html_node/Text-Functions.html)).
* Le symbole `:=`{.makefile} vs `=`{.makefile}.
# Le symbole `*`
## `make` peut "développer" (expand) des `wildcards` (`*`)
* dans les recettes le `*` est géré par le shell
```makefile
clean:
rm-f*.ogalaxy
```
* 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
```
# La différence entre `*` et `%`
* Le symbole `*`{.makefile} sert à générer une *liste* d'objets.
* Le symbole `%`{.makefile} sert comme *emplacement* (placeholder).
## Exemple
```makefile
%.o:%.c # % est la partie avant .c
$(CC)-o$@-c$<$(CFLAGS)# la règle pour chaque `%.c`
# équivalent à
galaxy.o:galaxy.c
stars.o:stars.c
vec.o:vec.c
```
## Application
```makefile
$(patsubst# Substitution de texte pour chaque
%.c,\ # Le pattern "avant" le .c
%.o,\ # Le pattern "avant" le .o
$(wildcard *.c)\ # Tous les fichiers .c
)
```
# Le symbole `:=`{.makefile} vs `=`{.makefile} (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 + imprédictible!).
# 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)):