5.12. GCC-4.3.2 - Durchlauf 2

Das Paket GCC enthält die GNU-Compiler-Sammlung. Darin sind die C- und C++-Compiler enthalten.

Geschätzte Kompilierzeit: 6.5 SBU
Etwa Benötigter Speicherplatz: 865 MB

5.12.1. Neuinstallation von GCC

Die Hilfsmittel zum Testen von GCC und Binutils sind nun installiert (Tcl, Expect und DejaGNU). Sie können GCC und Binutils nun erneut installieren, gegen die neue Glibc verlinken und testen. Eines muss noch beachtet werden: Die Testsuites sind stark von funktionierenden Pseudo-Terminals (PTYs) abhängig. Diese werden vom Host-System bereitgestellt. Heutzutage werden PTYs meist über das Dateisystem devpts implementiert. Ob Ihr Host-System korrekt eingerichtet ist, können Sie mit einem einfachen Test feststellen:

expect -c "spawn ls"

Das Ergebnis könnte so aussehen:

The system has no more ptys.
Ask your system administrator to create more.

Wenn Sie die obige Meldung sehen, ist Ihr Host-System nicht korrekt für PTYs eingerichtet. Solange Sie dieses Problem nicht behoben haben, brauchen Sie die Testsuites von GCC und Binutils gar nicht erst durchlaufen lassen. Wenn Sie mehr Informationen zum Einrichten von PTYs brauchen, schauen Sie am besten in die LFS-FAQ unter http://www.linuxfromscratch.org//lfs/faq.html#no-ptys.

In Abschnitt 5.8, „Anpassen der Toolchain“ wurde bereits erklärt, dass GCC unter normalen Umständen sein fixincludes-Skript laufen lässt, um defekte Header-Dateien aufzufinden und zu reparieren. Da an diesem Punkt GCC-4.3.2 und Glibc-2.8-20080929 bereits installiert sind und deren Header-Dateien definitiv nicht repariert werden müssen, wird das fixincludes-Skript eigentlich nicht benötigt. Wie bereits erwähnt, könnte es sogar den negativen Nebeneffekt haben, Header-Dateien vom Host-System in das LFS-System einzuschleusen. Mit dem folgenden Kommando können Sie das Ausführen des fixincludes-Skriptes verhindern:

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

Im Bootstrap-Durchlauf aus Abschnitt 5.5, „GCC-4.3.2 - Durchlauf 1“ wurde zum Kompilieren von GCC der Compiler-Parameter -fomit-frame-pointer verwendet. Der Nicht-Bootstrap-Durchlauf verwendet diesen Parameter jedoch standardmäßig nicht. Um die Kompilier-Durchläufe von GCC konsistent zu halten, sollten Sie den Parameter für diesen Durchlauf mit dem folgenden sed-Kommando einschalten:

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

Der folgende Befehl ändert den Pfad zu GCCs dynamischen Linker so ab, dass die Version verwendet wird, die wir in /tools installiert haben. Er entfernt /usr/include aus dem Include-Suchpfad von GCC. Die Änderung an dieser Stelle anstatt des nachträglichen Anpassens der specs-Datei stellt sicher, dass beim Kompilieren von GCC der neue dynamische Linker verwendet wird. Dies bedeutet, dass alle Binärdateien beim Kompiliervorgang gegen die neue Glibc gelinkt werden. Führen Sie nun diesen Befehl aus:

