Les outils de développement sous FreeBSD : Guide de l'utilisateur
Précédent |  | Suivant

# 4. Make

## 4.1. Qu'est-ce que `make`?

Lorsque vous travaillez sur un programme simple avec seulement un ou deux fichiers de source, taper:

    % cc fichier1.c fichier2.c

n'est pas trop gênant, mais cela devient rapidement très fastidieux lorsqu'il y a plusieurs fichiers - et cela peut aussi mettre du temps à compiler.

Un façon d'éviter ces problèmes est d'utiliser des fichiers objets et de ne recompiler que les fichiers de source dont le contenu a changé. Nous pourrions alors avoir quelque chose du style:

    % cc fichier1.o fichier2.o ... file37.c ...

si nous avons modifé `fichier37.c`, et celui-là uniquement, depuis notre compilation précédente. Cela peut sérieusement accélérer la compilation, mais ne résout pas le problème de saisie à répétition de la commande.

Nous pourrions aussi écrire une procédure pour résoudre ce dernier problème, mais ne ne pourrions alors que lui faire tout recompiler, ce qui serait très peu efficace sur un gros projet.

Que ce passe-t-il si nous avons des centaines de fichiers de sources? Si nous travaillons en équipe et que d'autres oublient de nous prévenir des modifications qu'ils ont apportées à un des fichiers que nous utilisons?

Peut-être pourrions-nous rassembler les deux solutions et écrire quelque chose qui ressemble à une procédure et comporte une sorte de règle magique qui dise quand tel fichier de source doit être compilé. Nous n'aurions plus besoin que d'un programme qui comprennent ces règles, parce que c'est un peu trop compliqué pour une procédure.

Ce programme s'appelle `make`. Il lit un fichier, qu'on appelle un makefile, qui lui dit quelles sont les dépendances entre les différents fichiers, et en déduit lesquels ont besoin ou non d'être recompilés. Par exemple, une règle peut signifier quelque chose comme ``si `fromboz.o` est plus ancien que `fromboz.c`, cela veut dire que `fromboz.c` doit avoir été modifié, il faut donc le recompiler''. Le fichier ``makefile'' inclut aussi des règles qui lui disent comment recompiler, ce qui en fait un outil encore plus puissant.

Ces fichiers ``makefiles'' sont habituellement rangés dans le même répertoire que les sources auxquels ils s'appliquent, et peuvent être appelés `makefile`, `Makefile` ou `MAKEFILE`. La plupart des programmeurs utilisent le nom `Makefile`, ce qui fait qu'ils se trouvent alors vers le début de la liste des fichiers et sont ainsi facilement repérables [1].

## 4.2. Exemple d'utilisation de `make`

Voici un fichier `Makefile` élémentaire :

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

Il contient deux lignes, une pour la dépendance et une pour la génération.

