make est un outil qui permet de déterminer quelles parties d'un programme nécessitent une recompilation et de lancer les commandes nécessaires pour les recompiler. C'est un outil qui est très utilisé dans le cas de programmes C, mais que l'on peut utiliser pour des cas beaucoup plus proches du développement web. Il a aussi l'avantage d'être largement disponible sur les systèmes ce qui permet de ne pas avoir à installer une dépendance supplémentaire juste pour utiliser make.
Makefile
Afin d'utiliser make il faut commencer par créer un fichier Makefile qui va permettre de décrire la relation entre les fichiers du programme et les commandes à éxécuter pour les obtenir. La syntaxe d'un Makefile est très simple :
Attention ! les commandes doivent être précédée d'une tabulation (pas de 2 ou 4 espaces, une vraie tabulation). Dans le cas d'un projet C on peut ainsi indiquer comment compiler les fichiers à partir de leur dépendances
Ainsi pour générer le fichier main.o, make sait qu'il doit regarder le fichier main.c et defs.h. Si le fichier main.o est plus récent que les 2 prérequis alors aucune opération ne sera effectuée, sinon il éxécutera la commande cc -c main.c.
Mais je fais du web pas du C !
Dans le cas d'un gros projet C on peut comprendre que make permet d'économiser du temps en évitant de devoir tout recompiler en permanence. Mais du coup, comment make peut être utilé dans le cadre d'un projet web ?
Il peut par exemple servir à décrire la phase d'installation des différentes dépendances. Par exemple dans le cadre d'un projet PHP :
On indique ici plusieurs choses :
- Si le fichier
composer.jsonest plus récent que le fichiercomposer.lockon met à jour les dépendances via la commandecomposer update. - Si le fichier
composer.lockest plus récent que le dossiervendoralors on installe les dépendances. - On crée une "fausse" cible (déclarée dans le .PHONY) qui permet de lancer l'installation via un simple
make install
L'utilisation de la cible ".PHONY" permet d'utiliser make comme un simple système d'alias :
On remarque ici que notre cible install est utilisée en prérequis de la cible test. Ainsi, si on lance la commande make test sans avoir préinstallé les dépendances, make le détectera et commancera par éxécuter les cibles nécessaires.
Les variables
On peut pousser les choses un peu plus loin en utilisant des variables. Il est par exemple possible de spécifier l'éxécutable à utiliser dans une variable.
On peut ainsi facilement redéfinir la variable en amont et lancer les tests unitaires avec différentes versions :
On choisit ici de lancer nos tests gràce à docker, ce qui nous permet de facilement utiliser plusieurs versions d'un même outil :
Pour en apprendre plus sur l'utilisation des variables n'hésitez pas à faire un tour sur le manuel.
Pattern Rule
Il est aussi possible de définir des motifs de règles gràce au symbole % :
Dès qu'une autre règle aura besoin d'une image située dans le dossier optimized, make sera en mesure de comprendre comment la construire. Combiné avec l'utilisation de variables et de fonctions il est possible de créer des tâches plus complexes :
Si on tape make images le système va automatiquement optimiser les nouvelles images et les placer dans le dossier optimized. Il est aussi possible, gràce au drapeau -j de paralléliser les tâches.
Cette parallélisation peut aussi être utilisée pour démarrer plusieurs tâches en même temps. Par exemple pour lancer le serveur web interne de PHP et browser-sync pour actualiser automatiquement la page.
La commande make -j2 watch permettra donc de lancer les cibles server et browsersync en parallèle.