for file in $(find gcc/config -name linux64.h -o -name linux.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" >> $file
  touch $file.orig
done

Falls der obige Befehl etwas zu unübersichtlich scheint, hier folgt die Erklärung dazu: Zuerst werden unter gcc/config alle Dateien namens linux.h oder linux64.h gesucht. Für jede gefundene Datei wird eine Sicherungskopie mit dem Suffix „.orig“ angelegt. Das erste sed-Kommando stellt die Zeichenkette „/tools“ allen Fundstellen von „/lib/ld“, „/lib64/ld“ oder „/lib32/ld“ voran. Das zweite sed-Kommando ersetzt hart einkodierte Vorkommen von „/usr“. Danach werden am Ende der Datei die define-Anweisungen angefügt, die den Suchpfad für Include-Dateien anpassen. Zuguterletzt wird mittels touch der Zeitstempel der kopierten Dateien aktualisiert. Wenn dies zusammen mit cp -u verwendet wird, wird unerwarteten Änderungen an den Originaldateien vorgebeugt, falls der Befehl versehentlich mehrmals ausgeführt wird.

Wie auch schon im ersten Durchlauf von GCC werden die Pakete GMP und MPFR benötigt. Entpackten Sie die Pakete und verschieben Sie sie in die vorgeschriebenen Ordner:

tar -jxf ../mpfr-2.3.2.tar.bz2
mv mpfr-2.3.2 mpfr
tar -jxf ../gmp-4.2.4.tar.bz2
mv gmp-4.2.4 gmp

Erstellen Sie erneut einen eigenen Ordner zum Kompilieren:

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

Denken Sie daran, vor dem Kompilieren von GCC alle Umgebungsvariablen zurückzusetzen, die die Standard-Optimierungen überschreiben würden.

Bereiten Sie GCC zum Kompilieren vor:

../gcc-4.3.2/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-bootstrap

Die Bedeutung der neuen Parameter zu configure:

--enable-clocale=gnu

Dieser Parameter stellt sicher, dass unter allen Umständen das korrekte locale-Modell für die C++ Bibliotheken ausgewählt wird. Falls das configure-Skript de_DE Locales findet, wird es das korrekte Modell gnu wählen. Falls aber de_DE nicht installiert ist, besteht das Risiko, dass aufgrund des fälschlicherweise ausgewählten Modells generic ABI-inkompatible C++-Bibliotheken erstellt werden.

--enable-threads=posix

Das schaltet die Behandlung von C++-Exceptions für Code mit Threads ein.

--enable-__cxa_atexit

Dieser Parameter ermöglicht die Verwendung von __cxa_atexit anstelle von atexit, um C++-Destruktoren für lokale Statics und globale Objekte zu registrieren. Außerdem ist die Option für eine vollständig standardkonforme Behandlung von Destruktoren erforderlich. Das beeinflusst auch die C++ ABI; das Ergebnis sind gemeinsame C++-Bibliotheken und C++-Programme die interoperabel mit anderen Linux-Distributionen sind.

--enable-languages=c,c++

Dieser Parameter stellt sicher, dass sowohl der C- als auch der C++-Compiler erzeugt werden.

--disable-libstdcxx-pch

Verhindert das Erzeugen der vorkompilierten Header-Dateien (PCH, pre-compiled header) für libstdc++. Diese Funktion verbraucht viel Platz und wir benötigen sie nicht.

--disable-bootstrap

Das Bootstrapping des Compilers ist nun die Voreinstellung von GCC. Unsere Installationsmethode sollte jedoch einen stabilen Compiler hervorbringen, ohne dass ein Bootstrapping jedesmal vonnöten ist.

Kompilieren Sie das Paket:

make

Der Kompiliervorgang ist nun abgeschlossen. Wie bereits erwähnt, empfehlen wir, die Testsuite für das temporäre System in diesem Kapitel nicht durchlaufen zu lassen. Falls Sie die Testsuite dennoch laufen lassen möchten, führen Sie dieses Kommando aus:

make -k check

Der Parameter -k lässt die Testsuite bis zum Ende durchlaufen, selbst, wenn Fehler auftreten sollten. Die Testsuite von GCC ist sehr umfangreich und es ist beinahe sicher, dass Fehler auftreten.

Eine Information über die kritischen Fehler finden Sie im Abschnitt 6.14, „GCC-4.3.2“

Installieren Sie das Paket:

make install
[Achtung]

Achtung

An diesem Punkt ist es unbedingt notwendig, die korrekte Funktion der Toolchain (Kompilieren und Linken) zu überprüfen. Darum führen Sie nun einen kleinen „Gesundheitscheck“ durch:

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

Wenn alles korrekt funktioniert, sollten keine Fehler auftreten und die Ausgabe des letzten Kommandos sieht so oder so ähnlich aus:

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

Achten Sie besonders darauf, dass /tools/lib als Prefix zu Ihrem dynamischen Linker angegeben ist.

Wenn Sie keine oder eine andere als die obige Ausgabe erhalten haben, ist etwas schiefgelaufen. Sie müssen alle Ihre Schritte noch einmal überprüfen und den Fehler finden und korrigieren. Fahren Sie nicht fort, bevor Sie den Fehler nicht beseitigt haben. Als erstes führen Sie nochmals den Gesundheitscheck durch und benutzen gcc anstelle von cc. Wenn das funktioniert, fehlt der Link von /tools/bin/cc. Gehen Sie zurück zu Abschnitt 5.5, „GCC-4.3.2 - Durchlauf 1“ und reparieren Sie den symbolischen Link. Als zweites stellen Sie bitte sicher, dass Ihre Umgebungsvariable PATH richtig gesetzt ist. Sie können die Variable mit dem Kommando echo $PATH anzeigen lassen; prüfen Sie, dass /tools/bin am Anfang der Liste steht. Wenn die PATH Variable falsch gesetzt ist, sind Sie möglicherweise nicht als lfs eingeloggt oder in Abschnitt 4.4, „Vorbereiten der Arbeitsumgebung“ ist etwas schiefgelaufen. Vielleicht hat auch beim Anpassen der specs-Datei etwas nicht richtig funktioniert. In diesem Fall wiederholen Sie die Anpassung und benutzen Sie Kopieren und Einfügen, um das Kommando auszuführen, tippen Sie es nicht ab.

Wenn Sie mit dem Ergebnis zufrieden sind, räumen Sie auf:

rm -v dummy.c a.out

Details zu diesem Paket finden Sie in Abschnitt 6.14.2, „Inhalt von GCC“