Explorer les Livres électroniques
Catégories
Explorer les Livres audio
Catégories
Explorer les Magazines
Catégories
Explorer les Documents
Catégories
ENSIMAG 1A
Anne scolaire 20082009
Un Makefile est un fichier, utilis par le programme make, regroupant une srie de commandes permettant dexcuter un ensemble dactions, typiquement la compilation dun
projet. Un Makefile peut tre crit la main, ou gnr automatiquement par un utilitaire (exemples : automake, gmake, . . .). Il est constitu dune ou de plusieurs rgles de la
forme :
cible: dpendances
commandes
Lors du parcours du fichier, le programme make value dabord la premire rgle rencontre, ou celle dont le nom est spcifi en argument. Lvaluation dune rgle se fait
rcursivement :
1. les dpendances sont analyses : si une dpendance est la cible dune autre rgle,
cette rgle est son tour value ;
2. lorsque lensemble des dpendances a t analys, et si la cible est plus ancienne que
les dpendances, les commandes correspondant la rgle sont excutes.
Exemple
Ce qui suit prsente la cration dun Makefile pour un exemple de projet. Supposons
pour commencer que ce projet regroupe trois fichiers exemple.h, exemple.c et main.c.
1.1
Makefile de base
En effet pour crer lexcutable mon_executable, nous avons besoin des fichiers objets
exemple.o et main.o. make va dabord rencontrer exemple.o, et va donc valuer la rgle
dont ce fichier est la cible. La seule dpendance de cette rgle tant exemple.c, qui nest
pas cible dune autre rgle, make va excuter la commande :
gcc -o exemple.o -c exemple.c -Wall -O
De la mme faon, make va ensuite analyser la rgle dont main.o est la cible et excuter
la commande :
gcc -o main.o -c main.c -Wall -O
Finalement, toutes les dpendances de la rgle initiale ayant t analyses, make va excuter la commande :
gcc -o monexecutable exemple.o main.o
1.2
Un premier raffinement
1.3
Introduction de variables
Il est possible de dfinir des variables dans un Makefile. Elles se dclarent sous la forme
NOM=valeur et sont appeles sous la forme $(NOM), peu prs comme dans un shellscript.
Parmi quelques variables standards pour un Makefile de projet C ou C++, on trouve :
CC qui dsigne le compilateur utilis ;
CFLAGS qui regroupe les options de compilation ;
LDFLAGS qui regroupe les options ddition de liens ;
EXEC ou TARGET qui regroupe les excutables.
Pour notre projet exemple, cela donne :
CC=gcc
CFLAGS=-Wall -O
LDFLAGS=
EXEC=mon_executable
all: $(EXEC)
mon_executable: exemple.o main.o
$(CC) -o mon_executable exemple.o main.o $(LDFLAGS)
exemple.o: exemple.c
$(CC) -o exemple.o -c exemple.c $(CFLAGS)
main.o: main.c exemple.h
$(CC) -o main.o -c main.c $(CFLAGS)
clean:
rm -f *.o core
mrproper: clean
rm -f $(EXEC)
Il existe aussi, et cest encore plus intressant car trs puissant, des variables internes au
Makefile, utilisables dans les commandes ; notamment :
$@ : nom de la cible ;
$< : nom de la premire dpendance ;
$ : liste des dpendances ;
$? : liste des dpendances plus rcentes que la cible ;
$* : nom dun fichier sans son suffixe.
On peut donc encore compacter notre Makefile :
CC=gcc
CFLAGS=-Wall -O
LDFLAGS=
3
EXEC=mon_executable
all: $(EXEC)
mon_executable: exemple.o main.o
$(CC) -o $@ $^ $(LDFLAGS)
exemple.o: exemple.c
$(CC) -o $@ -c $< $(CFLAGS)
main.o: main.c exemple.h
$(CC) -o $@ -c $< $(CFLAGS)
clean:
rm -f *.o core
mrproper: clean
rm -f $(EXEC)
1.4
Rgles dinfrences
On voit nanmoins quil y a encore moyen damliorer ce Makefile : en effet les rgles dont
les deux fichiers objets sont les cibles se ressemblent fortement. Or justement, on peut
crer des rgles gnriques dans un Makefile : il suffit dutiliser le symbole % la fois pour
la cible et pour la dpendance. Il est galement possible de prciser sparement dautres
dpendances pour les cas particuliers, par exemple pour ne pas oublier la dpendance au
fichier exemple.h pour la rgle dont main.o est la cible. Ceci nous donne :
CC=gcc
CFLAGS=-Wall -O
LDFLAGS=
EXEC=mon_executable
all: $(EXEC)
mon_executable: exemple.o main.o
$(CC) -o $@ $^ $(LDFLAGS)
main.o: exemple.h
%.o: %.c
$(CC) -o $@ -c $< $(CFLAGS)
clean:
rm -f *.o core
mrproper: clean
4
rm -f $(EXEC)
1.5
On peut encore simplifier ce Makefile. En effet, on constate que la gnration de lexcutable dpend de tous les fichiers objets. Ceci peut tre long crire dans le cas dun
gros projet ! Pour simplifier lcriture, sachant que tous les fichiers objets correspondent
aux fichiers sources en remplaant lextension .c par lextension .o, on peut utiliser les
variables SRC et OBJ et dfinir OBJ=$(SRC :.c=.o). SRC sera dfinie par la liste des fichiers
sources . . . ce qui na fait que dplacer le problme ! L encore, une syntaxe particulire
permet de simplifier le Makefile : SRC=$(wildcard *.c). wildcard permet lutilisation
de la variable $* en dehors dune commande.
Le Makefile du projet exemple devient finalement :
CC=gcc
CFLAGS=-Wall -O
LDFLAGS=
EXEC=mon_executable
SRC=$(wildcard *.c)
OBJ=$(SRC:.c=.o)
all: $(EXEC)
mon_executable: $(OBJ)
$(CC) -o $@ $^ $(LDFLAGS)
main.o: exemple.h
%.o: %.c
$(CC) -o $@ -c $< $(CFLAGS)
clean:
rm -f *.o core
mrproper: clean
rm -f $(EXEC)
Il existe encore bien dautres possibilits pour simplifier un Makefile. Il est notamment
possible de crer des Makefile pour des sous-rpertoires correspondant des sous-parties
du projet, et davoir un Makefile matre trs simple qui appelle ces sous-Makefile,
avec la variable MAKE. Il existe galement des outils de gnration automatique.