Zuerst packen wir wieder aus:
tar -xjf pakete/gcc-4.6.2.tar.bz2 && cd gcc-4.6.2/
und dazu kommt gleich einmal eine Reparatur:
patch -Np1 -i ../patches/gcc-4.6.2-startfiles_fix-1.patch
Warum? Der GCC nach 4.3 verhält sich wie ein verirrter Kompiler und sucht daher nicht mehr dort nach den Startdateien, die dort mit dem --prefix angegeben sind. Jetzt wäre das nicht mehr hilfreich und so wird GCC zu einem ordentlichen Verhalten angehalten.
Normalerweise wird mit dem Skript fixincludes versucht, eventuelle defekte Dateien für GCC zu reparieren. Wir haben bereits ein installiertes GCC, Glibc und die dazugehörigen Dateien sind soweit mit dem Vermerk fehlerfrei versehen und ein fixincludes wäre nicht sinnvoll. Ja ein neuer Durchgang wäre nicht nur nicht hilfreich, sondern schon genau deswegen schlecht, könnten doch dabei Dateien des Muttersystems wieder einbezogen werden. In jedem Fall bewahrt uns das Folgende vor genau diesen Gefahren:
cp -v gcc/Makefile.in{,.orig} && sed 's@\./fixinc\.sh@-c true@' gcc/Makefile.in.orig > gcc/Makefile.in
Bei Architekturen der Art x86 wird ein Bau der Art bootstrap mit der Marke -fomit-frame-pointer beim Compiler verwendet. Ohne bootstrap wird das aber verschluckt und wollen wir trotzdem diese Marke (flag) und genau einen Compiler, als ob der wie einer mit bootstrap wäre, hilft folgender Befehl:
cp -v gcc/Makefile.in{,.tmp} && sed 's/^T_CFLAGS =$/& -fomit-frame-pointer/' gcc/Makefile.in.tmp > gcc/Makefile.in
Mit der folgenden Befehlsfolge wird für GCC der Ort des
voreingestellten dynamischen Linkers dahin gehend geändert, dass
nur mehr der in /tools
verwendet
wird. Auch wird der Weg /usr/include
aus dem Verzeichnis der Pfade gestrichen, die GCC beim Suchen
verwendet. Und jetzt wird beim Bau von GCC genau unser neuer Linker
beim Kompilieren eingeprägt und ab sofort kennen alle übersetzten
Programme nur mehr die Verbindung zu unserer neuen Glibc.
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
Wir analysieren ein wenig: Finden wir zuerst noch alle Dateien im
Verzeichnis gcc/config
mit den Namen
linux.h
, respektive linux64.h
und sysv4.h
, kopieren wir die mit der Endung
„.orig“ beiseite. Dann
stellt sed vor jede
Datei /tools
vor allen in
/lib/ld
und beim folgenden Durchgang
noch einmal ein /usr
davor. Dann
werden an das Ende sowohl die Suchpfade, als auch für die
Startdatei neu geschrieben. Mit cp
-u werden die Originaldateien davor bewahrt,
versehentlich umgeschrieben zu werden.
Wieder kommen die folgenden Pakete dazu:
tar -xjf ../pakete/mpfr-3.1.0.tar.bz2 && mv -v mpfr-3.1.0 mpfr && tar -xjf ../pakete/gmp-5.0.2.tar.bz2 && mv -v gmp-5.0.2 gmp && tar -xzf ../pakete/mpc-0.9.tar.gz && mv -v mpc-0.9 mpc
Erneut legen wir das separate Buildverzeichnis an:
mkdir -v ../gcc-build && cd ../gcc-build
Noch einmal und ganz wichtig, wir ändern die Umgebungsvariablen dahingehend, dass sie nicht die Optimierungsmarken zerstören:
CC="$MOLLI_TGT-gcc -B/tools/lib/" \ AR=$MOLLI_TGT-ar RANLIB=$MOLLI_TGT-ranlib \ ../gcc-4.6.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-multilib \ --disable-bootstrap --disable-libgomp \ --without-ppl --without-cloog \ --with-mpfr-include=$MOLLI/sources/gcc-4.6.2/mpfr/src \ --with-mpfr-lib=$MOLLI/sources/gcc-build/mpfr/src/.libs
Ein wenig Erklärung auch dazu, soweit noch notwendig:
--enable-clocale=gnu
Damit sollte das einzig wahre locale für die C++ Bibliotheken garantiert werden. Steht da vielleicht kein de_DE, dann kann es ein Problem geben bei nicht passenden Application Binary Interface (ABI) C++ Bibliotheken, die dann nicht recht zusammenarbeiten wollen.
--enable-threads=posix
Damit können die Ausnahmen für C++ und dabei möglichen mehrfach aufgereihten Programmabläufen Platz greifen.
--enable-__cxa_atexit
damit kann man __cxa_atexit
statt nur atexit
zur Merken von
C++ destructors bei lokalen Statistiken und globalen Objekten
nutzen und das brauchen die eben für die mitverwendeten C++
Bibliotheken und C++ Programmen wie auch für Application
Binary Interface (ABI) und Anwendungen auch anderer Linux
Versionen.
--enable-languages=c,c++
Jetzt endlich kann auch C++ übersetzt werden.
--disable-libstdcxx-pch
Vorgefertigte Dateien (header) sollen nicht verwendet werden. Die sind nutzlos und auch Platzverschwendung.
--disable-bootstrap
GCC ist berufen, mit bootstrap zu arbeiten. Jetzt wird aber GCC beim Bau nicht nur ein einziges Mal durchlaufen, sondern drei Mal, und auch wenn bei den weiteren Durchgängen eher nur mehr auf flüssigen Durchgang Wert gelegt wird, ein bootstrap ist dabei nicht unbedingt notwendig.
Das Paket kompilieren:
make
Nun installieren:
make install
Es wird noch eine weiche Anknüpfung notwendig, weil immer noch Programme cc statt gcc haben wollen, wie auch UNIX. Auch manche Administratoren sind versucht, das zu verwenden:
ln -vs gcc /tools/bin/cc
Nun verlassen wir das Verzeichnis und löschen es:
cd .. && rm -rf gcc-*
an diesem Punkt ist es absolut wichtig unseren neuen Kompiler zu testen:
echo 'main(){}' > dummy.c && cc dummy.c && readelf -l a.out | grep ': /tools'
Das Ergebnis sollte wieder folgendes sein:
[Requesting program interpreter: /tools/lib/ld-linux.so.2]
Bei einem 64bit System sollte es dies sein:
[Requesting program interpreter: /tools/lib/ld-linux-x86-64.so.2]
Vor den dynamischen Linkern soll noch /tools/lib
stehen, gibt es auch da wieder anders
lautende Ergebnisse oder gar keine, ist da das Ende, bis der Fehler
gefunden ist. Gerne schleichen sich Fehler bei Pfaden ein,
Kontrolle echo $PATH,
bei der weichen Anbindung „ln“, wenn man nicht als Benutzer molli
arbeitet und bei dessen Umgebung und erst wenn alle Fehler
beseitigt sind, mache man das:
rm -v dummy.c a.out