Make
La commande make
est un utilitaire permettant de décrire les dépendances d’une application,
de compiler les fichiers sources et de linker les fichiers objets nécessaires à sa génération
make
La description de ces dépendances se fait par l’intermédiaire d’un fichier texte
exec: main.o libmymathlib.a
gcc main.o -lmymathlib -L. -o exec
main.o: main.c mymathlib.h
gcc -Wall -Wextra -g -c -O0 -std=gnu11 -o main.o main.c
Le nom de défaut est Makefile, mais il possible de le nommer différemment
make -f Makefile
Principe et syntaxe
Un makefile est constitué d’une suite de règles
cible: dépendances
commande
cible
:- nom du fichier (exécutable, objet … généré par la commande
- ou action à effectuer, telle que
all
,clean
ouinstall
dépendances
: fichiers utilisés comme fichiers sources pour la génération de la ciblecommande
:- recette / action utilisée pour générer la cible
- exécutée si au moins une des dépendances plus récentes que la cible
- attention : l’indentation de la commande doit être faite avec un caractère Tab et non avec des espaces.
Variables
L’utilisation de variables permet de simplifier grandement l’écriture des Makefile
EXEC=exec
CC=gcc
CFLAGS=-Wall -Wextra -g -c -O0 -std=gnu11
LDFLAGS=-lmymathlib -L.
Exemple :
$(EXEC): main.o libmymathlib.a
$(CC) main.o $(LDFLAGS) -o $(EXEC)
main.o: main.c mymathlib.h
$(CC) $(CFLAGS) -o main.o main.c
Plusieurs cibles
Il est possible de spécifier plusieurs cibles dans un même Makefile
EXEC=exec
CC=gcc
CFLAGS=-Wall -Wextra -g -c -O0 -std=gnu11
LDFLAGS=-lmymathlib -L.
all: $(EXEC)
$(EXEC): main.o libmymathlib.a
$(CC) main.o $(LDFLAGS) -o $(EXEC)
main.o: main.c mymathlib.h
$(CC) $(CFLAGS) -o main.o main.c
clean:
rm -Rf $(EXEC) *.o
.PHONY: all clean
all
: Pour générer l’application (fichier de sortie), il suffit de tapermake
oumake all
. Si aucune cible n’est spécifiée, c’est la première cible qui se trouve dans le Makefile qui sera généré.clean
: Pour effacer le fichier de sortie et tous les fichiers de dépendances, il suffit de tapermake clean
.PHONY
:- Pour indiquer que les cibles
all
etclean
sont factices - Pour forcer leur reconstruction
- Pour indiquer que les cibles
Règles suffixes
Les règles suffixes permettent d’éviter de spécifier pour chaque fichier (cible) les commandes à effectuer :
SRCS=main.c
OBJS=$(SRCS:.c=.o)
EXEC=exec
CC=...
all: $(EXEC)
$(EXEC): $(OBJS) libmymathlib.a
$(CC) $(LDFLAGS) $^ -o $@
%.o: %.c
$(CC) $(CFLAGS) $< -o $@
clean:
...
SRCS=main.c
: Liste des fichiers sourcesOBJS=$(SRCS:.c=.o)
: Expression pour remplacer l’extension.c
des noms de fichiers sources contenus dans la variableSRCS
par l’extension.o
des fichiers cibles%.o: %.c
: Règle suffixe pour la compilation des fichiers sources.c
en fichiers cibles.o
- Explication des variables :
$@
: nom de la cible$<
: nom du fichier source$*
: nom du fichier sans le suffixe$^
: nom de toutes les dépendances$?
: noms de toutes les dépendances plus récentes que la cible
Génération des dépendances
Lors de la génération d’applications développées en C il est essentiel de garantir que celles-ci soient correctement générées et que toutes les modifications soient bien prises en compte
Le compilateur GNU permet de générer pour chaque fichier source un fichier de ses dépendances, lequel pourra ensuite être utilisé dans le Makefile
...
CFLAGS=-Wall -Wextra -g -c -O0 -std=gnu11 -MD
...
all: $(EXEC)
...
-include $(OBJS:.o=.d)
clean:
rm -Rf $(EXEC) $(OBJS) $(OBJS:.o=.d)
-MD
: Option du compilateur pour forcer la génération d’un fichier de dépendanceinclude $(OBJS:.o=.d)
: Instruction pour inclure tous les fichiers de dépendances- Ne pas oublier d’effacer les fichiers de dépendances…
Conditions
Des directives permettant d’exécuter conditionnellement une partie du Makefile, ceci en fonction d’une variable et de sa valeur
ifeq ($(VARIABLE), value)
## if true do that
else
## if false do that
endif
La variable peut être contenue dans le Makefile, mais il est également possible de la spécifier lors de l’appel du Makefile
make VARIABLE=value target
Cette technique permet de générer un logiciel pour différentes plateformes (machine hôte, cible …) ou en différentes versions (release, debug, …)
Sous-Makefile
Pour simplifier la génération de grands projets, il est possible de créer des sous-Makefile
La variable $(MAKE)
fournit l’outil nécessaire à l’appel de sous-Makefile
target:
$(MAKE) -C directory_name target
Le mot clef export
permet de passer les variables à des sous-Makefile
export CFLAGS
Alternatives à make
Make est un outil qui date de 1977. Il est très puissant, mais il est aussi très difficile à maîtriser. Aujourd’hui, de nombreuses alternatives plus modernes existent :