5.10. GCC-4.5.3 - Passe 2

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

Temps aproximatif de construction: 9.0 SBU
Espace disque requis: 1003 Mio

5.10.1. Installation de GCC

Les versions de GCC supérieures à 4.3 vont gérer cette construction comme si C était un compilateur placé à un nouvel endroit et interdire la recherche de fichiers de démarrage (startfiles) dans l'emplacement spécifié par --prefix. Comme ce ne sera pas un compilateur placé à un nouvel endroit, et vu que les fichiers de démarrage dans /tools sont cruciaux pour la construction d'un compilateur fonctionnel liés aux libs dans /tools, appliquez le correctif suivant qui ramène partiellement GCC vers son ancien comportement :

patch -Np1 -i ../gcc-4.5.3-startfiles_fix-1.patch

Dans des circonstances normales, le script fixincludes de GCC est exécuté afin de réparer des fichiers d'en-tête potentiellement cassés. Comme GCC-4.5.3 et Glibc-2.12.2 ont désormais déjà été installés, et vu que leur fichiers d'en-têtes respectifs sont connus comme n'ayant pas besoin de réparation, le script fixincludes n'est pas utile. En fait, il se peut que le script pollue l'environnement de construction en installant des en-têtes corrigées du système hôte dans le répertoire autonome include de GCC. L'exécution du script fixincludes peut être supprimée en lançant les commandes suivantes :

cp -v gcc/Makefile.in{,.orig}
sed 's@\./fixinc\.sh@-c true@' gcc/Makefile.in.orig > gcc/Makefile.in

Pour les machines x86, une construction bootstrap de GCC utilise le drapeau -fomit-frame-pointer du compilateur. Les constructions non-bootstrap suppriment ce drapeau par défaut, l'objectif serait d'obtenir un compilateur qui est exactement le même que si nous étions bootstrapés. Appliquez la commande sed suivante pour obliger la construction à utiliser le drapeau :

cp -v gcc/Makefile.in{,.tmp}
sed 's/^T_CFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.in.tmp \
  > gcc/Makefile.in

La commande suivante modifiera l'emplacement par défaut de l'éditeur de lien dynamique de GCC pour utiliser celui installé dans /tools. Il supprime aussi /usr/include du chemin de recherche des en-têtes de GCC.

Faire cela maintenant plutôt qu'ajuster le fichier specs après l'installation nous assure que l'éditeur de liens dynamiques sera utilisé lors de la construction de GCC. C'est-à-dire que tous les exécutables créés lors de la construction seront liés à la nouvelle Glibc. Lancez :

for file in \
 $(find gcc/config -name linux64.h -o -name linux.h -o -name sysv4.h)
do
   cp -uv $file{,.orig}
   sed -e 's@/lib\(64\)\?\(32\)\?/ld@/tools&@g' \
   -e 's@/usr@/tools@g' $file.orig > $file
   echo '
#undef STANDARD_INCLUDE_DIR
#define STANDARD_INCLUDE_DIR 0
#define STANDARD_STARTFILE_PREFIX_1 ""
#define STANDARD_STARTFILE_PREFIX_2 ""' >> $file
   touch $file.orig
done

Si ce qui précède vous semble dur à suivre, décomposons-le un peu. D'abord, nous trouvons tous les fichiers sous le répertoire gcc/config qui sont nommés linux.h ou linux64.h. Pour chaque fichier trouvé, nous le copions vers un fichier du même nom mais avec en plus le suffixe « .orig ». Puis la première expression sed préfixe chaque occurrence de « /lib/ld », « /lib64/ld » ou « /lib32/ld » par « /tools », tandis que la deuxième remplace les occurrences de « /usr » codées en dur. Nous ajoutons alors nos déclarations define qui modifient le chemin de recherche et le préfixe du fichier de démarrage par défaut à la fin du fichier. Enfin, nous utilisons touch pour mettre à jour l'horodatage des fichiers copiés. Utilisé conjointement avec cp -u, cela empêche les modifications inattendues des fichiers d'origine au cas où les commandes seraient exécutées deux fois par inadvertence.

En x86_64, le déparamétrage du spec multilib (multibibliothèque) pour GCC assure qu'il ne s'efforcera pas de se lier aux bibliothèque sur le système hôte :

case $(uname -m) in
  x86_64)
    for file in $(find gcc/config -name t-linux64) ; do \
      cp -v $file{,.orig}
      sed '/MULTILIB_OSDIRNAMES/d' $file.orig > $file
    done
  ;;
esac

Corrigez GCC pour ajouter -D_FORTIFY_SOURCE=2, -fPIE -pie, -fstack-protector-all, et --param=ssp-buffer-size=4 par défaut :

patch -Np1 -i ../gcc-4.5.3-fortify_source-1.patch
patch -Np1 -i ../gcc-4.5.3-fpie-1.patch
patch -Np1 -i ../gcc-4.5.3-fstack_protector-1.patch

Comme dans la première construction de GCC, il a besoin de GMP, de MPFR et MPC. Déballez les archives tar et déplacez-les dans les répertoires nommés comme il le faut :

