Mise à niveau de GCC

From Gentoo Wiki
Jump to:navigation Jump to:search
This page is a translated version of the page Upgrading GCC and the translation is 27% complete.

Les mises à niveau de GCC devraient généralement être gérées en douceur avec Portage et les outils habituels de Gentoo, voir la section suivante. Si jamais une mise à jour est plus complexe et nécessite l'intervention de l'utilisateur, elles sont normalement accompagnées d'un article d'actualité, qui doit être lu et suivi.

La rétrogradation de GCC peut avoir des effets secondaires indésirables. Consultez la section de dépannage pour certains problèmes couramment signalés.

Guide rapide pour la mise à niveau de GCC

La plupart des mises à niveau de GCC sont aussi simples que de changer la version du compilateur (ici de 10.3.0 à 11.2.0) et de recompiler dev-build/libtool :

root #emerge --ask --oneshot sys-devel/gcc
root #gcc-config --list-profiles
[1] x86_64-pc-linux-gnu-10.3.0 *
[2] x86_64-pc-linux-gnu-11.2.0
root #gcc-config 2
root #source /etc/profile
root #emerge --ask --oneshot --usepkg=n dev-build/libtool

Vérifiez le numéro de version actuel, puis désinstallez l'ancienne version :

root #gcc --version
root #emerge --ask --depclean sys-devel/gcc:10.3.0

Profitez de votre nouveau compilateur !

Guide complet pour les mises à jour GCC

La mise à jour de GCC a toujours été mystifiée, les recommandations allant de « les utilisateurs n'ont rien à faire » à « les utilisateurs devront recompiler l'ensemble du système deux fois ». L'incertitude était due à la confusion concernant l'incompatibilité des ABI, qui, de nos jours, ne pose que rarement des problèmes.

libtool

La raison pour laquelle nous devons recompiler libtool après la mise à jour des versions de gcc est son objectif principal : libtool est un ensemble d'outils qui regroupe le code spécifique à la plate-forme dans une interface générique, permettant aux applications de compiler avec des bibliothèques partagées sans avoir à traiter les aspects spécifiques à la plate-forme des bibliothèques partagées. Pour remplir sa fonction correctement, le script libtool utilise divers emplacements de bibliothèques qui contiennent des informations de version gcc codées en dur.

Voir bug #88596.

Changement d'ABI

Avant GCC 5.1

An ABI (Application Binary Interface), is a set of conventions used by all tools that deal with binary representation of programs, including compilers, assemblers, linkers, and language runtime support (source: GCC Binary Compatibility). When the ABI used for binary applications and libraries is changed, there is a risk getting linker errors or malfunctioning programs unless all libraries using C++ code are rebuilt.

When upgrading to GCC 4.1, or GCC 5.1, it is likely to encounter ABI issues. To prevent this, the revdep-rebuild command should be run against the libstdc++.so.5 library when moving from GCC 3 to GCC 4.1, or libstdc++.so.6 when moving from GCC 4 to GCC 5.1.

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

This is only needed till GCC 4.1/5.1 because from that version onward, GCC uses a forward-compatible ABI, which removes the need for rebuilding applications and libraries. Of course, guarantees can never be given indefinitely, but when an incompatibility occurs again, we'll definitely document it here and release a news item. In that case, the version of the libstdc++.so library will probably be increased.

The special case C++11 (and C++14)

While GCC (or more specifically, libstdc++) goes to great lengths to guarantee stability of the ABI, this guarantee does not extend to all parts of C++ within libstdc++. Formally, with versions starting from 3.4, GCC/libstdc++ only guarantees C++98/C++03 ABI stability and not more. This is crucial for packages that depend on C++11. GCC only makes C++11 ABI stability guarantees beginning with version 5.1. This means that switching (even minor) versions of gcc (say from 4.7.3 -> 4.7.4) might cause ABI breakage for binaries built from C++11 code.

For more information and some examples, see:

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

Which packages are known to need a rebuild?

The following table gives the packages that, if installed, need to be rebuilt and why.

Package Rebuild needed because ...
dev-build/libtool libtool has hardcoded paths towards GCC internal libraries, see bug #88596.
root #emerge --ask --oneshot --usepkg=n --verbose dev-build/libtool

Some collections of packages need to be built with the same compiler (for example, the various qt-* packages). Such packages are usually bumped by package maintainers simultaneously, so they will always be built with the same GCC version. Cherry-picking re-installs on these packages might prove to be troublesome.

Rebuilding everything

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

That, however, doesn't mean they are completely incorrect: newer GCC versions often include better support for the processors' instruction set, which might influence the performance of some applications in a positive way.

Apart from such "benign" benefits, rebuilding everything from scratch may be necessary in some cases to fix problems that don't seem to have any obvious cause.

Some software problems are inherently difficult to diagnose and yet could be solved by simply rebuilding one or more appropriate packages. If such a problem has arisen following a GCC upgrade and persists after using the revdep-rebuild approach described above (and after rebuilding any other obviously relevant packages), a complete system rebuild may be the answer.

The "safest" but slowest way to accomplish this is to use the --emptytree (-e) option of emerge to rebuild the system set and then the world set:

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

Try this approach before reporting bugs that might have been caused by a GCC upgrade.

Remarque
The commands above will cause the packages in the system set to be rebuilt twice, which is necessary to be absolutely certain that every package gets built in the same presumably "problem-free" environment. Any problems that remain after doing this are due to either "genuine bugs" that should be reported or poor system configuration.

Troubleshooting

Rebuild of Boost

If dev-libs/boost needs to be rebuilt, one will get the following error message:

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

One can rebuild with:

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

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

During updates, it's possible to encounter an error like the following:

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

This implies an attempt to build a package with an older GCC version than that with which some depending libraries were built. The C++ ABI is forward-compatible, but it ensures only that higher (or same) GCC versions can be used when building applications and linking libraries (compared to the GCC version used to build those libraries).

To rebuild all the packages depending on libstdc++, see the revdep-rebuild instructions above.

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.

Remarque
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

See also

External resources

References