GCC Aktualisieren

From Gentoo Wiki
Jump to:navigation Jump to:search
This page is a translated version of the page Upgrading GCC and the translation is 100% complete.
Other languages:
Deutsch • ‎English • ‎español • ‎italiano • ‎русский • ‎中文(中国大陆)‎ • ‎日本語 • ‎한국어

Dieses Dokument beschreibt den Prozess der Aktualisierung auf neuere Versionen von GCC.

Es ist zu beachten, dass das Aktualisieren von GCC auf eine ältere Version zu ungewollten Seiteneffekten führen kann. Der Abschnitt zur Fehlerbehebung beschreibt einige häufig gemeldete Probleme.

Kurzfassung

Dieser Abschnitt beschreibt das Aktualisieren von GCC in Kurzfassung. Eine ausführliche Erklärung ist im nächsten Abschnitt, #GCC-Aktualisierung erklärt, zu finden.

Die meisten GCC-Aktualisierungen lassen sich einfach durch einen Wechsel der Compiler-Version (hier von 5.4.0 auf 6.4.0) und eine Neuinstallation von libtool durchführen.

root #emerge --ask --oneshot sys-devel/gcc
root #gcc-config --list-profiles
[1] x86_64-pc-linux-gnu-5.4.0 *
[2] x86_64-pc-linux-gnu-6.4.0
root #gcc-config 2
root #source /etc/profile
root #emerge --ask --oneshot --usepkg=n sys-devel/libtool
Notiz
Wird eine Aktualisierung von GCC 4.x auf GCC 5.x oder später durchgeführt, sind zusätzliche Schritte notwendig. Sie sind auf der Extraseite Upgrading from gcc-4.x to gcc-5.x beschrieben.

Nach einer Überprüfung der aktuellen Versionsnummer kann die alte Version deinstalliert werden:

root #gcc --version
root #emerge --ask --depclean =sys-devel/gcc-5.4.0

Anschließend sollte die Systemintegrität mittels revdep-rebuild verifiziert werden:

root #revdep-rebuild

Viel Spaß mit dem neuen Compiler!

GCC-Aktualisierung erklärt

Die Aktualisierung von GCC ist seit jeher ein verwirrendes Thema, für das Empfehlungen von "Benutzer müssen überhaupt nichts tun" bis hin zu "Benutzer müssen das gesamte System zweimal kompilieren" kursieren. Die Hauptursache dieser Angst und Unsicherheit ist ABI-Inkompatibilität, etwas, das heutzutage selten passiert (und wenn doch, dann wird es angekünfigt). Aber zunächst zu einem kurzen Hinweis zu libtool.

libtool

Die Tatsache, dass libtool nach einer GCC-Aktualisierung neu installiert werden muss, liegt in seinem Hauptanwendungszweck begründet: "libtool" ist Werkzeugkasten, der plattformspezifische Anweinsungen in einer generischen Schnittstelle aggregiert, gegen die Anwendungen dann gemeinsam genutzte Bibliotheken bauen können, ohne die plattformspezifischen Aspekte dieser berücksichtigen zu müssen. Um diese AUfgabe hinreichend zu erfüllen, enthalten die von libtool verwendeten Skripte hartcodierte gcc-Versionsinformationen.

ABI-Änderungen

Die ABI, also das Application Binary Interface, auch Binärschnittstelle genannt, ist ein Satz von Konventionen, der von allen Werkzeugen benutzt wird, die mit binären Repräsentationen von Programmen arbeiten. Dazu gehören beispielsweise Compiler, Assembler, Linker und die Laufzeitunterstützung von Sprachen (Quelle: GCC-Binärkompatibilität). Wenn die von binären Anwendungen und Bibliotheken benutzte ABI sich ändert, besteht das Risiko von Linker-Fehlern und Fehlfunktionen in Programmen. Dies kann verhindert werden, indem alle Bibliotheken, die C++-Code nutzen, neu kompiliert werden.

Dies gilt insbesondere für C++, da hier die meisten ABI-Inkompatbilitäten auftreten. Wird auf GCC 4.1 oder GCC 5.1 aktualisiert, so ist mit ABI-Problemen zu rechnen. Um dies zu verhindern, sollte der Befehl revdep-rebuild gegen die Bibliothek libstdc++.so.5 ausgeführt werden, wenn von GCC 3 auf GCC 4.1 aktualisiert wird. Dasselbe gilt für libstdc++.so.6, wenn von GCC 4 auf GCC 5.1 aktualisiert wird.

root #revdep-rebuild --library 'libstdc++.so.6' -- --exclude gcc

Warum ist dies nur für die Versionen GCC 4.1/5.1 erforderlich? Das liegt daran, dass GCC ab dieser Version eine vorwärtskompatible ABI benutzt, mit der das neukompilieren von Anwendungen und Bibliotheken nicht mehr nötig ist. Natürlich kann eine solche Garantie nicht für immer gelten, aber sollte es erneut zu einer Inkompatibilität kommen, so wird diese hier dokumentiert und auch ein zugehöriges News Item wird herausgegeben. In diesem Fall wird die Version von libstdc++.so vermutlich erhöht.

Der Sonderfall C++11 (und C++14)

