23.6. Recompiler le système
Précédent | Chapitre 23. Mise à jour de FreeBSD | Suivant

## 23.6. Recompiler le système

Une fois que vous avez synchronisé votre arborescence des sources avec une version donnée de FreeBSD (FreeBSD-STABLE, FreeBSD-CURRENT, et ainsi de suite) vous pouvez alors utiliser cette arborescence des sources pour recompiler le système.

### Faites une sauvegarde:

On n'insistera jamais assez sur l'importance de faire une sauvegarde de votre système avant tout autre chose. Bien qu'il soit facile de “refaire le monde” (recompiler FreeBSD), si vous suivez ces instructions, vous ferez inévitablement des erreurs à un moment ou un autre, ou d'autres feront des erreurs au niveau de l'arborescence des sources qui empêcheraient votre système de redémarrer.

Assurez-vous que vous avez bien fait une sauvegarde. Ayez une disquette de maintenance, ou un CD démarrable à portée de la main. Vous ne l'utiliserez probablement pas, mais prudence est mère de sûreté!

### S'abonner à la bonne liste de diffusion:

Les branches FreeBSD-STABLE et FreeBSD-CURRENT sont, par nature, en développement. Les personnes qui participent à FreeBSD sont des humains, et des erreurs se produisent occasionnellement.

Ces erreurs sont parfois bénignes, provocant simplement l'affichage d'un nouveau message d'avertissement par votre système. Elles peuvent aussi être catastrophiques, et empêcher votre système de redémarrer ou détruire vos systèmes de fichiers (ou pire).

Quand de tels problèmes se produisent, un avertissement “heads up” est posté sur la liste de diffusion appropriée, décrivant la nature du problème et quels systèmes sont concernés. Un message “all clear” est posté quand le problème est résolu.

Si vous tentez de suivre FreeBSD-STABLE ou FreeBSD-CURRENT et que vous ne lisez pas la liste de diffusion à propos de la branche FreeBSD-STABLE ou la liste de diffusion à propos de la branche FreeBSD-CURRENT, vous allez au devant d'ennuis.

### N'utilisez pas la commande `make world`:

De nombreuses anciennes documentations préconisent d'utiliser la commande `make world`. Cette commande n'effectue pas un certain nombre d'étapes importantes et ne devrait être utilisée que si vous êtes sûr de ce que vous faites. Dans presque tout les cas `make world` n'est pas une bonne chose à faire, et la procédure décrite dans la suite de ce document devrait être utilisée à la place.

### 23.6.1. La méthode générique de mise à jour du système

Pour mettre à jour votre système, vous devriez consulter `/usr/src/UPDATING` pour toute opération préliminaire nécessaire en fonction de la version de vos sources et ensuite utiliser la procédure suivante:

    # cd /usr/src
    # make buildworld
    # make buildkernel
    # make installkernel
    # shutdown -r now

### Note:

Dans quelques rares cas, il est nécessaire de lancer un `mergemaster -p` avant l'étape `buildworld`. Ces cas sont décrits dans le fichier `UPDATING`. Généralement, vous pouvez omettre cette opération si vous ne mettez pas à jour d'une version majeure de FreeBSD à une autre.

Une fois l'opération `installkernel` terminée avec succès, vous devrez démarrer en mode mono-utilisateur (en utilisant par exemple la commande `boot -s` à l'invite du chargeur). Exécutez ensuite:

    # mount -a -t ufs
    # mergemaster -p
    # cd /usr/src
    # make installworld
    # mergemaster
    # reboot

### Lisez les explications supplémentaires:

La séquence décrite ci-dessus n'est qu'un court résumé pour vous aider à démarrer. Vous devriez cependant lire les sections suivantes afin de comprendre clairement chaque étape, tout particulièrement si vous désirez utiliser une configuration du noyau personnalisée.

### 23.6.2. Lire `/usr/src/UPDATING`

