8.26.1. Installation de GCC
Si vous construisez sur x86_64, changez le nom du répertoire par
défaut des bibliothèques 64 bits en « lib » :
case $(uname -m) in
x86_64)
sed -e '/m64=/s/lib64/lib/' \
-i.orig gcc/config/i386/t-linux64
;;
esac
La documentation de GCC recommande de construire GCC dans un
répertoire de construction dédié :
mkdir -v build
cd build
Préparez la compilation de GCC :
../configure --prefix=/usr \
LD=ld \
--enable-languages=c,c++ \
--enable-default-pie \
--enable-default-ssp \
--disable-multilib \
--disable-bootstrap \
--with-system-zlib
Remarquez que pour d'autres langages de programmation, il existe
des prérequis qui ne sont pas encore disponibles. Consultez la
page GCC du livre BLFS pour des instructions sur la manière de
construire tous les langages pris en charge par GCC.
Voici la signification des nouveaux paramètres de
configuration :
-
LD=ld
-
Ce paramètre permet de s'assurer que le script configure
utilise le ld installé par binutils, construit plus tôt dans
ce chapitre, au lieu de la version compilée de manière
croisée qui serait autrement utilisée.
-
--with-system-zlib
-
Ce paramètre dit à GCC de se lier à la copie de la
bibliothèque zlib installée sur le système, plutôt qu'à sa
propre copie interne.
Note
PIE (exécutable indépendant de la position) est une technique
pour produire des programmes binaires qui peuvent être chargés
n'importe où en mémoire. Sans PIE, la fonctionnalité de sécurité
nommée ASLR (randomisation de l'agencement de l'espace
d'adressage) peut être appliquée pour les bibliothèques
partagées, mais pas pour l'exécutable lui-même. Activer PIE
permet l'ASLR des exécutables en plus des bibliothèques partagées
et réduit certaines attaques basées sur des adresses fixes de
code sensible ou de données dans les exécutables.
SSP (protection contre l'écrasement de la pile) est une technique
qui s'assure que la pile des paramètres n'est pas corrompue. La
corruption de pile peut par exemple changer l'adresse de retour
d'une sous-routine, ce qui permettrait de transférer le contrôle
à du code dangereux (qui existerait dans le programme ou les
bibliothèques partagées, ou éventuellement injecté par
l'attaquant) au lieu du code d'origine.
Compilez le paquet :
make
Important
Dans cette section, la suite de tests de GCC est considérée comme
importante, mais elle prend beaucoup de temps. Les novices sont
encouragés à ne pas l'ignorer. La durée des tests peut être
significativement réduite en ajoutant -jx à la commande make
ci-dessous, où x est le nombre de cœurs sur votre système.
Un ensemble de tests dans la suite de tests de GCC est connu pour
utiliser toute la pile par défaut, c'est pourquoi vous devez
augmenter la taille de la pile avant de lancer les tests :
ulimit -s 32768
Testez les résultats en tant qu'utilisateur non privilégié, mais ne
vous arrêtez pas aux erreurs :
chown -Rv tester .
su tester -c "PATH=$PATH make -k check"
Pour recevoir un résumé des résultats de la suite de tests,
lancez :
../contrib/test_summary
Pour n'avoir que les résumés, redirigez la sortie vers
grep -A7 Summ
.
Vous pouvez comparer les résultats avec ceux situés dans https://www.linuxfromscratch.org/lfs/build-logs/development/
et https://gcc.gnu.org/ml/gcc-testresults/.
Dans gcc, onze tests, dans la suite de tests i386, sont connus pour
échouer. C'est dû au fait que les fichiers de tests ne prennent pas
en compte l'option --enable-default-pie
.
Dans g++, quatre test liés à PR100400 sont connus pour être
rapportés à la fois en XPASS et en FAIL. C'est parce que le fichier
de test pour ce problème connu n'est pas bien écrit.
Quelques échecs inattendus sont parfois inévitables. Les
développeurs de GCC connaissent généralement ces problèmes, mais
ils ne les ont pas encore résolus. Sauf si les résultats des tests
sont très différents de ceux sur l'adresse ci-dessus, vous pouvez
poursuivre en toute sécurité.
Installez le paquet :
make install
Le répertoire de construction de GCC appartient maintenant à
tester
et la propriété du
répertoire des en-têtes installé (et son contenu) sera incorrecte.
Transférez la propriété à l'utilisateur et au groupe root
:
chown -v -R root:root \
/usr/lib/gcc/$(gcc -dumpmachine)/12.2.0/include{,-fixed}
Créez un lien symbolique requis par le FHS
pour des raisons « historiques ».
ln -svr /usr/bin/cpp /usr/lib
Ajoutez un lien symbolique de compatibilité pour permettre la
compilation de programmes avec l'optimisation à l'édition des liens
(LTO) :
ln -sfv ../../libexec/gcc/$(gcc -dumpmachine)/12.2.0/liblto_plugin.so \
/usr/lib/bfd-plugins/
Maintenant que notre chaîne d'outils est en place, il est important
de s'assurer à nouveau que la compilation et l'édition de liens
fonctionneront comme prévu. Vous devez alors effectuer plusieurs
contrôles d'intégrité :
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 dernière
commande devrait être (avec des différences spécifiques pour chaque
plateforme dans le nom du chargeur dynamique) :
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
Maintenant assurez-vous que vous êtes prêt à utiliser les bons
fichiers :
grep -E -o '/usr/lib.*/S?crt[1in].*succeeded' dummy.log
La sortie de la dernière commande devrait être :
/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../lib/Scrt1.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../lib/crti.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/../../../../lib/crtn.o succeeded
Selon l'architecture de votre machine, le message ci-dessus peut
légèrement différer. La différence porte sur le nom du répertoire
après /usr/lib/gcc
. Il est important
de vérifier que gcc a
trouvé les trois fichiers crt*.o
sous
le répertoire /usr/lib
.
Vérifiez que le compilateur recherche les bons fichiers
d'en-têtes :
grep -B4 '^ /usr/include' dummy.log
Cette commande devrait renvoyer la sortie suivante :
#include <...> search starts here:
/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include
/usr/local/include
/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include-fixed
/usr/include
À nouveau, le répertoire nommé selon votre triplet cible peut être
différent de celui ci-dessus, selon l'architecture de votre
système.
Ensuite, 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 au chemins qui ont des composantes comme
« -linux-gnu » devraient être ignorés, mais sinon la
sortie de la dernière commande devrait être :
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64")
SEARCH_DIR("/usr/local/lib64")
SEARCH_DIR("/lib64")
SEARCH_DIR("/usr/lib64")
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");
Un système 32 bits peut voir quelques répertoires
différemment. Par exemple, voici la sortie d'une machine
i686 :
SEARCH_DIR("/usr/i686-pc-linux-gnu/lib32")
SEARCH_DIR("/usr/local/lib32")
SEARCH_DIR("/lib32")
SEARCH_DIR("/usr/lib32")
SEARCH_DIR("/usr/i686-pc-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");
Ensuite assurez-vous que vous utilisez la bonne libc :
grep "/lib.*/libc.so.6 " dummy.log
La sortie de la dernière commande devrait être :
attempt to open /usr/lib/libc.so.6 succeeded
Assurez-vous que GCC utilise le bon éditeur dynamique :
grep found dummy.log
La sortie de la dernière commande devrait être (avec éventuellement
des différences spécifiques à votre plateforme dans le nom de
l'éditeur dynamique) :
found ld-linux-x86-64.so.2 at /usr/lib/ld-linux-x86-64.so.2
Si la sortie ne ressemble pas à celle montrée ci-dessus ou si elle
n'est pas disponible du tout, alors quelque chose s'est vraiment
mal passé. Enquêtez et répétez les étapes pour trouver où les
problème se trouve et corrigez-le. Tout problème doit être résolu
avant de continuer le processus.
Une fois que tout fonctionne correctement, nettoyez les fichiers de
test :
rm -v dummy.c a.out dummy.log
Enfin, déplacez un fichier mal placé :
mkdir -pv /usr/share/gdb/auto-load/usr/lib
mv -v /usr/lib/*gdb.py /usr/share/gdb/auto-load/usr/lib