diff --git a/make/README.md b/make/README.md new file mode 100644 index 0000000..1564859 --- /dev/null +++ b/make/README.md @@ -0,0 +1,55 @@ +# Make - UNIX + +GNU Make est un héritier de `make`, mais sous Linux, c'est bien GNU Make qui est +installé. + +Make permet de gagner du temps par rapport aux shells: on n'exécute que ce qui +est nécessaire, en fonction des changements de source par rapport à leur cible. + +Un shell fait tous les traitements qui y sont indiqués. + +![Un shell fait tous les traitements qui y sont indiqués](../UnixShell_cours2018/Shell.gif) + +Un make ne fait que les traitements qui sont nécessaires. + +![Un make ne fait que les traitements qui sont nécessaires](../UnixShell_cours2018/Make.gif) + +## Syntaxe + +Le fichier `Makefile` contient les règles de dépendance. + +Une règle est de la forme : + +```make +cible: [fichier de départ] ... + commande +``` + +> ⚠ La commande doit être précédée d'une tabulation! + +Pour créer le fichier cible : `make cible` + +Exemple de fichier `Makefile` : + +```make +# Commentaire +compte.txt: aCompter.txt + wc -l < aCompter.txt > compte.txt +``` + +La deuxième fois qu'on lance la cible `compte.txt`, la commande `wc` n'est pas +exécutée, sauf si le fichier `aCompter.txt` a une date de modification plus +récente que celle de `compte.txt`. + +Une règle qui ne dépend d'aucun fichier de départ peut exister. +De plus, elle ne peut donner lieu à la création d'un fichier. +Une telle règle sera toujours exécutée (à condition que son nom ne soit pas +celui d'un fichier). + +## Références + +- Make Manual +- GNU Make +- Pour les spécialistes + +[Précédent](../sed/tp.md) - [Suivant](./tp.md) diff --git a/make/tp.md b/make/tp.md new file mode 100644 index 0000000..025ff53 --- /dev/null +++ b/make/tp.md @@ -0,0 +1,160 @@ +# Travaux pratiques - Make - UNIX + +Créer un fichier `Makefile` contenant une règle bonjour, qui affiche sur la sortie standard `Bonjour, comment ca va?` + +
+Voir la solution + +```make +bonjour: + @echo "Bonjour, comment ca va?" +``` + +> L'utilisation du `@` devant `echo` rend la commande "silencieuse", elle +> n'apparaît pas sur la sortie standard. + +
+ +--- + +Ajouter une règle `bye` qui affiche `A bientot!`. + +
+Voir la solution + +```make +bye: + @echo "A bientot!" +``` + +
+ +--- + +Créer une règle qui crée un fichier `modif.txt` dont le contenu vient du fichier +[`original.txt`](../UnixShell_cours2018/original.txt) (que vous pouvez +enregistrer grâce au bouton de droite) et qui remplace (grâce à `sed`) les +apparitions de `ILIB` par `DILIB`. + +
+Voir la solution + +```make +modif.txt: original.txt + sed -e 's/ILIB/DILIB/g' < original.txt > modif.txt +``` + +Le fichier `modif.txt` depend du contenu du fichier `original.txt`, c'est +pourquoi ce dernier apparaît à droite de `:`. + +
+ +--- + +Créer une règle qui crée un fichier `modif2.txt` à partir de `original.txt` et +[`table.txt`](../UnixShell_cours2018/table.txt), en utilisant la table fournie +pour modifier le fichier original. + +
+Voir la solution + +```make +modif2.txt: original.txt table.txt + sed -f table.txt < original.txt > modif2.txt +``` + +Le fichier `modif2.txt` dépend des contenus des fichiers `original.txt` et +`table.txt` (si l'un des deux est modifié, la commande `sed` sera exécutée). + +
+ +--- + +Ajouter une ligne à `table.txt` pour remplacer `CNRS` par `Centre National de la +Recherche Scientifique`. +Puis relancer `make modif2.txt` pour vérifier que la commande a bien été +exécutée. + +--- + +Ajouter une règle qui crée un fichier `compte.txt` contenant le nombre de lignes +du fichier `modif2.txt`. + +
+Voir la solution + +```make +compte.txt: modif2.txt + wc -l < modif2.txt > compte.txt +``` + +Le fichier `compte.txt` dépend du fichier `modif2.txt` (donc de sa règle, qui +dépend de `original.txt` et de `table.txt`). +Donc si on modifie `table.txt` et qu'on tape `make compte.txt`, ou toute autre +règle qui dépend directement ou indirectement de `table.txt`, cette règle sera +exécutée. + +
+ +--- + +Créer une règle `clean` qui supprime les fichiers dont le nom se termine par +`~`. + +
+Voir la solution + +```make +clean: + rm -f *~ +``` + +> Si vous utilisez un lecteur Samba (probable à l'INIST), vous risquez une +> désynchronisation entre les fichiers enregistrés par le lecteur Samba et la +> date de lancement de `make` (il est arrivé que les fichiers aient une à deux +> minutes d'avance). +> Pour limiter de tels problèmes, on peut utiliser la commande `touch`, qui +> remet un fichier à l'heure courante du shell, mais seulement sur les fichiers +> qui viennent d'être modifiés/créés! + +
+ +--- + +Créer une règle `all` qui dépende de `bonjour`, `compte.txt`, `clean`, et `bye`, +mais qui ne contient aucune commande (on peut quand même y mettre un `echo -- +Make all: exécuté --`). + +Remarques : + +- L'exécution d'une règle ne donne pas forcément lieu à l'exécution de sa + commande. + Dans le cas de la production d'un fichier, quand le fichier cible est plus + récent que le(s) fichier(s) dont il dépend, le fichier cible n'est pas recréé + (donc, la commande de sa règle n'est pas exécutée). +- Quand une règle dépend d'une autre règle qui dépend d'un autre fichier, et que + ce fichier est modifié (par exemple grâce à la commande `touch`, qui change la + date de modification du fichier qu'elle prend en paramètre), les commandes de + chacune de ces règles sont exécutées (voir le comportement de `make all` après + avoir tapé `touch original.txt`, ou après avoir ajouté du texte à + `original.txt`). + +
+Voir la solution + +```make +all: bonjour compte.txt clean bye + @echo --- Make all: exécuté --- +``` + +> On peut généraliser le `@echo --- Make exécuté ---` à toutes les +> règles, cela permet de mieux se rendre compte de ce que le `make` a effectué. + +
+ +--- + +Pour ceux qui ne l'ont pas fait : modifier le fichier `original.txt`, et +relancer la règle `all`. + +[Précédent](./README.md)