Avant tout autre chose, lisez `/usr/src/UPDATING` (ou le fichier équivalent en fonction de l'endroit où se trouve vos sources). Ce fichier devrait contenir les informations importantes au sujet des problèmes que vous pourriez rencontrer, ou indique l'ordre dans lequel vous devriez exécuter certaines commandes. Si le fichier `UPDATING` contredit quelque chose d'écrit ici, `UPDATING` prime sur tout le reste.

### Important:

La lecture du fichier `UPDATING` n'est pas un substitut à l'abonnement à la liste de diffusion correcte, comme décrit précédemment. Ces deux prérequis sont complémentaires, et non pas exclusifs.

### 23.6.3. Contrôler `/etc/make.conf`

Contrôlez les fichiers `/usr/share/examples/etc/make.conf` et `/etc/make.conf`. Le premier contient des paramètres par défaut – la plupart étant placés en commentaires. Pour les utiliser quand vous recompilez votre système à partir des sources, rajoutés-les au fichier `/etc/make.conf`. Gardez à l'esprit que tout ce que vous ajoutez au fichier `/etc/make.conf` est utilisé chaque fois que vous invoquez la commande `make`, il est donc bon de s'assurer que les valeurs par défaut sont appropriées à votre système.

Un utilisateur typique voudra probablement copier les lignes `CFLAGS` et `NO_PROFILE` se trouvant dans `/usr/share/examples/etc/make.conf` vers `/etc/make.conf` et les décommenter.

Examinez les autres définitions (`COPTFLAGS`, `NOPORTDOCS` et ainsi de suite) et décidez si elles vous conviennent.

### 23.6.4. Mettre à jour les fichiers dans `/etc`

Le répertoire `/etc` contient la plupart des informations de configuration de votre système, ainsi que les procédures de démarrage. Certaines de ces procédures changent d'une version à l'autre de FreeBSD.

Certains fichiers de configuration sont également utilisés en permanence par le système. En particulier `/etc/group`.

Il est arrivé que la phase d'installation `make installworld` ait besoin que certains utilisateurs et groupes existent. Il y a de fortes chances qu'ils n'aient pas été définis avant la mise à jour. C'est une source de problèmes. Dans certains cas `make buildworld` contrôlera si ces utilisateurs ou groupes existent.

Un exemple de cela fut l'addition de l'utilisateur `smmsp`. Le processus d'installation échouait quand `mtree` tentait de créer `/var/spool/clientmqueue`.

La solution est d'exécuter mergemaster(8) dans le mode pré-“buildworld” en ajoutant l'option `-p`. Cela effectuera la comparaison uniquement des fichiers essentiels pour le succès de la procédure `buildworld` ou `installworld`. Si votre vieille version de `mergemaster` ne supporte pas l'option `-p`, utilisez la nouvelle version présente dans l'arborescence des sources quand vous l'exécutez pour la première fois:

    # cd /usr/src/usr.sbin/mergemaster
    # ./mergemaster.sh -p

### Astuce:

Si vous êtes particulièrement paranoïaque, vous pouvez contrôler votre système afin de voir quels fichiers appartiennent au groupe que vous renommez ou effacez:

    # find / -group GID -print

affichera les fichiers appartenant au groupe `GID` (qui peut être soit un nom de groupe ou un identifiant numérique de groupe).

### 23.6.5. Passer en mode mono-utilisateur

Il vaut mieux recompiler le système en mode mono-utilisateur. En dehors du fait que cela sera légèrement plus rapide, la réinstallation va modifier un grand nombre de fichiers systèmes importants, tous les binaires de base du système, les bibliothèques, les fichiers d'include et ainsi de suite. Les modifier sur un système en fonctionnement (en particulier s'il y a des utilisateurs connectés à ce moment là), c'est aller au devant de problèmes.

Une autre méthode consiste à compiler le système en mode multi-utilisateurs, et passer dans le mode mono-utilisateur pour l'installation. Si vous désirez utiliser cette méthode, conservez les étapes suivantes pour le moment où la compilation sera terminée. Vous pouvez reporter le passage en mode mono-utilisateur jusqu'à l'exécution de `installkernel` ou `installworld`.

En tant que super-utilisateur, vous pouvez exécuter la commande:

    # shutdown now

sur un système en fonctionnement, pour passer en mode mono-utilisateur.

Ou bien, redémarrer le système, et à l'invite de démarrage, sélectionnez l'option « single user ». Le système démarrera alors en mode mono-utilisateur. A l'invite de l'interpréteur de commandes, exécutez alors:

    # fsck -p
    # mount -u /
    # mount -a -t ufs
    # swapon -a

Cela effectue une vérification des systèmes de fichiers, remonte `/` en mode lecture/écriture, et monte tous les autres systèmes de fichiers UFS listés dans le fichier `/etc/fstab`, puis active la pagination.

### Note:

Si votre horloge CMOS est réglée sur l'heure locale et non pas sur le fuseau GMT (cela est vrai si la sortie de la commande `date` ne donne pas l'heure et le fuseau correct), vous aurez également peut-être besoin d'exécuter la commande suivante:

    # adjkerntz -i

Cela permettra de s'assurer que vos paramètres de fuseaux horaires sont correctement configurés — sans cela, vous risquez de faire face, plus tard, à des problèmes.

### 23.6.6. Effacer `/usr/obj`

