6.10. Ajustement de la chaîne d'outils

Maintenant que les bibliothèques C finales ont été installées, il est temps d'ajuster la chaîne d'outils pour qu'elle lie tout programme nouvellement compilé à ces nouvelles bibliothèques.

D'abord, sauvegardez l'éditeur de liens de /tools, et remplacez-le par l'éditeur de lien ajusté que nous avons fait au chapitre 5. Nous créerons aussi un lien vers son équivalent dans /tools/$(uname -m)-pc-linux-gnu/bin :

mv -v /tools/bin/{ld,ld-old}
mv -v /tools/$(uname -m)-pc-linux-gnu/bin/{ld,ld-old}
mv -v /tools/bin/{ld-new,ld}
ln -sv /tools/bin/ld /tools/$(uname -m)-pc-linux-gnu/bin/ld

Puis, modifiez le fichier des specs GCC afin qu'il pointe vers le nouvel éditeur de liens dynamiques. La suppression simple de tous les exemples de « /tools » devrait nous laisser uniquement le bon chemin sur l'éditeur de liens dynamique. Ajustez aussi le fichier de specs pour que GCC sache où trouver les en-têtes correctes et les fichiers de démarrage de Glibc. Une commande sed fait cela :

gcc -dumpspecs | sed -e 's@/tools@@g'                   \
    -e '/\*startfile_prefix_spec:/{n;s@.*@/usr/lib/ @}' \
    -e '/\*cpp:/{n;s@$@ -isystem /usr/include@}' >      \
    `dirname $(gcc --print-libgcc-file-name)`/specs

C'est une bonne idée d'examiner visuellement le fichier de specs pour vérifier que le changement voulu a bien été effectué.

Il est impératif à ce moment d'arrêter et de vous assurer que les fonctions basiques (compilation et édition des liens) de l'ensemble des outils ajusté fonctionnent comme attendu. Pour cela, réalisez une petite vérification :

echo 'int main(){}' > dummy.c
cc dummy.c -v -Wl,--verbose &> dummy.log
readelf -l a.out | grep ': /lib'

Il ne devrait pas y avoir d'erreur et la sortie de la commande sera (avec des différences spécifiques aux plateformes dans le nom de l'éditeur de liens) :

[Requesting program interpreter: /lib/ld-linux.so.2]

Remarquez que /lib est maintenant le préfixe de notre éditeur de liens.

[Note]

Note

Sur les systèmes 64-bit, l’interpréteur devrait être /lib64/ld-linux-x86-64.so.2.

Maintenant, assurez-vous que nous utilisons les bons fichiers de démarrage :

grep -o '/usr/lib.*/crt[1in].*succeeded' dummy.log

La sortie de la dernière commande sera :

/usr/lib/crt1.o succeeded
/usr/lib/crti.o succeeded
/usr/lib/crtn.o succeeded
[Note]

Note

Sur les systèmes 64-bit, le chemin précédent sera /usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/../../../../lib64/. Cela se réduit à /usr/lib64 et /usr/lib64 est un lien symbolique qui pointe vers /usr/lib.

Vérifiez que le compilateur cherche les bons fichiers d'en-têtes :

grep -B1 '^ /usr/include' dummy.log

Cette commande devrait afficher la sortie suivante :

#include <...> search starts here:
 /usr/include

Puis, vérifiez que le nouvel éditeur de liens est utilisé avec les bons chemins de recherche :

grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'

Les références vers des localisations qui ont des composants avec '-linux-gnu' doivent être ignorées, sinon la sortie de la dernière commande doit être :

SEARCH_DIR("/usr/lib")
SEARCH_DIR("/lib");

Ensuite, assurez-vous que nous utilisons la bonne libc :

grep "/lib.*/libc.so.6 " dummy.log

La sortie de la dernière commande devrait être (avec un répertoire lib64 sur les hôtes 64 bits) :

attempt to open /lib/libc.so.6 succeeded

Pour finir, assurez-vous que GCC utilise le bon éditeur de liens dynamiques :

grep found dummy.log

La sortie de la commande devrait être (avec des différences spécifiques aux plateformes dans le nom de l'éditeur de liens et un répertoire lib64 sur les hôtes 64 bits) :

found ld-linux.so.2 at /lib/ld-linux.so.2

Si la sortie n'apparaît pas comme montré ci-dessus ou qu'elle n'apparaît pas du tout, alors quelque chose ne va vraiment pas. Enquêtez et retracez les étapes pour savoir d'où vient le problème et comment le corriger. La raison la plus probable est que quelque chose s'est mal passé lors de la modification du fichier specs ci-dessus. Tout problème devra être résolu avant de continuer le processus.

Une fois que tout fonctionne correctement, nettoyez les fichiers tests :

rm -v dummy.c a.out dummy.log