5.5. Make

5.5.1. Qu'est-ce que make?

Quand vous travaillez sur un programme simple avec seulement un ou deux fichiers source, taper

% cc fichier1.c fichier2.c
      

n'est pas si mal, mais cela devient rapidement fastidieux quand il y a plusieurs fichiers—et cela peut prendre du temps à compiler aussi.

Une façon de contourner cela est d'utiliser les fichiers objet et de recompiler le fichier source seulement si le code source a changé. Aussi, nous pourrions avoir quelque chose comme ça:

% cc fichier1.o fichier2.ofichier37.c

si nous avions changé le fichier fichier37.c mais aucun des autres depuis la dernère compilation. Cela pourrait accélerer assez bien la compilation mais cela ne resoud pas le problème de la frappe au clavier.

Ou nous pourrions écrire une procédure pour résoudre ce problème de frappe, mais celle-ci devrait tout re-compiler, devenant ainsi inefficace sur un gros projet.

Que se passe-t-il si nous avons des centaines de fichiers source ? Que se passe-t-il si nous travaillons dans une équipe avec d'autres personnes qui oublient de nous dire quand ils ont changé un de leurs fichiers source que nous utilisons ?

Peut-être pourrions nous mettre ensemble les deux solutions et écrire quelque chose comme une procédure qui contiendrait quelque règle magique disant quand notre fichier source doit être compilé. Maintenant, tout ce dont nous avons besoin est un programme qui comprend ces règles, alors que c'est trop compliqué pour l'interpréteur.

Ce programme s'appelle make. Il lit dans un fichier, appelé un makefile, qui lui dit comment les différents fichiers dépendent les uns des autres, et détermine quels fichiers ont besoin d'être recompilés et quels n'en ont pas besoin. Par exemple, une règle pourrait dire quelque chose comme « si fromboz.o est plus ancien que fromboz.c, cela signifie que quelqu'un a dû changer fromboz.c, aussi il a besoin d'être recompilé. » Le makefile possède aussi des règles pour dire à make comment re-compiler un fichier source, en faisant ainsi un outil encore plus puissant.

Les Makefiles sont typiquement stockés dans le même répertoire que le source auxquels il s'appliquent, et peuvent être appelés makefile, Makefile ou MAKEFILE. La plupart des programmeurs utilise le nom Makefile, celui-ci se trouvant proche du début de la liste du contenu du répertoire où il peut être facilement vu. [7]

5.5.2. Exemple d'utilisation de make

Voici un exemple très simple de Makefile:

foo: foo.c
	cc -o foo foo.c

Il consiste en deux lignes, une ligne de dépendance et une ligne de création.

La ligne de dépendance ici consiste en le nom du programme (connu comme cible), suivi de deux-points puis un espace et enfin le nom du fichier source. Quand make lit cette ligne, il vérifie si foo existe; s'il existe, il compare la date à laquelle foo a été modifié la dernière fois avec la date de dernière modification de foo.c. Si foo n'existe pas ou est plus ancien que foo.c, il regarde la ligne de création pour trouver ce qu'il doit faire. En d'autres termes, il s'agit de la règle à utiliser quand foo.c a besoin d'être re-compilé.

La ligne de création commence avec un tab (appuyez sur la touche tab) suivi de la commande que vous taperiez pour créer foo si vous deviez le faire à l'invite de commandes. Si foo n'est pas à jour ou n'existe pas, make exécute alors cette commande pour le créer. En d'autres termes, il s'agit de la règle permettant à make de re-compiler foo.c.

Aussi, quand vous tapez make, il vérifiera que foo est à jour en respect de vos derniers changements sur foo.c. Ce principe peut être étendu à des Makefiles de plusieurs centaines de cibles—en fait, sur FreeBSD, il est possible de compiler un système d'exploitation entier en tapant juste make world dans le répertoire approprié !

Une autre propriété utile des makefiles est que les cibles n'ont pas nécessairement besoin d'être des programmes. Par exemple, nous pourrions avoir un Makefile qui ressemble à cela:

foo: foo.c
	cc -o foo foo.c

install:
	cp foo /home/moi

Nous pouvons dire à make quelle cible nous voulons en tapant:

% make cible
      

make ira seulement voir cette cible et ingorera les autres. Par exemple, si nous tapons make foo avec le Makefile du dessus, make ignorera la cible install.

Si nous tapons juste make, make regardera toujours la première cible et s'arrêtera sans regarder aucune autre. Aussi, si nous avions tapé make seul, make serait juste allé à la cible foo, aurait recompilé foo si nécessaire et se serait arrêté sans aller à la cible install.

Notez que la cible install ne dépend pour l'instant de rien ! Cela signifie que la commande qui suit est toujours exécutée lorsque nous essayons de créer cette cible en tapant make install. Dans ce cas, make va copier foo dans le répertoire de l'utilisateur. Cela est souvent utilisé par les Makefiles des applications, ainsi l'application peut être installée dans le répertoire correct quand elle a été correctement compilée

Il s'agit d'un sujet légèrement embrouillant à essayer et expliquer. Si vous ne comprenez pas bien comment make fonctionne, la meilleure chose à faire est d'écrire un petit programme comme « bonjour monde » et un fichier Makefile comme le précédent et de le tester. Ensuite continuez en utilisant plus d'un fichier source ou en ayant un fichier source incluant un fichier d'en-tête. La commande touch est très utile ici—elle change la date sur un fichier sans avoir à l'éditer.