Au fur et à mesure que les différentes parties du système sont recompilées, elles sont placées dans des répertoires qui (par défaut) sont sous `/usr/obj`. Les répertoires sont agencés comme sous `/usr/src`.

Vous pouvez accélérer le processus `make buildworld`, et également vous éviter d'éventuels problèmes de dépendances en effaçant ce répertoire.

Certains fichiers dans `/usr/obj` peuvent avoir l'indicateur immuable positionné (consultez la page de manuel chflags(1) pour plus d'informations) qui doit être retiré en premier.

    # cd /usr/obj
    # chflags -R noschg *
    # rm -rf *

### 23.6.7. Recompiler le système de base

#### 23.6.7.1. Enregistrer la sortie

C'est une bonne idée d'enregistrer la sortie de make(1) dans un fichier. Si quelque chose se passe mal, vous aurez une trace des messages d'erreur. Même si cela ne vous aide pas à diagnostiquer ce qui n'a pas fonctionné, cela peut aider les autres si vous postez votre problème sur une des listes de diffusion de FreeBSD.

La méthode la plus aisée pour faire cela est d'utiliser la commande script(1), avec en paramètre le nom du fichier où enregistrer les résultats. Vous devez faire cela immédiatement juste avant de recompiler le système, et taper `exit` une fois que c'est terminé.

    # script /var/tmp/mw.out
    Script started, output file is /var/tmp/mw.out
    # make TARGET
    … compile, compile, compile …
    # exit
    Script done, …

Si vous le faites, n'enregistrez pas le résultat dans `/tmp`. Ce répertoire peut être vidé au prochain redémarrage du système. Un meilleur endroit de sauvegarde est `/var/tmp` (comme dans l'exemple précédent) ou dans le répertoire utilisateur de `root`.

#### 23.6.7.2. Compiler le nouveau système

Vous devez être dans le répertoire `/usr/src`:

    # cd /usr/src

(à moins, bien sûr, que votre code source ne soit ailleurs, auquel cas vous devrez aller dans le répertoire correspondant).

Pour recompiler le système, on utilise la commande make(1). Cette commande lit ses instructions dans le fichier `Makefile`, qui décrit comment devraient être reconstruits les programmes qui constituent FreeBSD, dans quel ordre, et ainsi de suite.

Le format général de la ligne de commande que vous taperez sera la suivante:

    # make -x -DVARIABLE cible

Dans cet exemple, `-`x`` est une option que vous passez à make(1). Reportez-vous à la page de manuel pour un exemple d'options que vous pouvez passer.

`-D`VARIABLE`` transmet un variable au fichier `Makefile`. Le comportement du `Makefile` est défini par ces variables. Ce sont les mêmes variables que l'on trouve dans `/etc/make.conf`, et c'est un autre moyen de les positionner.

    # make -DNO_PROFILE cible

est une autre manière de dire qu'il ne faut pas compiler les bibliothèques profilées et correspond à la ligne:

    NO_PROFILE=    true	#    Avoid compiling profiled libraries

dans `/etc/make.conf`.

`cible` indique à make(1) ce que vous voulez faire. Chaque `Makefile` définit un certain nombre de “cibles”, et votre choix de cible détermine ce qui se passe.

Certaines cibles listées dans le fichier `Makefile`, ne doivent pas être employées. Ce sont des étapes intermédiaires utilisées par le processus de recompilation pour décomposer les étapes importantes de la recompilation du système en sous-étapes.

La plupart du temps, vous n'aurez pas besoin de passer de paramètres à make(1), et votre commande ressemblera à ceci:

    # make cible

Où `cible` sera une des nombreuses options de compilation. La première cible devrait toujours être `buildworld`.

Comme leurs noms l'indiquent, `buildworld` reconstruit la nouvelle arborescence dans `/usr/obj`, et `installworld`, une autre cible, l'installe sur la machine.

Disposer d'options séparées est très utile pour deux raisons. Tout d'abord cela vous permet de recompiler en toute sûreté en sachant qu'aucun composant du système actuel ne sera affecté. La compilation est “autonome”. En raison de cela vous pouvez exécuter `buildworld` sur une machine en mode multi-utilisateurs sans redouter d'effets fâcheux. Il est néanmoins recommandé de toujours exécuter l'étape `installworld` en mode mono-utilisateur.

En second lieu, cela vous permet d'utiliser des systèmes montés par NFS pour mettre à jour plusieurs machines de votre réseau. Si vous avez trois machines `A`, `B` et `C` que vous voulez mettre à jour, exécutez `make buildworld` et `make installworld` sur `A`. `B` et `C` doivent ensuite monter par NFS `/usr/src` et `/usr/obj` depuis `A`, et vous pouvez alors exécuter `make installworld` pour installer le système recompilé sur `B` et `C`.

