8.30. GCC-16.1.0

Le paquet GCC contient la collection de compilateurs GNU, laquelle contient les compilateurs C et C++.

Temps de construction approximatif: 45 SBU (avec les tests)
Espace disque requis: 6,6 Go

8.30.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        \
             --enable-targets=all     \
             --disable-multilib       \
             --disable-bootstrap      \
             --disable-fixincludes    \
             --with-system-zlib

We only enable C and C++ here to save the build time as no packages in LFS and BLFS require GCC to compile other languages. Append algol68 for Algol 68, fortran for Fortran, go for Go, objc for Objective C, obj-c++ for Objective C++, and/or m2 for Modula 2 into the value of --enable-languages option if you want to compile programs in one or more of those languages with GCC.

GCC also supports the Ada, COBOL, and D languages. But that would require some dependencies which are not available in the base LFS system and would exceed the scope of this book. Read the upstream documentation for details.

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

Par défaut, le système de construction de GCC va le bootstrapper en trois étapes à moins qu'il ne soit construit en tant que compilateur croisé ou qu'il soit compilé de manière croisée. Le processus de bootstrap est requis pour la robustesse, surtout quand on met à jour GCC vers une nouvelle version. Dans LFS nous utilisons une méthode différente pour bootstrapper GCC (comme introduit dans le Remarques techniques sur la chaîne de compilation), donc nous n'avons pas besoin du processus de bootstrap fourni par le système de construction et nous le désactivons ici pour réduire considérablement le temps de construction. Supprimez cette option si vous mettez à jour GCC sur un système LFS complet (au lieu de construire une nouvelle LFS).

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

--enable-targets=all

Ce paramètre dit à GCC d'activer la prise en charge de la génération du code 64 bits même lorsqu'on construit pour un système 32 bits. Cela est requis pour construire GRUB pour UEFI 64 bits. Ce paramètre n'a pas d'effet lorsqu'on construit pour un système 64 bits.

[Note]

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]

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

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

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

Parmi les tests gcc.target/i386, les tests nommés auto-init-padding-9.c builtin-memmove-*.c, mem{cpy,set}-pr120683-*.c, pr111657-1.c, pr115102.c, pr116896.c, pr120881-2a.c et pr122343-4a.c, sont connus pour échouer. Le test nommé shift-gf2p8affine-2.c est connu pour échouer si le processeur ne prend pas AVX512 en charge.

Parmi les tests g++.target/i386, les tests nommés memset-pr108585-1{a,b}.C, mv{,c}-symbols*.C, pr112824-2.C et pr116896-1.C sont connus pour échouer.

De plus, les tests gcc.dg/ipa/pr122458.c, gcc.dg/lto/toplevel-*-asm-* et gcc.dg/plugin/crash-test-nested-*.c sont connus pour échouer. Le test g++.dg/gomp/deprecate-1.C est connu pour parfois échouer.

