Créer simplement des makefiles

 Herve.Frezza-Buet@supelec.fr


Préparation du tutorial

Pour réaliser ce tutoriel, nous allons manipuler des fichiers .hh (ou .h parfois) et .cc, qui sont des fichiers de code C++. Il n'est pas nécessaire d'en lire le contenu, on ne s'attachera qu'à la compilation (séparée donc) et son automatisation avec les makefiles. Téléchargez le fichier TutorialMakefile.tar.gz et le désarchiver :
tar zxvf TutorialMakefile.tar.gz 
rm TutorialMakefile.tar.gz
Vous vous retrouvez avec un répertoire TutorialMakefile. Descendez-y.
cd TutorialMakefile
ls

Compilation à la main

Allez dans la première partie.
cd Partie1
ls
On va faire de la compilation séparée à la main, ce qui est un brin fastidieux.
g++ -c -g -I. Main.cc
g++ -c -g -I. Bonjour.cc
g++ -c -g -I. Ciao.cc
La signification des options est la suivante :
g++ C'est le compilateur
-c Ne cherche pas à faire un exécutable, mais un exécutable partiel (un objet).
-g Laisse trainer dans le code de l'exécutable partiel de quoi lui appliquer un débuggeur.
-I<chemin> Ici, le chemin est ., d'où -I. Le chemin précisé est un endroit où se trouve des fichiers incluables par #include <...> (et non #include "..."). On peut mettre plusieurs fois -I<chemin> si on a des .hh dans différents répertoires.
<nom>.cc Le fichier à compiler. Il sera transformé automatiquement en .o (et non a.out).
Faire ensuite ...
 ls *.o
... pour vérifier que tout y est. Il existe sur le disque des fichiers .o prets à l'emploi, déjà compilés par d'autres personnes (/usr/lib/... /usr/local/lib/... et d'autres). C'est ce qu'on appelle des bibliothèques (bibliothèques pour les fonctions d'entrée sortie, pour le graphisme, etc...)

Le tout est maintenant de regrouper (linker) les .o et les éventuelles bibliothèques nécessitées par le programme, pour faire un vrai fichier exécutable (du genre a.out).
 g++ -o coup_de_vent Main.o Bonjour.o Ciao.o 
La signification des options est la suivante :
-o <nom> Appelle l'exécutable <nom> au lieu de l'arride a.out.
-L<chemin> Désigne un chemin ou se trouve des bibliothèques. C'est analogue au -I pour les fichiers .hh
-l<nom_bibliothèque> Désigne les bibliothèques à linker : exemple: pour ajouter libm.so qui contient les fonctions mathématiques définies dans 'math.h', on écrit -lm (et -lX pour libX.so).
Pour les bibliothèques usuelles, -L... est inutile. Dans cet exemple, c'est g++ qui se charge du linkage, mais il appelle en fait le linker ld. Quand il y a des problèmes au linkage, les messages sont donc du genre : ld: you have done n'importe quoi, play again

Lancer l'exécutable coup_de_vent pour passer... en coup de vent!
 ./coup_de_vent Robert

Mon premier makefile

Allez dans Partie2...
cd ../Partie2
ls
... on y trouve les mêmes fichiers, ainsi qu'un makefile bien commenté. Lire tout le makefile. Tapez
make 
(pour faire la première cible : coup_de_vent). Vérifiez que tout a marché (tous les .o et l'exécutable coup_de_vent). Tapez encore
make
... il ne refait que le linkage, tout n'est pas recompilé. Tapez
touch Bonjour.cc
pour faire comme si il venait d'être modifié (touch positionne la date du fichier à la date actuelle) Tapez
make
... pratique non ? Tapez
touch Bonjour.hh
make
... il ne se passe rien (que le linkage)... alors qu'il aurait été bon que si. En effet, en éditant Bonjour.cc et Main.cc, on constate que ces deux fichiers incluent (#include ...) Bonjour.hh. Il aurait fallu rajouter Bonjour.hh comme dépendance de Bonjour.cc, mais aussi de Main.cc !!!

La partie 3 porte sur la gestion automatique des dépendances liées à l'inclusion des .hh.
Faire
make clear
pour ne garder que les sources.

Gestion des dépendances induites par les fichiers inclus

Allez dans Partie3
cd ../Partie3
Lire le makefile. C'est presque le même, si ce n'est qu'on ajoute une cible 'depend'. Vous n'êtes pas obligé de comprendre finement le comportement de makedepend, retenez ceci : avec ce makefile, il faut taper
make depend
pour activer une cible qui appelle le programme makedepend. Par curiosité, regardez le contenu du fichier 'makefile_depend',
less makefile_depend
Il contient des cibles crées automatiquement par makedepend pour gérer les dépendances entre les sources .cc et les .hh qu'elles incluent. Tapez
make
touch Bonjour.hh
make
... les fichiers Main.o et Bonjour.o sont bien recompilés !!!

Conclusion

Le makefile de la partie 3 peut vous servir de base pour faire des copier-coller pour vos propres compilations. On peut encore automatiser des choses, mais ca devient plus complexe. Cette version minimale est un bon compromis.