Bien que la cible `world` existe toujours, vous êtes fortement encouragé à ne pas l'utiliser.

Exécutez:

    # make buildworld

Il est possible de passer l'option `-j` à make(1) ce qui lui permettra d'exécuter plusieurs processus simultanément. C'est particulièrement utile sur une machine avec plusieurs processeurs. Cependant, comme la compilation est plus gourmande en E/S plutôt qu'en CPU, c'est également utile sur des machines mono-processeur.

Typiquement sur une machine mono-processeur, vous exécuteriez:

    # make -j4 buildworld

make(1) pourra exécuter jusqu'à 4 processus simultanément. Des constatations empiriques postées sur les listes de diffusion montrent que c'est en général ce qui apporte le plus de gain en performances.

Si vous avez une machine multi-processeurs et que vous avez configuré un noyau SMP, essayez des valeurs entre 6 et 19 et voyez quel bénéfice vous en tirez.

#### 23.6.7.3. Durée

De nombreux facteurs influencent la durée de compilation, mais les machines récentes devraient mettrent seulement de une à deux heures pour compiler l'arborescence FreeBSD-STABLE, sans modification ni raccourcis durant le processus. Une arborescence FreeBSD-CURRENT nécessitera un peu plus de temps.

### 23.6.8. Compiler et installer un nouveau noyau

Pour tirer pleinement parti de votre nouveau système, vous devrez recompiler le noyau. C'est pratiquement indispensable, parce que certaines structures mémoires peuvent avoir changées, et des programmes comme ps(1) et top(1) ne fonctionneront pas tant que le système et le noyau n'utilisent pas les mêmes versions de code source.

La manière la plus simple et la plus sûre est de compiler et installer un noyau basé sur le noyau `GENERIC`. Alors que le noyau `GENERIC` peut ne pas comporter les pilotes de périphériques nécessaires pour votre système, il devrait contenir tout ce qui est nécessaire pour faire démarrer votre système en mode mono-utilisateur. C'est une bonne façon de tester le fonctionnement de votre nouveau système. Après avoir démarré à partir du noyau `GENERIC` et vérifié que votre système fonctionne vous pouvez alors compiler un nouveau noyau basé sur votre fichier de configuration normal du noyau.

Sur FreeBSD, il est important de recompiler le système avant de compiler un nouveau noyau.

### Note:

Si vous désirez compiler un noyau personnalisé, et que vous avez déjà un fichier de configuration, utilisez juste `KERNCONF=`MONNOYAU`` comme suit:

    # cd /usr/src
    # make buildkernel KERNCONF=MONNOYAU
    # make installkernel KERNCONF=MONNOYAU

Notez que si vous avez augmenté la variable `kern.securelevel` à une valeur supérieure à 1 et que vous avez positionné l'indicateur `noschg` ou similaire sur votre noyau, il sera intéressant de passer en mode mono-utilisateur pour utiliser `installkernel`. Sinon vous devriez être en mesure d'exécuter ces commandes à partir du mode multi-utilisateur sans problèmes. Voir la page de manuel de init(8) pour plus de détails à propos de `kern.securelevel` et la page chflags(1) pour des informations sur les différents indicateurs de fichiers.

### 23.6.9. Redémarrer en mode mono-utilisateur

Vous devriez redémarrer en mode mono-utilisateur pour tester le fonctionnement du nouveau noyau. Pour cela suivez les instructions de Section 23.6.5, « Passer en mode mono-utilisateur ».

### 23.6.10. Installer les nouveaux binaires système

Si vous avez compilé une version de FreeBSD assez récente pour avoir utilisé `make buildworld` alors vous devriez utiliser maintenant `installworld` pour installer les nouveaux binaires système.

Lancez:

    # cd /usr/src
    # make installworld

### Note:

Si vous spécifiez des variables sur la ligne de commande de `make buildworld`, vous devez utiliser les mêmes variables avec la commande `make installworld`. Cela ne reste pas forcément vrai pour d'autres options; par exemple, `-j` ne doit jamais être utilisée avec `installworld`.

Par exemple, si vous exécutez:

    # make -DNO_PROFILE buildworld

vous devrez ensuite installer les résultats avec:

    # make -DNO_PROFILE installworld

sinon il essayera d'installer les bibliothèques profilées qui n'ont pas été recompilées à l'étape `make buildworld`.

### 23.6.11. Mettre à jour les fichiers non modifiés par `make installworld`

