--- title: Plus de Makefiles date: 2021-03-03 --- # `make` avancé ## Rappel: utilité - Automatiser le processus de conversion d'un type de fichier à un autre, en *gérant les dépendances*. - Effectue la conversion des fichiers qui ont changé uniquement. - Utilisé pour la compilation: - 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`). # Utilisation de `make` ## `Makefile` simple :::::::::::::: {.columns} ::: {.column width="60%"} ```bash # Les commentaires commencent # par # # exemple est la cible, example.o # la dépendance example: example.o # ligne exécuté à l'appel de # `make` (`make example`) gcc -o example example.o # exemple.o est la cible, example.c # et example.h les dépendances exmaple.o: exmaple.c example.h # ligne exécuté à l'appel de # `make example.o` gcc -c example.c ``` ::: ::: {.column width="40%"} ## Terminal ```bash $ make gcc -c example.c gcc -o example example.o ``` ::: :::::::::::::: # `Makefile` plus complexe (1/3) ```makefile # Un Makefile typique # Le compilateur CC = gcc # La variable CFLAGS contient les flags de compilation: # -g compile avec les infos de debug # -Wall Plein de warning # -Wextra Encore plus de warnings # -pedantic Warning lvl archimage # -O0 Option d'optimisation (0,1,2,3) # -std=c11 Utilisation du standard c11 # -fsanitize=address Utilisation du standard c11 CFLAGS = -g -Wall -O0 -std=c11 ``` # `Makefile` plus complexe (2/3) ```makefile # La variable LDFLAGS contient les flags pour l'éditeur # de liens: -lm dit d'éditer les liens avec la lib math LDFLAGS = -lm # Définition des sources SOURCES = galaxy.c stars.c vec.c # OBJECTS contient SOURCES avec .c -> .o OBJECTS = $(SOURCES:.c=.o) # galaxy sera l'exécutable (galaxy.c contient le main) TARGET = galaxy # Jusqu'ici on a aucune cible. ``` # `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 .PHONY: clean clean: # aucune dépendance rm -f $(TARGET) $(OBJECTS) ``` # Gestion implicites (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? ## 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 Quand `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 $(CPPFLAGS) $(CFLAGS) ``` # Gestion implicites (2/2) ## Question Et pour les dépendances des cibles implicites ça se passe comment? ## Réponse On peut définir individuellement les ## 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. 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 $(CPPFLAGS) $(CFLAGS) ``` # Macros ## Les macros - Assignation ```make CC = gcc CFLAGS = -g -Wall -Wextra -pedantic -O0 -std=c11 LDFLAGS = -lm ``` - Utilisation ```bash $(CC) ``` - Déclaration à la ligne de commande ```bash make CFLAGS="-O3 -Wall" ``` ## Variables internes - `$@` : la cible - `$^` : la liste des dépendances - `$<` : la première dépendance - `$*` : le nom de la cible sans extension