Les auteurs de LFS ont vérifiés ces échecs et confirmé qu'aucun n'indique de problème critique. La plupart sont causés par le fait que les auteurs des cas de test n'ont pas prévu l'utilisation de --enable-default-ssp ou --enable-default-pie.

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 $(gcc -print-file-name=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 -sfvr $(gcc -print-prog-name=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(){}' | cc -x c - -v -Wl,--verbose &> dummy.log
readelf -l a.out | grep ': /lib'

Il ne devrait pas y avoir d'erreurs et la sortie de la dernière commande aura cette forme (en permettant au nom de l'éditeur des liens de différer en fonction de la plateforme) :

[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/16.1.0/../../../../lib/Scrt1.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.0/../../../../lib/crti.o succeeded
/usr/lib/gcc/x86_64-pc-linux-gnu/16.1.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/16.1.0/include
 /usr/local/include
 /usr/lib/gcc/x86_64-pc-linux-gnu/16.1.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 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

8.30.2. Contenu de GCC

Programmes installés: c++, cc (lien vers gcc), cpp, g++, gcc, gcc-ar, gcc-nm, gcc-ranlib, gcov, gcov-dump, gcov-tool et lto-dump
Bibliothèques installées: libasan.{a,so}, libatomic.{a,so}, libcc1.so, libgcc.a, libgcc_eh.a, libgcc_s.so, libgcov.a, libgomp.{a,so}, libhwasan.{a,so}, libitm.{a,so}, liblsan.{a,so}, liblto_plugin.so, libquadmath.{a,so}, libssp.{a,so}, libssp_nonshared.a, libstdc++.{a,so}, libstdc++exp.a, libstdc++fs.a, libsupc++.a, libtsan.{a,so} et libubsan.{a,so}
Répertoires installés: /usr/include/c++, /usr/lib/gcc, /usr/libexec/gcc et /usr/share/gcc-16.1.0

Descriptions courtes

c++

Le compilateur C++

cc

Le compilateur C

cpp

Le pré-processeur C est utilisé par le compilateur pour l'extension des instructions #include, #define et d'autres instructions similaires dans les fichiers source

g++

Le compilateur C++

gcc

Le compilateur C

gcc-ar

Une enveloppe autour de ar qui ajoute un greffon à la ligne de commande. Ce programme n'est utilisé que pour ajouter « l'optimisation à l'édition des liens » et il n'est pas utile avec les options de construction par défaut.

gcc-nm

Une enveloppe autour de nm qui ajoute un greffon à la ligne de commande. Ce programme n'est utilisé que pour ajouter « l'optimisation à l'édition des liens » et il n'est pas utile avec les options de construction par défaut.

gcc-ranlib

Une enveloppe autour de ranlib qui ajoute un greffon à la ligne de commande. Ce programme n'est utilisé que pour ajouter « l'optimisation à l'édition des liens » et il n'est pas utile avec les options de construction par défaut.

gcov

Un outil de tests, qui est utilisé pour analyser les programmes et savoir où des optimisations seraient suivies du plus d'effets

gcov-dump

Outil d'affichage de profil gcda et gcno hors-ligne

gcov-tool

Outil de traitement de profils gcda hors-ligne

lto-dump

Outil pour afficher les fichiers objets produits par GCC quand LTO est activé

libasan

La bibliothèque de vérification des adresses à l'exécution

libatomic

Bibliothèque d'exécution intégrée pour les opérations atomiques de GCC

libcc1

Une bibliothèque qui permet à GDB d'utiliser GCC

libgcc

Contient la prise en charge de gcc à l'exécution

libgcov

Cette bibliothèque est liée à un programme si GCC active le profilage

libgomp

L'implémentation GNU de l'API OpenMP API pour la programmation en mémoire parallèle partagée sur plusieurs plateformes en C/C++ et Fortran

libhwasan

La bibliothèque de vérification des adresses à assistance matérielle à l'exécution

libitm

La bibliothèque mémoire transactionnelle de GNU

liblsan

La bibliothèque de vérification de fuites à l'exécution

liblto_plugin

Le greffon LTO de GCC permet à Binutils de traiter les fichiers objets créés par GCC quand LTO est activé

libquadmath

API de la bibliothèque mathématique en quadruple précision de GCC

libssp

Contient des routines qui prennent en charge la fonctionnalité de protection de GCC contre les débordement de pile. Normalement elle n'est pas utilisée car glibc fournit aussi ces routines.

libstdc++

La bibliothèque C++ standard

libstdc++exp

Bibliothèque de contrats C++ expérimentale

libstdc++fs

Bibliothèque de systèmes de fichiers ISO/IEC TS 18822:2015

libsupc++

Fournit des routines de prise en charge du langage de programmation C++

libtsan

La bibliothèque de vérification des threads à l'exécution

libubsan

La bibliothèque de vérification des comportements non définis à l'exécution