La recompilation du système ne mettra pas à jour certains répertoires (en particulier, `/etc`, `/var` et `/usr`) avec les fichiers nouveaux ou modifiés.

La manière la plus simple de mettre à jour ces fichiers est d'utiliser mergemaster(8), bien qu'il soit possible de le faire manuellement si vous le désirez. Indépendamment de la manière que vous choisissez, assurez-vous de faire une sauvegarde du répertoire `/etc` au cas où quelque chose se passerait mal.

#### 23.6.11.1. `mergemaster`

Contribution de Tom Rhodes.

L'utilitaire mergemaster(8) est une procédure Bourne qui vous aidera à déterminer les différences entre vos fichiers de configuration dans le répertoire `/etc`, et les fichiers de configuration dans l'arborescence des sources `/usr/src/etc`. C'est la solution recommandée pour maintenir à jour les fichiers de configuration du système avec ceux situés dans l'arborescence des sources.

Pour commencer, tapez simplement `mergemaster` à l'invite, et observez-le travailler. `mergemaster` commencera à constituer une arborescence temporaire, à partir de `/`, et la remplira avec divers fichiers de configuration. Ces fichiers sont alors comparés avec ceux actuellement installés sur votre système. A ce point, les fichiers qui diffèrent seront affichés dans le format diff(1), avec le signe `+` représentant les lignes modifiées ou ajoutées, et le `-` représentant les lignes qui seront soit complètement supprimées, soit remplacées avec une nouvelle ligne. Voir la page de manuel diff(1) pour plus d'informations au sujet de la syntaxe diff(1) et comment sont affichées les différences.

mergemaster(8) vous affichera ensuite chaque fichier présentant des différences, et vous aurez à ce moment-là le choix de soit supprimer le nouveau fichier (le fichier temporaire), soit d'installer le fichier temporaire non modifié, soit de fusionner le fichier temporaire et le fichier actuellement installé, soit enfin de revoir les résultats de l'opération diff(1).

Choisir de supprimer le fichier temporaire indiquera à mergemaster(8) que nous désirons conserver notre fichier actuel intacte, et effacera la nouvelle version. Cette option n'est pas recommandée, à moins que vous ne voyez aucune raison de modifier le fichier actuel. Vous pouvez obtenir de l'aide à n'importe quel moment en tapant ? à l'invite de mergemaster(8). Si l'utilisateur choisit de passer un fichier, il sera présenté à nouveau une fois que tous les autres fichiers auront été traités.

Choisir d'installer un fichier temporaire intact remplacera le fichier actuel avec le nouveau. Pour la plupart des fichiers non modifiées, c'est la meilleure option.

Choisir de fusionner le fichier, vous affichera un éditeur de texte, et le contenu des deux fichiers. Vous pouvez maintenant les fusionner en les visionnant côte à côte sur l'écran, et en sélectionnant des parties des deux fichiers pour créer un fichier final. Quand les fichiers sont comparés côte à côte, la touche l sélectionnera le contenu de gauche et la touche r sélectionnera celui de droite. Le résultat final sera un fichier constitué des deux parties, qui peut alors être installé. Cette option est habituellement utilisée pour les fichiers où les des paramètres ont été modifiés par l'utilisateur.

Choisir de revoir les résultats de l'opération diff(1) vous affichera les différences entre fichiers tout comme la fait mergemaster(8) avant de vous demander un choix.

Après que mergemaster(8) en ait terminé avec les fichiers système, il vous proposera de nouvelles opérations. mergemaster(8) vous demandera si vous désirez reconstruire le fichier des mots de passe et terminera en vous proposant de supprimer les fichiers temporaires restants.

#### 23.6.11.2. Mise à jour manuelle

Si vous désirez faire la mise à jour manuellement, vous ne pouvez cependant pas vous contenter de copier les fichiers de `/usr/src/etc` dans `/etc` pour que cela fonctionne. Certains de ces fichiers doivent d'abord être “installés”. En effet le répertoire `/usr/src/etc` “n'est pas” une copie de ce que devrait contenir votre répertoire `/etc`. De plus, il a des fichiers qui doivent être dans `/etc` et qui ne sont pas dans `/usr/src/etc`.

Si vous utilisez mergemaster(8) (comme recommandé), vous pouvez passer cette section et aller directement à la section suivante.

La façon la plus simple de procéder est d'installer les fichiers dans un nouveau répertoire, puis de passer en revue les différences.

### Sauvegardez votre répertoire `/etc` actuel:

Bien qu'en principe rien ne sera modifié automatiquement dans ce répertoire, prudence est mère de sûreté. Copiez donc votre répertoire `/etc` dans un endroit sûr. Quelque chose du genre:

    # cp -Rp /etc /etc.old

