Make
Un article de Games Creators Network.
Attention
Cet article est en attente du choix d'une licence par son auteur. Elle n'est pas soumise à la licence par défaut du GCN.
Cela signifie entre autre chose que si vous n'êtes pas l'auteur de cet article, vous n'avez probablement pas le droit de le modifier.
La documentation francaise sur l'outil GNU Make étant relativement restreinte, cet article a pour but de vous faire decouvrir les bases essentielles à la réalisation d'un fichier Makefile.
Rappel: make permet d'ordonner et de faciliter la compilation d'un projet, tout en évitant de recompiler inutilement les objets inchangés. C'est cet outil qui est utilisé quand, par exemple, vous installez un programme a partir de ses sources sous Unix.
Sommaire |
[modifier] Principe de GNU Make
La plupart du temps, à moins d'utiliser un IDE, les fichiers sources sont compilés via la commande shell correspondante. Pour ce cours, nous prendrons l'exemple d'un projet en langage C utilisant GCC. Pour un fichier source unique, la commande utilisée est donc souvent :
gcc fichier.c -o executable -Wall
En ajoutant certains paramètres, comme -Wall pour afficher la totalité des avertissements à la compilation. Si le projet ne comporte qu'un simple fichier, un Makefile est superflu. Néanmoins, c'est rarement le cas et si le projet compte huit fichiers sources on ne peut se permettre de retaper, à chaque modification, une suite d'instructions telle la suivante :
gcc fichier1.c -c -o objet1.o -Wall
gcc fichier2.c -c -o objet2.o -Wall
gcc fichier3.c -c -o objet3.o -Wall
gcc fichier4.c -c -o objet4.o -Wall
gcc fichier5.c -c -o objet5.o -Wall
gcc fichier6.c -c -o objet6.o -Wall
gcc fichier7.c -c -o objet7.o -Wall
gcc fichier8.c -c -o objet8.o -Wall
gcc objet1.o objet2.o objet3.o objet4.o objet5.o \
objet6.o objet7.o objet8.o -o executable
Quand le projet commence à prendre une telle ampleur, il devient nécessaire d'utiliser un outil performant et accessible pour gérer les phases de compilation et, au passage, éviter toute recompilation superflue. GNU Make est un tel outil, le plus utilisé. Son emploi relativement simple va de paire avec celui de scripts shells, aussi est-il recommandé de disposer de quelques bases en langage shell (bash) pour l'utiliser.
[modifier] Bases essentielles
[modifier] Premier Makefile
Pour compiler un projet, Make a besoin d'un fichier comportant les informations requises. Un tel fichier se nomme un Makefile, et le nom du fichier doit être strictement identique. On peut aussi utiliser les orthographes makefile ou .make, mais celles-ci sont deconseillées. Un tel fichier est relativement proche d'un script shell, mais si la syntaxe est parfois la même la structure est differente.
Un Makefile est constitué de règles, chaque règle représentant un ensemble d'opérations bien précises. Le plus souvent, une règle permet de compiler un fichier, d'afficher de l'aide ou de supprimer les fichiers temporaires. Dans son expression la plus simple, une regle est representée comme suit :
cible: pré-requis [tabulation]instructions
La cible est le plus souvent le fichier à construire, mais en règle générale elle représente l'action à effectuer (compiler, effacer etc.) Les pré-requis sont les cibles d'autres règles qui seront realisées avant d'exécuter la suite d'instructions de la règle, chaque ligne étant précédée d'une tabulation. Un pré-requis peut aussi être un fichier nécessaire à l'execution de la regle. Par exemple, si un fichier main.c requiert un en-tete header.h, on peut imaginer le petit Makefile suivant :
all: main.c main.c: header.h echo 'Compilation de main.c' gcc main.c -o executable -Wall
Le fichier main.c ne sera compilé que si le fichier header.h existe. Lors de l'execution de make, si main.c ou header.h ont été modifiés, l'exécutable sera recompilé. La regle executée par defaut est la première rencontrée : nous avons donc ajouté une règle par défaut 'all' necessitant main.c. Un simple appel à make suffira donc à recompiler l'exécutable, si besoin est...
Note : si vous ne désirez pas que les instructions shell soient recopiées dans le terminal utilisateur, vous pouvez précéder les noms des binaires par un arobase '@' pour que la commande devienne "silencieuse". Exemple : @echo 'Compilation...'
[modifier] Syntaxe et expressions
Vous remarquerez que les lignes comportant des instructions shell doivent êtres précédées de tabulations. Le caractere d'échappement '\' permet de poursuivre l'instruction sur une ligne suivante si celle-ci se révèle trop longue. A l'instar du shell, les commentaires d'un Makefile correspondent aux lignes débutant par le caractere '#'. Enfin, vous pourrez utiliser certaines expressions rationnelles du shell, dont le caractère etoile. Ainsi, si main.c doit etre recompilé en cas de modification de l'un des headers du répertoire, on écrira la règle suivante :
main.c: *.h echo 'Recompilation de main.c' gcc main.c -o executable -Wall
[modifier] .PHONY
Détail pratique : il peut arriver que l'on passe en argument à make le nom des fichiers à compiler, comme par exemple make main.c, auquel cas la règle exécutée par défaut sera main.c. Néanmoins, cette fonctionnalité peut devenir un problème dès lors que l'on a un fichier portant le même nom que celui d'une cible de règle du Makefile, comme par exemple all ou encore clean. Pour éviter que le fichier all soit compilé au lieu d'exécuter la règle, il existe la directive .PHONY, qui rend prioritaire les règles sur les noms de fichiers. Celle-ci a deux avantages : elle évite tout conflit au niveau des noms de règles, et elle améliore les performances d'exécution. Elle s'utilise de la façon suivante : .PHONY: regle1 regle2. A titre d'exemple, imaginons la règle suivante permettant de supprimer les fichiers temporaires :
clean :
rm ./*.o
Elle fait souvent partie des pré-requis de la règle par défaut, car il peut être nécessaire de supprimer les fichiers temporaires avant toute recompilation. Problème : si un fichier clean est créé, et que sa date de mise-à-jour est récente, la règle clean sera considérée comme "à jour" par make et, de ce fait, ne sera pas appelée. Utiliser .PHONY évite le problème, au moment de l'exécution la règle clean sera exécutée au mépris des fichiers portant le même nom. Il est important de maîtriser cette directive. L'exemple est issu de la documentation officielle de GNU Make.
clean:
rm ./*.o
.PHONY: clean
[modifier] Variables
[modifier] Découverte et utilisation
Vous pourrez utiliser des variables dans vos Makefiles, et il est même conseillé d'en abuser. Les variables du Makefile doivent etre declarées en-dehors de toute règle, et par convention leurs noms se rédigent en majuscules. Elles sont en général placées en debut de fichier, avant la déclaration de la règle par defaut. Attention: lors de l'utilisation de vos variables, vous devrez employer le nom de la variable entre parenthèses prefixées du caractère '$'. Si le nom de la variable ne fait qu'un caractere, vous pouvez omettre les parenthèses, mais il est recommandé de toujours les utiliser car elles différencient les variables locales au Makefile des variables d'environnement du shell.
Les utilisations de variables sont diverses : la plupart du temps, elles servent d'alias sur les fonctions du système ou décrivent des ensembles de fichiers ou de flags de compilation. Utiliser des variables au lieu d'appels directs aux commandes shell est fréquent et utile : cela permet, par exemple, d'utiliser le même Makefile pour GNU/Linux et Win32, un script en tête de fichier associant aux variables la commande à utiliser. Ainsi, nous pouvons peaufiner le Makefile vu plus haut ainsi :
# Commandes CC = gcc ECHO = echo
# Fichiers HEADERS = *.h SRC = main.c EXE = executable
# Flags CFLAGS = -Wall LFLAGS = -lm
# Règles par défaut all: $(SRC) .PHONY: all
# Compilation des sources
$(SRC): $(HEADERS)
$(ECHO) 'Recompilation de $(SRC)'
$(CC) $(SRC) -o $(EXE) $(CFLAGS) $(LFLAGS)
Ici, utiliser des variables à un autre avantage : si l'on utilise plusieurs fichiers sources au projet, il suffit d'éditer la variable $(SRC) pour compiler tous les exécutables ; pour employer des fichiers objets il faudra utiliser quelques modifications que nous verrons par la suite.
[modifier] Opérateurs sur les variables
Il existe quatre opérateurs d'affectation pour les variables d'un Makefile. Le plus courrant, '=', effectue une affectation par référence, c'est-à-dire que si une variable est associée à une autre par cet opérateur, elle agira d'une manière similaire aux pointeurs du langage C. Dans le cas de constantes, il se contente d'affecter une valeur à une variable.
Vient ensuite l'opérateur ':=' : celui-ci effectue également une affectation de valeur, mais par copie, c'est-à-dire que si une variable est associée à une autre par cet opérateur sa valeur deviendra la valeur de l'autre variable, mais le fait de modifier la seconde n'entraînera aucune modification sur la première (à l'inverse de '='). Il est important d'utiliser de manière judicieuse ces deux opérateurs.
L'opérateur '?=' n'affecte de valeur à la variable que si elle n'a pas encore été initialisée. Il est assez rarement utilisé. Le dernier opérateur sert à concaténer les valeurs : il s'agit de '+='. Si on 'ajoute' une chaîne de caractères à une variable via cet opérateur, les caractères seront ajoutés en fin de chaîne. Afin de clarifier les choses, voici un exemple de Makefile employant les quatre opérateurs :
# Affectations A := test B := $(A) C ?= test
# Beware beware D := $(E) E := test
# Référence F = $(G) G = tes G += t
# Une fois déclarée, il faut # utiliser la syntaxe $() pour # modifier une variable : $(A) = test
# Règle par défaut
all:
echo $(A) - $(B) - $(C)\n
echo $(D) - $(E) - $(F) - $(G)
.PHONY: all
Le résultat de cet exemple affiche "test - test - test - - test - test - test". Tout d'abord, on affecte la valeur "test" à $(A), après quoi on affecte la valeur actuelle de $(A) à $(B), d'où $(A) = $(B) = "test". La ligne suivante ne pose pas de problème : on affecte la valeur "test" à $(C) si elle n'est pas initialisée ; comme c'est le cas, $(C) = "test". Attention à la suite : on affecte la valeur de $(E) à $(D), or, au moment de l'affectation $(E) vaut nul, et on affecte donc une valeur nulle à $(D). Enfin, la dernière portion de code illustre le mécanisme de références : on affecte à $(F) la variable $(G), c'est-à-dire qu'utiliser $(F) revient au même que d'utiliser $(G), et en toute logique modifier $(G) modifie également $(F).
[modifier] Procédures internes
Make dispose de ses propres procédures. Leur utilisation est similaire à celle des procédures shell, à savoir $(commande paramètre1, paramètre2...). On reconnaît là la même syntaxe que pour $(ls *.c) par exemple. A titre d'exemple, nous découvrirons quelques commandes usuelles.
[modifier] Exemple de procédure : wildcard
Dans l'exemple ci-dessus, le contenu de la variable $(HEADERS) est déterminé non pas à son initialisation mais au moment de l'appeler, c'est-à-dire que si un fichier header indésirable est inséré en plein milieu de la compilation, il sera compilé pour certains objets mais pas tous ; libre à vous d'imaginer la suite. Pour pallier ce problème, la commande wildcard force l'évaluation de la variable dès son initialisation. Par la suite, le contenu de $(HEADERS) ne sera pas réévalué à chaque appel, et si un fichier .h est ajouté il sera ignoré. Utiliser wilrdcard se fait simplement comme vu ci-dessus :
HEADERS = $(wildcard *.h)
[modifier] Commandes de substitution
Il peut être intéressant de substituer tout ou partie du nom d'un fichier, afin par exemple d'obtenir les adresses des fichiers objets à partir de celles des fichiers sources. Pour ce faire, il existe deux procédures dédiées, respectivement subst et patsubst. Elles nécessitent trois arguments : le premier est le texte ou modèle à remplacer, le second est le texte remplaçant et le troisième est la variable à traiter.
La première commande substitue une suite de caractères par une autre dans une chaîne, tandis que la seconde emploie des "paterns", soient des expressions rationnelles proches de celles du shell. Attention : celles-ci ne sont pas identique, la principale différence étant que le caractère étoile '*' est remplacé par le pourcent '%'. Ainsi, le Makefile suivant détermine le nom des objets à partir des fichiers sources :
SOURCES = $(wildcard *.c) OBJETS = $(patsubst %.c, %.o, $(SOURCES))
Ces deux fonctions sont fréquemment utilisées, par exemple pour générer les noms de fichiers n'existant pas encore au moment de l'appel à make. Si les procédures permettent d'effectuer des manipulations génériques sur de grands ensembles de fichiers, il en va de même pour certains types de règles que nous vous invitons à découvrir ci-dessous.
Note: il existe une syntaxe plus concise pour modifier l'extention d'un fichier ; pour ce faire, il faut utiliser la syntaxe VAR2 = $(VAR1:.ext1=.ext2), soit pour des fichiers objets OBJ = $(SRC:.c=.o). Cette syntaxe est strictement équivalente à l'utilisation de patsubst.
[modifier] Précisions sur les règles
[modifier] Cibles multiples
Il est possible de créer une règle définie pour plusieures cibles : cela est utile, par exemple, pour le cas où l'on effectue une même action sur chaque fichier d'un ensemble ayants les mêmes pré-requis, comme les sources d'un projet. Pour ce faire, il suffit de déclarer les cibles séparées par des espaces. Cette fonctionnalité constitue un premier pas vers la définition de règles génériques. L'exemple suivant illustre une règle à cibles multiple ; en utilisant des variables spécifiques à ce type de traitement nous pourrons créer une règle "générique".
CC = gcc -Wall
all: main.c code.c $(CC) main.o code.o -o exe .PHONY: all
main.c code.c: header.h $(CC) main.c -c $(CC) code.c -c
[modifier] Variables spécifiques
Au sein d'une règle, il existe des variables spécifiques aux paramètres de la règle en cours d'exécution. Celles-ci sont maintenues par make et très fréquemment utilisées. Nous les étudierons en même temps que les modèles de règles génériques afin qu'elles prennent tout leur sens.
| Variable | Rôle |
| $@ | La cible |
| $< | Le premier pre-requis |
| $? | Le nom de tous les pre-requis plus recents que la cible |
| $^ | Le nom de tous les pre-requis séparés par un espace |
[modifier] Modèles de règles
Lorsque l'on traite toujours un ensemble de fichiers d'une manière similaire, il devient intéressant de créer des règles plus génériques. Pour ce faire, on utilisera le caractère '%', équivalent à l'étoile des expressions rationnelles du shell. Un modèle de règle apparait sous la forme suivante :
cible : pré-requis à changer : pré-requis final
instructions
SRC = $(wildcard *.c) $(SRC) : %.o : %.c # Compilation
A noter que vous pouvez omettre la cible, auquel cas la règle pourra être utilisée pour générer n'importe quel pré-requis à changer à partir des pré-requis finaux. A noter que le nom du pré-requis final est généré à partir de la cible : si celle-ci n'est pas définie explicitement, au contraire de l'exemple ci-dessus, make pourra utiliser cette règle pour générer n'importe quel fichier .o à partir d'un fichier .c, la cible prenant alors la valeur du nom du fichier .o à générer.
Ainsi, en utilisant les variables $@ et $^, contenant respectivement le nom de la cible ainsi que tous les prérequis, on peut écrire une règle définissant la construction de n'importe quel fichier objet à partir de fichiers sources :
CC = gcc -Wall SRC = $(wildcard *.c) OBJ = $(SRC:.c=.o) EXE = executable
all: $(EXE) .PHONY: all
# Compilation d'objets %.o: %.c $(CC) -c $^ -o $@
# Compilation de l'exécutable $(EXE): $(OBJ) $(CC) $^ -o $@
Ce Makefile mérite explications. Tout d'abord, on définis l'outil de compilation, ainsi que les fichiers sources (tous ceux du répertoire). Les fichiers objets sont équivalents aux fichiers source dont on modifie l'extension (voir la section sur les Procédures de Substitution.) Ceci fait, on défini une règle par défaut, all, nécessitant la compilation de l'exécutable.
La règle suivant est générique : à partir de n'importe quel fichier .o, nécessitant son équivalent .c, on construit un fichier objet. La cible et son prérequis utilisent une expression rationnelle de Make, comprenant le caractère %. Ceci fait, on ajoute l'appel "générique" au compilation, soit "Compiler seulement" le fichier .c, pré-requis contenu dans la variable $^, vers un fichier .o, cible contenue dans la variable $@. Ainsi, pour chaque fichier objet pré-requis d'une règle, sa construction sera faite en utilisant cette règle de traitement "générique", à moins qu'une autre règle n'ait été définie spécialement pour ce fichier.
Par la suite, on déclare les fichiers objets comme pré-requis de la règle de construction de l'exécutable. Tous ces fichiers seront donc compilés en utilisant la règle générique définie plus haut. Ceci fait, il ne reste plus qu'à compiler tous les pré-requis (objets) en une seule cible : le binaire final. Nous venons donc de mettre au point un Makefile "générique" compilant n'importe quel projet relativement simple.
[modifier] Exécution conditionnelle
Il arrive que l'on ait besoin d'exécuter une commande plutôt qu'une autre, et ce en fonction du contexte d'exécution. L'exemple le plus fréquent est celui de la portabilité : on souhaiterait qu'un Makefile serve à la fois pour compiler sous GNU/Linux, Unix et Win32. Pour permettre ce type de construction, Make propose une palette d'instructions de test, proches des macros préprocesseur du C.
| Instruction | Teste |
| ifeq (arg1,arg2) | Egalité de arg1 et arg2 |
| ifneq (arg1,arg2) | Inégalité entree arg1 et arg2 |
| ifdef arg | Existence de arg |
| ifndef arg | Inexistence de arg |
A titre d'exemple, il peut être intéressant de rédiger un Makefile mettant en oeuvre ces différentes instructions, dans un but de "portabilité" entre systèmes. Le suivant ne sert qu'à titre d'exemple. A savoir au passage que la valeur d'une variable peut différer de celle définie dans le Makefile si l'utilisateur redéfinit celle-ci dans son appel à Make. Ainsi, make CC=g++ affectera la valeur 'g++' à la variable CC, au lieu de GCC. Pour le Makefile suivant, on considère que l'utilisateur définit la variable OS dans son appel à make (la commande `uname` retourne celui-ci sous Unix).
CC = gcc -Wall SRC = $(wildcard *.c) EXE = example OS = Linux
all: clean
echo 'Compilation pour $(OS)...'
ifeq ($(OS), Win32)
$(CC).exe $(SRC) -o $(EXE)
else
$(CC) $(SRC) linux.specific.c -o $(EXE)
endif .PHONY: all
clean: ifneq ($(OS), Win32)
del *.o
else
rm *.o
endif .PHONY: clean
[modifier] Utilisation de Makefiles externes
[modifier] Inclusion de Makefiles
Il est possible d'inclure d'autres Makefiles au sein d'un Makefile précis. Cela permet entre autres de répartir les définissions de règles entre différents fichiers. Une première méthode consiste à utiliser la directive include, qui ne doit être précédée d'aucune tabulation. Similaire au préprocesseur C, on peut considérer que le fichier inclu est "recopié" en clair en lieu et place de l'appel à include. Ce paramètre est à prendre en compte, par exemple, si le fichier inclu comporte la règle par défaut.
Note : il est également possible de modifier la variable $MAKEFILES, mais il s'agit d'une variable d'environnement shell, et il est donc fortement déconseillé de procéder ainsi.
[modifier] Makefile: =
- Règle par défaut
all: compile affiche
@echo 'Construction terminee.'
.PHONY: all
- Inclusion des règles
include Rules.mk
[modifier] Rules.mk
compile:
@echo 'Compilation en cours...'
affiche:
@echo 'Contenu du dossier :'
ls -laF
.PHONY: compile affiche
Les inclusions de fichier peuvent permettre de compartimenter le code du Makefile, ce qui peut également permettre de générer une partie du Makefile via un script comme les classiques configure, mais elles ont aussi leurs désavantages. Ainsi, si le fichier contenant une règle est supprimé alors que la règle est appelée dans le Makefile principal, une erreur d'exécution comme la suivante peut survenir :
make: *** Pas de règle pour fabriquer la cible `***', nécessaire pour `**'. Arrêt.
Il est possible de remédier à ce détail en ajoutant une règle générique à toutes les cibles, une sorte de "rammasse-miettes" (garbage collector) sous forme de règle de cible %: qui peut contenir un script de debug. L'absence d'une règle n'empêchera ainsi pas la poursuite de l'exécution, mais les instructions manquantes ne seront bien sûr pas effectuées. Le fait d'inclure des Makefiles, s'il permet de compartimenter le code, ne résout pas certains problèmes comme la construction de certains "sous-modules" d'unu projet, classés par répertoire. Pour remédier à ce point, il est possible d'appeler des Makefiles externes.
[modifier] Appel de Makefiles externes
Il existe diverses manières d'appeller des Makefiles externes, la plus simple étant de changer de dossier et d'appeler le dit Makefile en deux commandes shell. Au passage, nous utiliserons la variable $(MAKE) qui contient la commande make courrante.
all: afficher
(cd audio; $(MAKE))
(cd input; $(MAKE))
(cd video; $(MAKE))
afficher:
echo "Répertoire courrant `pwd`"
Dans cet exemple, on part du principe que les Makefiles des sous-répertoires sont identiques, si ce n'est le contenu de la règle par défaut. Ces Makefiles seront appelés les uns à la suite des autres, mais il est intéressant de noter l'utilisation de sous-processus pour appeler les Makefiles "fils", et ce à l'aide de parenthèses. Ce procédé permet d'obtenir des logs plus précis de la part de Make en cas d'erreur, toutes les opérations étant rapportées dans le terminal de l'utilisateur.
[modifier] Répertoires
Il est généralement préférable de trier les fichiers d'un projet dans une arboressence de dossiers. Afin de vous faciliter les choses, Make dispose de procédures et de variables permettant la recherche automatique de fichiers dans les répertoires concernés, ce qui vous autorise par exemple à nommer directement les fichiers voulus sans indiquer leur répertoire. Pour ce faire, vous pouvez utiliser la variable VPATH ou la procédure vpath (attention à la casse des caractères), plus précise.
[modifier] VPATH le grand
Cette variable contient les répertoires à parcourir en plus du dossier courrant ; c'est-à-dire qu'au momment de rechercher un fichier, par exemple main.o, si le fichier ne se trouve pas dans le dossier courrant make va le rechercher dans les dossiers contenus dans VPATH. Cette fonctionnalité est un début permettant de classer ses fichiers dans des répertoires, en fonction de leur type par exemple. Les répertoires ajoutés à VPATH peuvent être séparés par deux points ou par un espace. Ainsi, on peut imaginer "ranger" les fichiers objets compilés dans un répertoire distinct, ce qui est même conseillé :
CC = gcc -Wall EXE = test OBJDIR = ./objets VPATH = $(OBJDIR):./objets:./headers SRC = main.c OBJ = $(SRC:.c=.o)
all: $(OBJ) $(CC) main.o -o $(EXE) .PHONY: all $(OBJ) : %.o : %.c $(CC) $^ -o $(OBJDIR)
A noter que la recherche en répertoire, que ce soit pour VPATH ou vpath, est toujours effectuée dans le seul cas où un fichier n'est pas trouvé. Ainsi, le fait d'ajouter un répertoire sources/ à VPATH n'ajoutera pas les sources du répertoire au résultat d'une directive $(wildcard *.c). Par contre, si vous recherchez un fichier misc.c absent du répertoire courrant, il sera recherché dans sources/.
[modifier] vpath le petit
Un inconvénient de la variable VPATH est qu'elle s'applique à toutes les règles. Il est possible de limiter la recherche en répertoires à certaines cibles seulement, ce qui permet par exemple de ne parcourir les répertoires contenant des fichiers sources qu'en cas de construction d'un fichier objet. C'est le rôle de la directive vpath (en minuscules), qui prend en paramètres un modèle de fichier ainsi que les répertoires où rechercher.
CC = gcc
EXE = test
SRC = main.c
OBJ = $(SRC:.c=.o)
OBJDIR = ./objets
# Recherche en répertoires
vpath %.o $(OBJDIR)
vpath %.sh /usr/bin:./scripts
# Règle par défaut
all: $(OBJ)
$(CC) main.o -o $(EXE)
.PHONY: all
# Construire les objets
$(OBJ) : %.o : %.c
$(CC) $^ -o $(OBJDIR)
# Nettoyage
clean:
miseajour.sh
nettoyage.sh
.PHONY: clean
L'avantage de cette recherche est qu'elle est plus performante : dans la règle par défaut, seul le répertoire objets/ sera examiné pour rechercher main.o, et de même pour la règle 'clean' où seul le répertoire scripts/ sera examiné (on part du fait que les fichiers *.sh y sont). Sur un petit Makefile comme celui-ci, le gain de performances est minime, mais sur des Makefiles volumineux il peut devenir nécessaire.
À noter deux autres utilisations différentes de vpath : l'appeler sans spécifier de second argument supprime tous les répertoires stockés de la liste associée au premier, et l'appeler sans argument efface la totalité des répertoires stockés auparavant. Ces directives devraient vous permettre d'organiser vos projets en répertoires au fur et à mesure qu'ils prennent de l'ampleur.
[modifier] Conclusion
Cet article constitue une introduction aux fonctionnalités de GNU Make les plus utiles et les plus courrantes. Nous espérons qu'il vous a permis de vous initier à l'utilisation de cet excellent outil, mais pour de plus amples détails rien ne vaut la documentation officielle. Des liens intéressants sont mis à votre disposition en bas de page.
[modifier] Liens
- Doc officielle (GNU.org)
- GCC/G++/G77 Utilisation de base (tutorial prografix)
- Introduction à Make, par Alexandre Brillant
Ce document a été publié sur la version 3 du G.C.N. par Stéphane Caron, alias Naopic Tastalian.
- Auteur Original : Stéphane Caron, alias Naopic Tastalian
- Date de publication : 30 août 2004

