13 septembre 2018
Copyright M Billaud 2018 - licence creative-commons france 3.0 BY-NC-SA. http://creativecommons.org/licenses/by-nc-sa/3.0/fr/ Attribution + Pas d’Utilisation Commerciale + Partage dans les mêmes conditions
Dernière révision 15 novembre 2021.
L’objectif est de produire, au moindre effort, des fichiers Makefile
qui fonctionnent correctement pour des projets qui mettent en oeuvre la compilation séparée : un exécutable obtenu par édition des liens de plusieurs modules, dont les sources incluent des headers qui éventuellement en incluent eux mêmes.
Explicitation des critères
Makefile
qui marche correctement : recompile tout ce qui doit l’être, et rien d’autre,Moyens
-MMD
) qu’offre gcc/g++
de générer, pendant la compilation d’un source, un fichier contenant la liste de dépendances (les fichiers qu’il inclut) ;Makefile
d’inclure d’autres makefiles.Le projet contient deux sources (hello.c
et salutations.c
), et un fichier d’en-tête salutations.h
.
Programme principal
// hello.c
#include <stdlib.h>
#include "salutations.h"
int main(void)
{
dire_bonjour();return EXIT_SUCCESS;
}
Fonctions auxiliaires
// salutations.c
#include <stdio.h>
#include "salutations.h"
void dire_bonjour() {
"Bonjour !\n");
printf( }
Prototypes des fonctions auxiliaires
// salutations.h
#ifndef SALUTATIONS_H
#define SALUTATIONS_H
void dire_bonjour();
#endif
CFLAGS = --std=c11
CFLAGS += -Wall -Wextra -pedantic
CFLAGS += -MMD # génération des dépendances
CFLAGS += -g
EXECS = hello # les exécutables à fabriquer
all: $(EXECS)
hello: hello.o salutations.o # composition de hello
-include $(wildcard *.d) # inclusion des dépendances
clean:
$(RM) *.o *.d *~
mrproper: clean
$(RM) $(EXECS)
La ligne “-include $(wildcard *.d)
” du Makefile
demande la lecture des fichiers *.d
qui sont présents dans le répertoire lors du lancement de make
. Et ne fait rien si il n’y en a pas.
La compilation d’un source avec l’option -MMD
fabrique un fichier de dépendances.
Le premier lancement de make
fabrique l’exécutable hello
en laissant aussi comme “sous-produits” des fichiers hello.d
salutations.d
(en plus des fichiers objets suffixés “.o
”).
Ces fichiers, qui contiennent respectivement
hello.o: hello.c salutations.h
et
salutations.o: salutations.c salutations.h
sont des makefiles basiques, contenant seulement une règle de dépendance, qui liste (de façon transitive) tous les fichiers dont dépend un module objet.
Le lancement suivant de make
, si on a modifié par exemple salutations.h
, provoquera donc la recompilation des deux sources, comme il est souhaitable, et la mise à jour des dépendances.
La méthode présentés ci-dessus ne demande que d’ajouter
-MMD
pour la compilation-include $(wildcard *.d)
et elle évite d’avoir à écrire la liste des dépendances à la main, ce qui est une source habituelle d’erreurs lors des changements
Elle est donc parfaitement recommandable, pour les petits comme pour les grands.
Remarques
-MMD
, ne figurent que les inclusions “utilisateurs”. L’option -MM
fournit aussi la liste des d’en-têtes système.-include
” avant la première cible, sinon la commande make
va lancer l’exécution de la cible du premier fichier de dépendance.Problèmes éventuels
.o
et .d
par un make clean
. La prochaine compilation régénère les dépendances.