GNU Make
GNU make est la variante GNU du moteur de production make. Gmake est le fruit de la collaboration entre Richard Stallman et Roland McGrath.
Créateur | Richard Stallman et Roland McGrath (d) |
---|---|
Développé par | Projet GNU |
Première version | |
Dernière version | 4.4.1 ()[1] |
Dépôt | git.savannah.gnu.org/cgit/make.git |
Écrit en | C |
Système d'exploitation | GNU/Linux, BSD, macOS et Microsoft Windows |
Environnement | GNU/Linux |
Type | Moteur de production |
Licence | GPLv3 |
Site web | www.gnu.org/s/make/ |
Spécificités
modifierCertaines des spécificités citées ci-après peuvent ne pas être strictement propres à GNU make dans la mesure où elles peuvent avoir été héritées d'autre variantes ou encore imitées par d'autres variantes mais également avoir été inventées indépendamment de part et d'autre.
Il n'est pas ici question de se substituer au (en)manuel utilisateur mais de mettre en évidence les éléments les plus remarquables.
Valeur des variables
modifierAlors que la valeur d'une variable est traditionnellement traitée comme une macro de manière récursive au moment de son utilisation, GNU make permet la définition de variables dont la valeur est fixée au moment de leur définition.
Exemple traditionnel :
titi = $(tata) tata = $(toto) toto = salut all:;echo $(titi)
affichera "salut" après que titi aura été évalué en tata à son tour évalué en toto finalement évalué en salut[2].
Cette première saveur est la seule connue des autres variantes de make. Celle-ci a des avantages, elle permet en particulier que la valeur finale effective ne puisse être déterminée qu'en dernière instance. Elle offre également une certaine souplesse dans l'ordre des déclarations, ainsi dans l'exemple ci-dessus, le résultat est indépendant de l'ordre des trois premières déclarations.
Cette première saveur a par contre deux désavantages. Le moindre est que les variables sont systématiquement réévaluées à chacune de leur utilisation (même quand leur valeur reste constante) ce qui constitue une charge inutile dans ce cas précis. L'autre est que, dans le cas général, elle ne permet pas que sa redéfinition puisse se faire comme dans l'exemple ci-après[3] :
titi = jour toto = bon titi = $(toto)${titi}
Dans ce cas, la troisième ligne conduit à une définition récursive de titi qui sera rejetée comme erreur par GNU make.
La seconde saveur possible avec GNU make est illustrée par l'exemple ci-après[3] :
x := titi y := $(x) tata x := toto
est équivalent à :
y := titi tata x := toto
En d'autres termes, cette seconde saveur confère aux variables ainsi définies un comportement identique à celui des variables de la plupart des autres langages de programmation tel que le Langage C par exemple.
Règles génériques
modifierMake permet de définir des règles explicites et implicites ou génériques[4].
- Dans une règle explicite les fichiers sources et cibles sont explicitement nommés soit sous directement forme littérale constante soit indirectement par l'intermédiaire de variables ou encore, dans le cas de GNU make par des appels de fonctions.
- Dans une règle implicite, source et cibles sont décrites par des expressions régulières simplifiées. Quand, à défaut d'être décrite par une règle explicite, le nom d'une cible et de sa source potentielle sont conformes aux expressions régulières d'une règle générique, alors cette dernière peut s'appliquer.
Dans la plupart des variantes de make de telles expressions se réduisent à des simples couples de suffixes. Quand pour un nom de fichier cible il existe fichier source de même racine et qu'il existe un règle implicite liant le suffixe de la cible à celui du source alors la règle peut s'appliquer. Exemple :
.c.o: $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
Décrit comment de manière implicite tout fichier de suffixe ".o" peut être produit à partir du fichier de suffixe ".c"
GNU make permet des expressions régulières un peu plus complexe et dont la syntaxe est analogue à celle des règles explicites. Exemple :
%.o: %.c toto.h $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
On remarquera dans cet exemple que la règle génériques ainsi définie ne se limite pas à lier les suffixes ".o" et ".c" mais permet en outre d'imposer ou spécifier (selon le point de vue) une dépendance supplémentaire à un fichier particulier : "toto.h" (dans l'exemple). Dans cette syntaxe c'est le caractère "%" qui localise le motif (ou encore pattern) commun entre source et cible.
Cette syntaxe permet de ne pas se limiter au seul suffixe. Ainsi dans l'exemple :
f%.o: g%.c $(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
on impose par ailleurs que la règle générique ne s'appliquera qu'à des cible de suffixe ".o" dont le nom de fichier commence par "f" et pour un source de suffixe ".c" dont le nom de fichier commence par "g" et partageant le même motif "%". Ainsi seront concernée par la règle générique définie plus haut les couples :
fifi.o gifi.c foto.o goto.c
mais pas les couples :
fifi.o fifi.c goto.o goto.c
Fonctions
modifierGNU make offre un jeu étendu de fonctions pouvant être utilisées en toute place où on pourrait trouver une référence de variable. La syntaxe d'appel à une fonction, très similaire à celle d'une référence de variable, est de la forme générale :
${fonction arguments}
Parmi les fonctions disponibles on peut identifier les catégories suivantes :
- fonctions généralistes de traitement de chaînes de caractères : substitutions, extractions, recherches, filtrages, tris, etc.
- fonctions dédiées à la manipulation des noms de fichiers : extractions du nom de base, du suffixe, du chemin, exploitation d'expressions régulières de type "shell", de construction, de normalisation des noms(forme canonique), etc.
- fonction permettant de construire des expressions conditionnelles simples (si, ou, et) dans le contexte de l'utilisation des fonctions[5].
- la fonction $(foreach nom, liste, texte) qui permet de construire des listes en répétant texte pour chaque mot présent dans liste en substituant celui-ci dans chaque occurrence de référence à nom présent dans texte.
- la fonction $(call variable, param, param, ...) qui permet d'invoquer n'importe quelle fonction construite par l'utilisateur (voir plus loin) et dont la définition est donnée par variable.
- la fonction $(shell texte) qui permet d'exécuter une fonction en dehors de l'environnement d'accueil (commandes disponibles dans l'environnement d'accueil) et usuellement utilisé pour affecter à une variable une information sur l'environnement extérieur à make (récupérer une date, le nom de la machine, de l'utilisateur, etc.).
- diverses fonctions permettant de connaître l'état (définie ou non), l'origine de sa définition (dans le makefile, la ligne de commande, une variable d'environnement, etc.), la saveur, la portée de toute chaîne de caractères susceptible d'identifier une variable.
- des fonctions permettant de contrôler l'exécution en levant des erreurs, des avertissements ou simplement en affichant des messages.
GNU make permet également à l'utilisateur de définir ses propres fonctions en factorisant via la définition d'une variable (le nom de la fonction) dont la valeur est combinaison d'autres fonctions et variables (formelles ou réelles).
GNU Guile
modifierLe support de Guile est assuré depuis la version 4.0[6]. La première brique logicielle à l’exploiter sera probablement Guix, un gestionnaire de paquets purement fonctionnel conçu pour GNU.
Notes et références
modifier- « GNU Make 4.4.1 released! »
- salut n'étant pas lui-même défini comme une variable il est traité comme une chaîne de caractères constante
- Il s'agit bien sûr ici juste d'un cas d'école
- Les règles implicites sont juste des règles génériques prédéfinies
- À ne pas confondre avec le code conditionnel qui permet d'exclure ou inclure de manière conditionnelle la prise en compte de certaines parties du makefile
- (en) « GNU Make 4.0 Brings New Features, Extends With Guile », sur phoronix.com, (consulté le ) ;