conviendra; l'option `-R` fait une copie récursive, `-p` préserve la date, les autorisations des fichiers et ainsi de suite.

Vous devez créer un ensemble de répertoires provisoires pour y installer les fichiers du répertoire `/etc` et autres. `/var/tmp/root` est un bon choix, il y a un certain nombre de sous-répertoires à créer également:

    # mkdir /var/tmp/root
    # cd /usr/src/etc
    # make DESTDIR=/var/tmp/root distrib-dirs distribution

Cela va créer l'arborescence nécessaire et y installera les fichiers. Un grand nombre des sous-répertoires créés dans `/var/tmp/root` sont vides et devront être supprimés. La façon la plus simple de le faire est:

    # cd /var/tmp/root
    # find -d . -type d | xargs rmdir 2>/dev/null

Ceci supprimera tous les répertoires vides (la sortie d'erreur standard est redirigée vers `/dev/null` pour empêcher les avertissements à propos des répertoires non vides).

`/var/tmp/root` contient maintenant tous les fichiers à installer à l'endroit requis sous `/`. Vous devez maintenant examiner chacun de ces fichiers pour déterminer en quoi ils diffèrent de vos propres fichiers.

Notez que certains des fichiers qui seront installés dans `/var/tmp/root` commencent par un “.”. Au moment où sont écrites ces lignes, les seuls fichiers concernés sont les fichiers d'initialisation des interpréteurs de commandes dans `/var/tmp/root/` et `/var/tmp/root/root/`, mais il pourrait y en avoir d'autres (cela dépend de quand vous lirez ces lignes). Assurez-vous d'utiliser la commande `ls -a` pour ne pas les oublier.

La manière la plus simple de procéder est d'utiliser la commande diff(1) pour comparer les deux fichiers:

    # diff /etc/shells /var/tmp/root/etc/shells

Cela vous indiquera les différences entre votre fichier `/etc/shells` et le nouveau fichier `/var/tmp/root//etc/shells`. A partir de là, décidez si vous aller reporter les modifications que vous y avez apportée ou si vous allez simplement recopier le nouveau fichier.

### Donnez au nouveau répertoire racine (`/var/tmp/root`) un nom qui inclue une date, pour pouvoir facilement comparer les différentes versions:

Si vous recompilez fréquemment votre système, cela signifie que vous devez également souvent mettre à jour le répertoire `/etc`, ce qui peut rapidement devenir une corvée.

Vous pouvez accélérer le processus en conservant une copie du dernier ensemble de fichiers modifiés que vous avez reportés dans `/etc`. La procédure suivante présente une façon de faire.

1. Recompilez le système comme à l'accoutumé. Au moment de mettre à jour `/etc` et les autre répertoires, donnez au répertoire cible un nom basé sur la date du jour. Si vous faisiez cela le 14 février 1998, vous pourriez procéder comme suit:

       # mkdir /var/tmp/root-19980214
       # cd /usr/src/etc
       # make DESTDIR=/var/tmp/root-19980214 \
           distrib-dirs distribution

2. Reporter les modifications depuis ce répertoire comme décrit plus haut.

   Ne supprimez pas le répertoire `/var/tmp/root-19980214` quand vous aurez terminé.

3. Quand vous récupérez la dernière version des sources et la recompilerez, suivez l'étape 1. Vous aurez alors un nouveau répertoire, qui pourrait s'appeler `/var/tmp/root-19980221` (si vous faites une mise à jour chaque semaine).

4. Vous pouvez maintenant voir les modifications intervenues d'une semaine à l'autre en utilisant diff(1) pour afficher les différences entre tous les fichiers deux répertoires:

       # cd /var/tmp
       # diff -r root-19980214 root-19980221

   Généralement, il y aura beaucoup moins de différences qu'entre `/var/tmp/root-19980221/etc` et `/etc`. Comme il y a beaucoup moins de différences, il est beaucoup plus facile de les reporter dans le répertoire `/etc`.

5. Vous pouvez maintenant supprimer le plus ancien des deux répertoires `/var/tmp/root-*`:

       # rm -rf /var/tmp/root-19980214

6. Répétez l'opération chaque fois que vous devez reporter des modifications dans `/etc`.

Vous pouvez utiliser date(1) pour automatiser la génération des noms de répertoires:

    # mkdir /var/tmp/root-`date "+%Y%m%d"`

### 23.6.12. Redémarrer

Vous en avez terminé. Après avoir vérifié que tout semble être en place, vous pouvez alors redémarrez votre système. Un simple shutdown(8) devrait suffire:

    # shutdown -r now

### 23.6.13. C'est fini

Vous devriez maintenant avoir mis à jour avec succès votre système FreeBSD. Félicitations.

Si les choses se sont légèrement mal passées, il est facile de recompiler un élément particulier du système. Par exemple, si vous avez accidentellement effacé `/etc/magic` lors de la mise à jour de `/etc`, la commande file(1) ne fonctionnerait plus. Dans ce cas, la solution serait d'exécuter:

    # cd /usr/src/usr.bin/file
    # make all install

### 23.6.14. Questions

23.6.14.1. Dois-je refaire le monde à chaque évolution?
23.6.14.2. Ma compilation échoue avec de nombreuses erreurs “signal 11” (ou tout autre numéro de signal). Que s'est-il passé?
23.6.14.3. Puis-je effacer /usr/obj après avoir fini?
23.6.14.4. Une recompilation interrompue peut-elle être reprise?
23.6.14.5. Comment puis-je accélérer la compilation du système?
23.6.14.6. Que faire si quelque chose se passe mal?

23.6.14.1. | Dois-je refaire le monde à chaque évolution?
| Il n'y a pas de réponse toute faite à cette question, tout dépend de la nature des évolutions. Par exemple, si vous venez juste d'exécuter CVSup, et que les fichiers suivants on été mis à jour:
    src/games/cribbage/instr.c
    src/games/sail/pl_main.c
    src/release/sysinstall/config.c
    src/release/sysinstall/media.c
    src/share/mk/bsd.port.mk
cela ne vaut probablement pas la peine de recompiler tout le système. Vous pouvez tout simplement aller dans les sous-répertoires appropriés, exécuter `make all install`, et c'est à peu près tout. Mais s'il y a des évolutions importantes, par exemple sur `src/lib/libc/stdlib` alors vous devrez soit refaire le monde, ou recompiler au moins toutes les parties du système qui sont liées statiquement (de même que tout ce vous pourriez avoir ajouté qui y serait lié statiquement). C'est à vous de voir. Vous préférerez peut-être recompiler votre système tous les quinze jours, et laisser les modifications s'empiler pendant quinze jours. Ou bien vous préférerez ne recompiler que ce qui a changé et vous faire confiance pour tout ce qui en dépend. Et, bien sûr, cela dépend de la fréquence avec laquelle vous voulez faire vos mises à jour, et de si vous suivez la branche FreeBSD-STABLE ou FreeBSD-CURRENT.
23.6.14.2. | Ma compilation échoue avec de nombreuses erreurs “signal 11” (ou tout autre numéro de signal). Que s'est-il passé?
| Cela indique généralement un problème matériel. (Re)compiler le système est un bon moyen de mettre votre matériel sous pression, et mettra souvent en évidence des défaillances de la mémoire vive. Elles se manifestent normalement d'elles-mêmes, la compilation échouant lors de la réception de mystérieux signaux. Un bon indicateur de cet état de fait, est que vous pouvez relancer la compilation et qu'elle échouera en un endroit différent. Dans ce cas, vous ne pouvez guère faire autre chose que d'intervertir les différents composants de votre matériel pour déterminer lequel est en cause.
23.6.14.3. | Puis-je effacer `/usr/obj` après avoir fini?
| Une réponse courte est oui. `/usr/obj` contient tous les fichiers objets générés à la compilation. Normalement, une des premières étapes de `make buildworld` est de supprimer ce répertoire et de repartir à zéro. Dans ce cas, conserver le répertoire `/usr/obj` après avoir terminé ne sert pas à grand chose, alors que vous économiseriez pas mal d'espace disque (actuellement environ 340 MO). Cependant, si vous savez ce que vous faites, vous pouvez faire en sorte que `make buildworld` saute cette étape. Cela rendra les compilations ultérieures plus rapides, puisque la plupart des sources n'auront pas besoin d'être recompilées. Le revers de la médaille est que des problèmes subtils de dépendance peuvent se manifester, provoquant l'échec de votre compilation de manière étrange. Cela génère fréquemment du bruit sur les listes de diffusion de FreeBSD, quand quelqu'un se plaint que sa mise à jour a échoué, sans réaliser que c'est parce qu'il a tenté de brûler les étapes.
23.6.14.4. | Une recompilation interrompue peut-elle être reprise?
| Tout dépend de jusqu'où vous êtes aller avant de rencontrer un problème. En général (et ceci n'est pas une règle absolue) `make buildworld` crée de nouveaux exemplaires des outils indispensables (comme gcc(1) et make(1)) et des bibliothèques système. Ces outils et bibliothèques sont ensuite installés. Puis ils sont utilisés pour se reconstruire eux-mêmes, et installés de nouveau. L'intégralité du système (y compris maintenant les programmes utilisateurs classiques, comme ls(1) ou grep(1)) est alors recompilé avec les nouveaux fichiers système. Si vous êtes à cette dernière étape, et que vous le savez (parce que vous avez consulté les résultats que vous avez enregistrés) alors vous pouvez (sans trop de risque) faire:
    … fix the problem …
    # cd /usr/src
    # make -DNO_CLEAN all