5.5.3. Les Makefilesde FreeBSD

Les Makefiles peuvent être plutôt compliqués à écrire. Heureusement, les systèmes BSD comme FreeBSD sont fournis avec des fichiers très puissants comme partie intégrante du système. Un très bon exemple est le système des logiciels portés. Voici la partie essentielle d'un Makefile typique des logiciels portés:

MASTER_SITES=   ftp://freefall.cdrom.com/pub/FreeBSD/LOCAL_PORTS/
DISTFILES=      scheme-microcode+dist-7.3-freebsd.tgz

.include <bsd.port.mk>

Maintenant, si nous allons dans le répertoire de ce logiciel porté et tapons make, la chose suivante se passe :

  1. Une vérification est faite pour voir si le code source de ce logiciel porté est déjà dans le système.

  2. Si celui-ci n'y est pas, une connexion FTP à l'URL dans MASTER_SITES est faite pour télécharger le source.

  3. La somme de contrôle (checksum) du source est calculée et comparée avec celle d'une bonne et connue copie du source. Cela est fait pour être sûr que le source n'a pas été corrompu pendant le transfert.

  4. Tout changement requis pour faire fonctionner le source sur FreeBSD est appliqué— cela est connu sous le nom de correctif[8].

  5. Toute configuration spéciale nécessaire pour le source est faite. (Beaucoup de distributions de programmes Unix essaye de fonctionner quelle que soit la version d'Unix sur laquelle elles sont compilées et quelles que soient les caractéristiques optionnelles qui sont présentes—c'est ce qui se trouve dans le scénario des logiciels portés pour FreeBSD).

  6. Le code source pour ce programme est compilé. En effet, nous changeons de répertoire pour le répertoire où le source a été décompressé et faisons make—le fichier Makefile du programme contient les informations nécessaires pour construire le programme.

  7. Nous avons maintenant une version compilée du programme. Si nous le désirons, nous pouvons le tester maintenant; quand nous sommes confiant dans le programme, nous pouvons taper make install. Cela va installer le programme et ses fichiers de soutien nécessaires au bon endroit; une entrée est aussi créée dans la base de données des logiciels pré-compilés, ainsi le logiciel porté peut être facilement désinstallé plus tard si nous changeons d'avis sur ce programme.

Maintenant je pense que vous serez d'accord que c'est plus impressionnant qu'une procédure de quatre lignes !

Le secret réside dans la dernière ligne qui dit à make de regarder dans le Makefile système appelé bsd.port.mk. Il est facile de fermer les yeux sur cette ligne mais c'est ici que tous les trucs forts se passent—quelqu'un a écrit un Makefile qui dit à make de faire tout ce qu'il y a au-dessus (plus un couple d'autres choses que je n'ai pas mentionnées, comme la gestion des erreurs) et n'importe qui peut avoir accès à cela simplement est ajoutant une simple ligne dans son propre fichier Makefile !

Si vous voulez jeter un regard sur ces Makefiles système, ils se trouvent /usr/share/mk mais il est probablement mieux d'attendre un moment jusqu'à ce que vous ayez un peu d'entrainement avec les Makefiles car ceux-ci sont très compliqués (et si vous les lisez, soyez sûr d'avoir un thermos de café fort à portée de main !)

5.5.4. Utilisations plus avancées de make

Make est un outil très puissant et peut faire beaucoup plus que le simple exemple précédent ne l'a montré. Malheureusement, il y a différentes versions de make et elles diffèrent considérablement. Le meilleur moyen d'apprendre ce qu'elles peuvent faire est probablement de lire la documentation—heureusement cette introduction vous donnera la base à partir de laquelle vous pourrez faire cela.

La version de make fournies avec FreeBSD est le Berkeley make(make de Berkeley); il y a un cours d'instruction pour celui-ci dans /usr/share/doc/psd/12.make. Pour le voir, faites

% zmore paper.ascii.gz
      

dans ce répertoire.

Beaucoup d'applications dans les logiciels portés utilisent GNU make, qui possède un très bon ensemble de page d'« info ». Si vous avez installé un de ces logiciels portés, GNU make aura été automatiquement installé sous le nom de gmake. Il est aussi disponible comme logiciel porté ou logiciel pré-compilé seul.

Pour voir les pages d'info pour GNU make, vous devrez editer le fichier dir dans le répertoire /usr/local/info pour ajouter une entrée pour celui-ci. Cela implique d'ajouter une ligne

 * Make: (make).                 l'utilitaire GNU Make.

au fichier. Une fois que vous avez fait ceci, vous pouvez taper info et ensuite sélectionner make dans le menu (ou dans Emacs, faites C-h i).



[7] Ils n'utilisent pas la forme MAKEFILE car les bloques de majuscules sont souvent utilisés pour les fichiers de documentation comme README.

[8] NDT: On entendra plus souvent parler de patch.

Ce document, ainsi que d'autres peut être téléchargé sur ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/

Pour toutes questions à propos de FreeBSD, lisez la documentation avant de contacter <questions@FreeBSD.org>.

Pour les questions sur cette documentation, contactez <doc@FreeBSD.org>.