8.29.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 \
--enable-host-pie \
--disable-multilib \
--disable-bootstrap \
--disable-fixincludes \
--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.
-
--disable-fixincludes
-
Par défaut, pendant l'installation de GCC, certains en-têtes
du système seraient « corrigés » pour fonctionner avec
GCC. Ce n'est pas nécessaire sur un système Linux moderne, et
peut être dangereux si un paquet est réinstallé après
l'installation de GCC. Ce paramètre évite que GCC ne
« corrige » les en-têtes.
-
--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 -k check
ci-dessous, où x désigne le nombre de cœurs sur votre système.
GCC peut avoir besoin de plus d'espace en pile pour compiler
certains motifs de code particulièrement complexes. Par précaution,
sur les distributions qui ont une limite de pile réduite,
configurez la limite de taille de pile à l'infini. Sur la plupart
des distributions hôtes (et le système LFS final) la limite stricte
est infinie par défaut, mais il n'y a pas d'inconvénient à
l'indiquer explicitement. Il n'est pas nécessaire de limiter la
limite non stricte car GCC la configurera à une valeur appropriée,
tant que cette valeur ne dépasse pas la limite stricte :
ulimit -s -H unlimited
Maintenant, supprimez ou corrigez plusieurs échecs aux tests
connus :
sed -e '/cpython/d' -i ../gcc/testsuite/gcc.dg/plugin/plugin.exp
sed -e 's/no-pic /&-no-pie /' -i ../gcc/testsuite/gcc.target/i386/pr113689-1.c
sed -e 's/300000/(1|300000)/' -i ../libgomp/testsuite/libgomp.c-c++-common/pr109062.c
sed -e 's/{ target nonpic } //' \
-e '/GOTPCREL/d' -i ../gcc/testsuite/gcc.target/i386/fentryname3.c
Testez les résultats en tant qu'utilisateur non privilégié, mais ne
vous arrêtez pas aux erreurs :
chown -R 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/12.2/
et https://gcc.gnu.org/ml/gcc-testresults/.
Quelques échecs inattendus sont parfois inévitables. Dans certains
cas les échecs des tests dépendent du matériel spécifique du
système. 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)/14.2.0/include{,-fixed}
Créez un lien symbolique requis par le FHS
pour des raisons « historiques ».
ln -svr /usr/bin/cpp /usr/lib
Beaucoup de paquets utilisent le nom cc pour appeler le compilateur C.
Nous avons déjà créé cc comme un lien symbolique dans
gcc-pass2, créez également sa
page de manuel avec un lien symbolique :
ln -sv gcc.1 /usr/share/man/man1/cc.1
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)/14.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/14.2.0/../../../../lib/Scrt1.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/14.2.0/../../../../lib/crti.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/14.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/14.2.0/include
/usr/local/include
/usr/lib/gcc/x86_64-pc-linux-gnu/14.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, cela signifie que quelque chose s'est
vraiment mal passé. Enquêtez et répétez les étapes pour trouver où
les problèmes se trouvent et corrigez-les. 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