8.29. GCC-14.2.0

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

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

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]

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

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

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