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 36% complete.
Outdated translations are marked like this.

GCC upgrades should generally be handled gracefully with Portage and the usual Gentoo tools, see next section. If ever there are more involved updates that require user intervention, they should be accompanied by a corresponding news item, that should be read and followed.

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.

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

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

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.

See bug #88596.

ABI changes

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:

Downgrading GCC

For the aforementioned reasons, if downgrading GCC or choosing an older slot with gcc-config, it is necessary to run revdep-rebuild to catch libstdc++ consumers requiring newer symbols:

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

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.

Tipp
This isn't necessary but is described here so people know how to do it thoroughly if they desire.

Some people swear that they need to rebuild every single package on their system when a new GCC version is made available. Of course, that doesn't make sense, since there are many applications that are not using GCC for their build and install process anyhow, so they would never be affected by such changes.

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.

undefined reference to `__cxa_call_terminate@CXXABI_1.3.15'

This is usually a result of compiling a package that had its dependencies built with a newer GCC version than with the current one selected. An example output might be:

CODE undefined reference to __cxa_call_terminate@CXXABI_1.3.15
/usr/lib/gcc/x86_64-pc-linux-gnu/13/../../../../x86_64-pc-linux-gnu/bin/ld: /usr/lib64/libgtest.so: undefined reference to `__cxa_call_terminate@CXXABI_1.3.15'

What this means is the package that is emerging is building with, for example, GCC 13 but the package that provides libgtest.so was built with a newer version of GCC, 14 in this case.

The solution to this problem is rather simple but can be hard to figure out if the package providing the file is unknown. Portage supports emerging file paths directly so running emerge -1 /path/to/file.so might detect the file.

In the example, try emerging /usr/lib64/libgtest.so

root #emerge -1a /usr/lib64/libgtest.so
Calculating dependencies -
 
!!! '/usr/lib/libgtest.so' is not claimed by any package.
... done!

Unfortunately the file needed was not claimed, but another utility exists to find files installed by packages, Pfl. Using e-file, it is possible to find the package that installs the needed file.

user $e-file libgtest.so
...
[I] dev-cpp/gtest
        Seen Versions:          1.13.0 1.14.0
        Portage Versions:       1.13.0 1.14.0 9999
        Installed Versions:     1.14.0(Fri Nov 24 04:35:00 2023)
        Homepage:               https://github.com/google/googletest
        Description:            Google C++ Testing Framework
        Matched Files:          /usr/lib/libgtest.so; /usr/lib64/libgtest.so
...

In this case, dev-cpp/gtest is causing the build issue, re-merging it with:

root #emerge --ask --oneshot dev-cpp/gtest

should fix the issue and allow the continuation of emerging the original package.

Hinweis
For larger packages, it is likely to encounter this more than once while rebuilding a package with a lower version of GCC, keep following the above steps to eventually succeed in recompiling the package with GCC 13

Weiterführende Informationen

External resources

Referenzen