Livre de chevet du développeur FreeBSD
Précédent | Chapitre 5. Outils de programmation | Suivant

# 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.o ... fichier37.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 `Makefile`s 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. [1]

## 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 `Makefile`s 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 `Makefile`s 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 `Makefiles`de FreeBSD

Les `Makefile`s 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 [2].

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 `Makefile`s 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 `Makefile`s 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`).

### Notes

[1] | Ils n'utilisent pas la forme `MAKEFILE` car les bloques de majuscules sont souvent utilisés pour les fichiers de documentation comme `README`.
[2] | NDT: On entendra plus souvent parler de `patch`.

Précédent | Sommaire | Suivant
Compiler avec `cc` | Niveau supérieur | Déverminer

Ce document, ainsi que d'autres peut être téléchargé sur 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>.