Cela ne détruira pas les résultats du travail qu'à déjà effectué `make buildworld`. Si vous voyez le message:
    --------------------------------------------------------------
    Building everything..
    --------------------------------------------------------------
dans les comptes-rendus de `make buildworld` alors cette façon de procéder est probablement bonne. Si vous ne voyez pas ce message, ou que vous doutez de vous, alors prudence est mère de sûreté, et il vaut mieux tout reprendre depuis le début.
23.6.14.5. | Comment puis-je accélérer la compilation du système?
- | Passez en mode mono-utilisateur. Mettez les répertoires `/usr/src` et `/usr/obj` sur des systèmes de fichiers et des disques différents. Si possible, installez ces disques sur des contrôleurs différents. Encore mieux, mettez ces systèmes de fichiers sur plusieurs disques utilisant le système ccd(4) (pilote de disques concaténés). Ne compilez pas les bibliothèques profilées (mettez “NO_PROFILE=true” dans le fichier `/etc/make.conf`). Vous n'en avez certainement pas besoin. Egalement dans `/etc/make.conf`, positionnez `CFLAGS` à quelque chose comme `-O -pipe`. L'optimisation `-O2` est bien plus lente, et la différence d'optimisation entre `-O` et `-O2` est en général négligeable. `-pipe` demande au compilateur d'utiliser des tuyaux à la place de fichiers temporaires, ce qui économise des accès disque (mais utilise plus de mémoire). Passez l'option `-j`n`` à make(1) pour permettre l'exécution de plusieurs processus en parallèle. Cela améliore généralement les choses, que vous ayez une machine mono- ou multi-processeurs. Le système de fichiers qui contient `/usr/src` peut être monté (ou remonté) avec l'option `noatime`. Cela empêche l'enregistrement des dates d'accès aux fichiers par le système de fichiers. Vous n'avez de toute façon probablement pas besoin de cette information.
      # mount -u -o noatime /usr/src
