Upgrading GCC/de

Dieses Dokument Article description::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,, 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 durchführen.

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

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

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
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 verwendeten Skripte hartcodierte -Versionsinformationen.

ABI-Änderungen
Die ABI, also das "Application Binary Interface" (auch Binärschnittstelle), ist ein Satz von Konventionen, der von allen Werkzeugen benutzt wird, die mit binären Repräsentationen von Programmen arbeiten, also beispielsweise Compilern, Assemblern, Linkern und der 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, es sei denn, alle Bibliotheken werden neu kompiliert, die C++-Code benutzen.

Ja, C++, denn die meisten Inkompatibilitäten kommen in der C++-ABI vor. Wird auf GCC 4.1 oder GCC 5.1 aktualisiert, so ist mit ABI-Problemen zu rechnen. Um dies zu verhindern, sollte der Befehl gegen die Bibliothek  ausgeführt werden, wenn von GCC 3 auf GCC 4.1 aktualisiert wird, bzw. , wenn von GCC 4 auf GCC 5.1 aktualisiert wird.

Warum ist dies nur für bis zu den Versionen GCC 4.1/5.1 erforderlich? Das liegt daran, dass GCC ab dieser Version eine vorwärtskompatible API 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 wenn es erneut zu einer Inkompatibilität kommen sollte, wird diese hier dokumentiert und auch ein zugehöriges News Item wird herausgegeben. In diesem Fall wird die Version von 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:


 * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61758
 * https://blogs.gentoo.org/blueness/2015/03/10/the-c11-abi-incompatibility-problem-in-gentoo/
 * https://stackoverflow.com/questions/16190269/g-always-backward-compatible-with-older-static-libraries/16196475#16196475
 * https://stackoverflow.com/questions/16190269/g-always-backward-compatible-with-older-static-libraries/16196475#16196475

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.

Einige Gruppen von Paketen müssen mit demselben Compiler gebaut worden sein (beispielsweise die verschiedenen -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   in emerge, um erst das System-Set und anschließend das World-Set neuzukompilieren:

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.)

Neu-Kompilierung von Boost
Wenn das Paket neu kompiliert werden muss, ist das an den folgenden Fehlermeldungen erkennbar:

Die Neu-Kompilierung kann folgendermaßen gestartet werden:

libstdc++.so.6: version `GLIBCXX_3.4.15' not found
Während einer Paketinstallation kann der folgende Fehler auftreten:

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 oben befolgt werden.

Weiterführende Informationen

 * Upgrading GCC up to 4.1, die vorherige Version dieses Dokuments
 * Upgrading frmo gcc-4.x to gcc-5.x
 * Fedora's 'Änderungen/GCC6' Wiki-Seite