La ligne décrivant la dépendance contient le nom du programme (qu'on appelle la cible), suivi de ``deux points'', puis d'un blanc et du nom du fichier source. Quand `make` lit cette ligne, il regarde si `foo` existe; s'il existe, il compare la date de dernière modification de `foo` à celle de dernière modification de `foo.c`. Si `foo` n'existe pas, ou s'il est antérieur à `foo.c`, il regarde alors la ligne de génération pour savoir ce qu'il faut faire. En d'autres termes, c'est la règle à appliquer pour savoir si `foo.c` doit être recompilé.

La ligne de génération commence par une tabulation (appuyez sur la touche Tab) suivie de la commande que vous taperiez pour compiler `foo` si vous le faisiez sur la ligne de commande. Si `foo` n'est pas à jour ou s'il n'existe pas, `make` exécute alors cette commande pour le créer. En d'autres termes, c'est la règle qui dit à `make` comment recompiler `foo.c`.

Ainsi, quand vous tapez `make`, il fera en sorte que `foo` soit en phase avec les dernières modifications que vous avez apportées à `foo.c`. Ce principe s'étend aux `Makefile`s avec des centaines de cibles - de fait, sur FreeBSD, il est possible de compiler tout le système d'exploitation en tapant simplement `make world` dans le répertoire adéquat!

Une autre particularité de `Makefile`s est que les cibles ne sont pas nécessairement des programmes. Nous pourrions par exemple avoir le `Makefile` suivant:

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

    install:
          cp foo /home/me

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

    % make cible

`make` examinera alors cette cible et ignorera toutes les autres. Par exemple, si, avec le `Makefile` précédent, nous tapons `make foo`, `make` ignorera la cible install.

Si nous tapons simplement `make` tout court, il examinera toujours la première cible et s'arrêtera ensuite sans s'occuper des autres. Si nous avions tapé `make` dans ce cas, il serait simplement allé à la cible foo, aurait recompilé `foo` si nécessaire, et se serait arrêté sans passer à la cible install.

Remarquez que la cible install ne dépend en fait de rien du tout! Cela signifie que la commande sur la ligne suivante est toujours exécutée si nous essayons de reconstruire cette cible en tapant `make install`. Dans ce cas, il copiera `foo` dans le répertoire de l'utilisateur. C'est souvent utilisé par les `Makefile`s de logiciels, de sorte que l'application soit installée dans le bon répertoire, une fois correctement compilée.

C'est un point un peu délicat à expliquer. Si vous ne comprenez pas exactement comment `make` fonctionne, la meilleure chose à faire est d'écrire un programme simple comme le classique ``Bonjour, le monde!'', un fichier `Makefile` et de faire des essais. Compilez ensuite en utilisant plus d'un fichier source, ou en ayant un fichier source qui inclut un fichier d'en-tête. La commande `touch` vous sera très utile - elle modifie la date d'un fichier sans que vous ayez à l'éditer.

## 4.3. Makefiles FreeBSD

L'écriture de `Makefile`s peut être assez compliquée. Heureusement, les systèmes basés sur BSD, comme FreeBSD, en fournissent de très puissants, intégrés au système. Le catalogue des logiciels portés de FreeBSD en est un excellent exemple. Voici l'essentiel d'un de leurs `Makefile`s typiques:

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

    .include <bsd.port.mk>

Si nous allons maintenant dans le répertoire associé à ce logiciel et tapons `make`, voici ce qui se passe:

1. Il regarde si le code source de ce logiciel est déjà présent sur le système.

2. S'il n'y est pas, une connexion FTP à l'URL indiquée par `MASTER_SITES` est établie pour télécharger le source.

3. La somme de contrôle est calculée sur le source et comparée à celle calculée sur une version connue et validée. Cela pour s'assurer que le source n'a pas été corrompu pendant le transfert.

4. Les modifications nécessaires pour que le code fonctionne sous FreeBSD sont appliquées - c'est ce que l'on appelle patcher.

5. Les opérations particulières de configuration du source sont effectuées. (De nombreuses distributions de programmes Unix essayent de déterminer sur quel système elles sont compilées et de quelles fonctionnalités Unix optionnelles il dispose - c'est à ce stade du scénario d'installation de logiciels sous FreeBSD que leur sont fournies ces informations).

6. Le code source du programme est compilé. De fait, on passe dans le répertoire où le code a été décompacté et `make` y est exécuté - le `Makefile` du programme lui-même contient les informations nécessaires à sa compilation.

7. Nous disposons maintenant d'une version compilée du programme. Si nous le voulons, nous pouvons maintenant la tester; si nous avons confiance dans le programme, nous pouvons taper `make install`. Cela recopiera le programme et tous les fichiers d'environnement dont il a besoin à l'endroit adéquat; une entrée sera aussi créée dans une base de données des logiciels, de façon à ce qu'il puisse être désinstallé par la suite, si nous changeons d'avis.

Je pense que vous serez maintenant d'accord pour trouver que c'est assez impressionnant pour une simple procédure de quatre lignes!

Le secret se trouve à la dernière ligne, qui dit à `make` d'aller voir ce qu'il y a dans le `Makefile` appelé `bsd.port.mk`. Il est facile de rater cette ligne, mais c'est pourtant de là que vient toute la mécanique subtile. Quelqu'un a écrit un `Makefile` qui dit à `make` de faire tout ce qui a été décrit ci-dessus (plus deux ou trois autres choses dont je n'ai pas parlé, dont le traitement des erreurs qui pourraient se produire) et tout le monde peut l'utiliser en mettant simplement cette unique ligne dans son propre `Makefile`!

Si vous voulez jeter un oeil à ces `Makefile`s systèmes, ils sont dans le répertoire `/usr/share/mk`, mais il vaut mieux attendre d'avoir un peu d'expérience des `Makefile`s, parce qu'ils sont très compliqués (et si vous les regardez, ayez sous la main une bonne dose de café serré!).

## 4.4. Utilisation plus poussée de `make`

`make` est un outil très puissant, et peut faire beaucoup plus que l'exemple élémentaire que nous avons donné. Il y a malheureusement plusieurs versions de `make`, et elles sont très différentes. La meilleure façon de savoir ce qu'elles peuvent faire est certainement de lire la documentation - espérons que cette introduction vous aura fourni les bases pour le faire.

La version de `make` fournie avec FreeBSD est Berkeley make; elle s'accompagne d'un guide dans `/usr/share/doc/psd/12.make`. Pour le visualiser, tapez:

    % zmore paper.ascii.gz

dans ce répertoire.

Il y a des nombreux logiciels du catalogue des logiciels portés qui utilisent GNU make, qui est très bien documenté dans les pages ``info''. Si vous avez installé un de ces logiciels, GNU make sera automatiquement installé sont le nom `gmake`. Il est aussi disponible sous forme de logiciel porté ou précompilé autonome.

Pour visualiser les pages ``info'' de GNU make, il vous faut éditer le fichier `dir` du répertoire `/usr/local/info` et y ajouter une ligne pour ce programme. C'est une ligne du genre:

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

Une fois que c'est fait, vous pouvez taper `info` puis sélectionner make dans le menu (ou sous Emacs, taper `C-h i`).

### Notes

[1] | Ils n'utilisent pas la variante `MAKEFILE` parce que les noms en majuscules servent souvent à désigner les fichiers de documentation comme `README`.

Précédent | Sommaire | Suivant
Compiler avec `cc` |  | Déboguer

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>.