- ### Avertissement: Cet exemple suppose que `/usr/src` constitue à lui seul un système de fichiers. Si ce n'est pas le cas (s'il fait partie de `/usr` par exemple) vous devez alors indiquer le point de montage de ce système de fichiers, et non `/usr/src`. Le système de fichiers où se trouve `/usr/obj` peut être monté (ou remonté) avec l'option `async`. Les écritures sur le disque se feront alors de façon asynchrone. En d'autres termes, le programme reprend immédiatement la main, et l'écriture des données sur le disque se fait quelques secondes plus tard. Cela permet le groupement des écritures sur le disque, et le gain en performance peut être spectaculaire. ### Avertissement: Gardez à l'esprit que cette option rend votre système de fichiers plus fragile. Avec cette option, les risques ne sont accrus qu'en cas de coupure d'alimentation, le système de fichiers soit irrécupérable quand la machine redémarrera. S'il n'y a que `/usr/obj` sur ce système de fichiers, ce n'est alors pas un problème. Si vous avez d'autres données importantes sur ce système de fichiers, assurez-vous que vos sauvegardes soient à jour avant d'activer cette option.
      # mount -u -o async /usr/obj
### Avertissement: Comme auparavant, si `/usr/obj` ne constitue pas un système de fichiers en soit, remplacez-le dans l'exemple par le nom du point de montage approprié.
23.6.14.6. | Que faire si quelque chose se passe mal?
| Soyez absolument sûr que votre environnement ne contient pas des restes de compilation précédentes. Cela est plutôt simple:
    # chflags -R noschg /usr/obj/usr
    # rm -rf /usr/obj/usr
    # cd /usr/src
    # make cleandir
    # make cleandir
En effet, `make cleandir` doit vraiment être exécutée deux fois. Ensuite relancez l'ensemble du processus, en commençant avec `make buildworld`. Si vous avez toujours des problèmes, envoyez l'erreur et le résultat de la commande `uname -a` à la liste de diffusion pour les questions d'ordre général à propos de FreeBSD. Tenez-vous prêt à répondre à d'autres concernant votre configuration!

Précédent | Niveau supérieur | Suivant
23.5. Synchroniser vos sources | Sommaire | 23.7. Suivre les mises à jour pour plusieurs machines

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