Obwohl GCC (oder besser gesagt, libstdc++) sehr darum bemüht ist, die Stabilität der ABI aufrechtzuerhalten, bezieht sich dieses Versprechen nicht auf alle Teile von C++ in libstdc++. Früher, in Versionen ab 3.4, garantierten GCC und libstdc++ die ABI-Stabilität nur für C++98/C++03 und nicht mehr. Das ist entscheidend für Pakete, die von C++11 abhängen. GCC garantiert eine Stabilität der C++11-ABI nämlich erst ab Version 5.1. Das bedeutet, dass selbst ein Wechsel der Nebenversion von GCC (beispielsweise 4.7.3 -> 4.7.4) eine ABI-Inkompatibilität für Pakete verursachen kann, die aus C++11-Quelltext kompiliert werden.

Für weiterführende Inhalte und einige Beispiele, siehe:

Welche Pakete müssen neu kompiliert werden?

Die folgende Tabelle enthält Pakete, die, falls installiert, neu kompiliert müssen, und warum dies so ist.

Paket Neu-Kompilierung erforderlich, weil ...
sys-devel/libtool libtool enthält hardcodierte Pfade von internen GCC-Bibliotheken.
sys-devel/llvm hängt von der exakten GCC-Version ab, kann zu Linker-Fehlern führen, wenn es nicht neu kompiliert wird und für Ebuilds, die LLVM benutzen (z.B. media-libs/mesa), benutzt wird.
sys-devel/clang hängt von der exakten GCC-Version ab, könnten von sys-devel/llvm beeinflusst werden.
root #emerge --ask --oneshot --usepkg=n --verbose sys-devel/libtool sys-devel/llvm sys-devel/clang

Einige Gruppen von Paketen müssen mit demselben Compiler gebaut worden sein (beispielsweise die verschiedenen qt-*-Pakete). Solche Pakete werden von den Paket-Maintainern üblicherweise gleichzeitig aktualisiert, sodass sie immer mit derselben GCC-Version gebaut werden. Pakete aus einer solchen Gruppe selektiv neu zu kompilieren kann sich als problematisch erweisen.

Alles neu kompilieren

Einige Personen behaupten, dass eine Neu-Kompilierung des gesammten Systems nach einer GCC-Aktualisierung unerlässlich sei. Das ergibt natürlich keinen Sinn, da viele Anwendungen GCC gar nicht während der Kompilierung oder Installation einsetzen und somit niemals von solchen Änderungen betroffen wären.

Allerdings ist dies auch nicht völlig falsch: neuere GCC-Versionen beinhalten oftmals auch eine bessere Unterstützung für den Befehlssatz des Prozessors, was sich positiv auf die Leistung einiger Anwendungen auswirken kann.

Abseits von solchen "marginalen" Vorteilen, kann eine Neu-Kompilierung des gesamten Systems manchmal erforderlich sein, um bestimmte Probleme zu beheben, die keine offensichtliche Ursache haben.

Einige Software-Probleme sind grundsätzlich schwierig zu diagnostizieren und können dennoch einfach behoben werden, indem ein oder mehrere Pakete neu kompiliert werden. Wenn ein solches Problem nach einer GCC-Aktualisierung auftritt und nach einem Aufruf von revdep-rebuild bestehen bleibt, kann eine komplette Neu-Kompilierung des Systems die richtige Antwort sein.

Die "sicherste" (aber auch zeitaufwändigste) Herangehensweise ist Verwendung des Parameters --emptytree (-e) in emerge, um erst das System-Set und anschließend das World-Set neuzukompilieren:

root #emerge --ask --emptytree --usepkg=n @system
root #emerge --ask --emptytree --usepkg=n @world

Dies wird allen Benutzern empfohlen, bevor sie einen Fehler melden, der durch eine GCC-Aktualisierung hervorgerufen worden sein könnte.

(Es ist zu beachten, dass die obigen Befehle die Pakete im System-Set zweimal kompilieren, was erforderlich ist, um sich "absolut sicher" zu sein, dass jedes Paket in einer [vermutlich] "problemfreien" Umgebung kompiliert wird. Alle Probleme, die danach weiterbestehen, sind entweder durch "tatsächliche Fehler", die gemeldet werden sollten, oder durch eine fehlerhafte Systemkonfiguration, hervorgerufen worden.)

Fehlerbehebung

Neu-Kompilierung von Boost

Wenn das Paket dev-libs/boost neu kompiliert werden muss, ist das an den folgenden Fehlermeldungen erkennbar:

root #emerge ...
 
checking for the Boost _____ library... no
configure: error: cannot find the flags to link with Boost _____

Die Neu-Kompilierung kann folgendermaßen gestartet werden:

root #emerge --ask --oneshot --usepkg=n --verbose dev-libs/boost

libstdc++.so.6: version `GLIBCXX_3.4.15' not found

Während einer Paketinstallation kann der folgende Fehler auftreten:

CODE GLIBCXX_x.y.z not found
cmake_bootstrap_28021_test: /usr/lib/gcc/i486-pc-linux-gnu/4.1.2/libstdc++.so.6:
version `GLIBCXX_3.4.11' not found

Sie bedeutet, dass eine Kompilierung des Pakets mit einer "älteren" GCC-Version versucht wird, als die, mit der die Bibliotheken kompiliert wurden, von denen das Paket abhängt. Wie eingangs erwähnt, ist die C++-ABI nur vorwärtskompatibel. Sie garantiert also nur, dass dieselbe oder eine höhere GCC-Version zum Kompilieren von Anwendungen und Linken von Bibliotheken verwendet werden kann (im Vergleich zur GCC-Version, mit der diese Bibliotheken kompiliert wurden).

Um alle Pakete neuzukompilieren, die von libstdc++ abhängen, können die Anweisungen zu revdep-rebuild oben befolgt werden.

Weiterführende Informationen

Referenzen