tar -jxf ../mpfr-3.0.0.tar.bz2 
mv -v mpfr-3.0.0 mpfr
tar -jxf ../gmp-5.0.2.tar.bz2
mv -v gmp-5.0.2 gmp
tar -zxf ../mpc-0.8.2.tar.gz
mv -v mpc-0.8.2 mpc

De nouveau, créez un répertoire de construction séparé :

mkdir -v ../gcc-build
cd ../gcc-build

Avant de commencer la construction de GCC, rappelez-vous de désinitialiser toute variable d'environnement surchargeant les options d'optimisation par défaut.

Maintenant, préparez la compilation de GCC :

CC="$LFS_TGT-gcc -B/tools/lib/" \
    AR=$LFS_TGT-ar RANLIB=$LFS_TGT-ranlib \
        ../gcc-4.5.3/configure --prefix=/tools \
    --with-local-prefix=/tools --enable-clocale=gnu \
    --enable-shared --enable-threads=posix \
    --enable-__cxa_atexit --enable-languages=c,c++ \
    --disable-libstdcxx-pch --disable-multilib \
    --disable-bootstrap --disable-libgomp \
    --with-gmp-include=$(pwd)/gmp --with-gmp-lib=$(pwd)/gmp/.libs \
    --without-ppl --without-cloog

Voici la signification des nouvelles options de configure :

--enable-clocale=gnu

Cette option nous assure que le bon modèle de locale est sélectionné pour les bibliothèques C++ sous toutes les circonstances. Si le script configure trouve la locale de_DE installée, il sélectionnera le bon modèle de locale gnu. Néanmoins, si la locale de_DE n'est pas installée, il existe un risque de construire des bibliothèques C++ incompatibles avec ABI (Application Binary Interface) à cause du choix d'un mauvais modèle générique de locale.

--enable-threads=posix

Ceci active la gestion des exceptions C++ pour le code multi-threadé.

--enable-__cxa_atexit

Cette option autorise l'utilisation de __cxa_atexit, plutôt que atexit, pour enregistrer les destructeurs C++ des objets statiques locaux et globaux. Cette option est essentielle pour la gestion des destructeurs en compatibilité complète avec les standards. Il affecte aussi l'ABI C++ et donc résulte en des bibliothèques partagées et des programmes C++ interopérables avec les autres distributions Linux.

--enable-languages=c,c++

Cette option garantie que les compilateurs C et C++ seront construits.

--disable-libstdcxx-pch

Ce commutateur empêche la construction de l'en-tête précompilé (PCH) de libstdc++. Il prend beaucoup d'espace et nous n'en avons aucune utilité.

--disable-bootstrap

Pour les constructions natives de GCC, on a par défaut une compilation "bootstrap". Elle ne fait pas que compiler GCC, mais elle le compile plusieurs fois. Elle utilise les programmes compilés dans une première étape pour se compiler une seconde fois, puis une troisième fois à nouveau. Les deuxième et troisième passages sont comparés pour garantir qu'elle peut se reproduire facilement. Cela implique aussi qu'elle a été compilée correctement. Néanmoins, la méthode de compilation LFS devrait fournir un compilateur solide sans qu'il soit nécessaire de bootstraper chaque fois.

Compilez le paquet :

make

Installez le paquet :

make install

En touche finale, créez un lien symbolique. Beaucoup de programmes et de scripts lance cc au lieu de gcc, qui est utilisé pour conserver des programmes génériques, utilisables donc sur n'importe quel type de système où le compilateur C n'est pas toujours installé. L'exécution de cc laisse l'administrateur du système décider quel compilateur C installer :

ln -vs gcc /tools/bin/cc
[Attention]

Attention

A ce stade, il est impératif de s'arrêter et de s'assurer que les fonctions de base (compilation et édition de liens) du nouvel ensemble d'outils fonctionnent comme prévu. Pour effectuer un test de propreté, lancez les commandes suivantes :

echo 'main(){}' > dummy.c
cc dummy.c
readelf -l a.out | grep ': /tools'

Si tout fonctionne correctement, il ne devrait pas y avoir d'erreurs et la sortie de la dernière commande aura la forme :

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

Remarquez que /tools/lib ou /tools/lib64 pour les machines 64 bits apparaît comme préfixe de l'éditeur de liens dynamique.

Si l'affichage diffère ou s'il n'y a aucun affichage, alors quelque chose ne se passe pas bien. Enquêtez et tracez vos étapes pour trouver où se cache le problème et comment le corriger. Ce problème doit être corrigé avant de continuer. Tout d'abord, relancez la vérification de propreté en utilisant gcc au lieu de cc. Si cela fonctionne, le lien symbolique /tools/bin/cc est manquant. Installez le lien symbolique comme indiqué ci-dessus. Ensuite, assurez-vous que le PATH est correct. Ceci se vérifie en lançant echo $PATH et en vérifiant que /tools/bin est en tête de la liste. Si le PATH est mauvais, cela pourrait signifier que vous n'êtes pas connecté en tant qu'utilisateur lfs ou que quelque chose s'est mal passé dans Section 4.4, « Configurer l'environnement. ».

Une fois que tout va bien, nettoyez les fichiers de test ::

rm -v dummy.c a.out

Les détails sur ce paquet sont situés dans Section 6.16.2, « Contenu de GCC. »