Les dép'

Petit rappel: les dépendances qui ne sont pas gérées dans makefile vont vous amener à de regrettables

$ make clean
$ make all

Tout ça pour un simple fichier d'entête modifié.

Il faut donc intégrer les dépendances dans votre makefile, à l'aide de rêgles telles que:

commun/main.o: commun/main.h
pour indiquer que le fichier source donnant main.o devra être recompilé à chaque changements dans main.h

Quand il y a beaucoup d'includes dans votre projet, ça devient vite pénible. Surtout quand on en rajoute, et qu'on oublie de les signaler dans le makefile.


makedepend

Pour pallier à cet inconvénient, il existe makedepend , qui comme son nom l'indique, génère les dépendances dans votre makefile.

makedepend fait partie du projet xorg , il y a d'ailleurs quelques dépendances avec les includes dudit projet.

Pour utiliser makedepend, il suffit de lui passer en paramètres les noms des fichiers sources à parser pour récupèrer les noms des includes.

Pour l'appeller depuis votre makefile, il faut écrire la rêgle classique :

deps:
        @makedepend *.cxx $(depends)


suivi d'un vigoureux make deps .
Problème: makedepend n'est pas forcément disponible avec tous les OS (pour MS-Windows et MSYS par exemple, il faut se le compiler).


gcc à la rescousse

Le grand ténébreux là, c'est gcc. Et il a plus d'une option dans son sac.

Parlons en des options.

gcc --help


Ca ne donne pas grand chose. Essayons ça:

gcc -v --help

Haha, on fait moins les malins !


Sans plus attendre, isolons les options utiles :

  • -M : Générer les dépendances pour make
  • -MD : Générer les dépendances pour make et compiler
  • -MF <file> : Ecrire les dépendances dans le fichier indiqué
  • -MG : Traiter les en-têtes manquantes de fichiers comme des fichiers générés
  • -MM : Identique à -M mais ignore les en-têtes de fichiers système
  • -MMD : Identique à -MD mais ignore les en-têtes de fichiers système


Utilisation pratique

Le gros avantage de l'utilisation directe de gcc par rapport à makedepend , c'est que les dépendances des includes systèmes ne seront plus générées avec un chemin dépendant de l'OS (inclusion des lettres de lecteur pour MS-Windows, etc..).

Une rêgle intéressante pour le makefile pourrait être:

deps:
        @$(CC) -MM *.cxx $(depends)

qui va ignorer les includes systèmes (vous y touchez souvent à vos includes systèmes ? Non ? J'en étais sûr).

Attention, la sortie de $(CC) -MM ne sera pas intégrée à la fin du makefile, comme lors de l'utilisation de makedepend. A vous de vous en charger avec une redirection dans un fichier temporaire.


Si on veut conserver les includes systèmes, il peut être plus judicieux de placer la sortie du parsing de gcc dans un fichier séparé, pour l'inclure soi même (plutot que de concaténer les rêgles à la fin du makefile).

Exemple de makefile:

deps:
        @$(CC) -M *.cxx $(depends) -MF mes_deps

(...)

-include mes_deps

Avec ce système, on peut tester l'OS dans le makefile afin de sélectionner le fichier de dépendances à utiliser.

note : si on traite plusieurs répertoires, il faut utiliser une redirection classique, plutot que le flag -MF qui va écraser les modifcations à chaque nouvelle série.

deps:
        @if [ -f mes_deps ]; then rm mes_deps; fi
        @$(CC) -MM commun/*.c* fltk/*.c* ogre/*.c* -DFLTK=1 -DOGRE=1 >>mes_deps

-include mes_deps


makedepend, ça ne sert à rien alors ?

Exactement :) .