This is Gentoo's testing wiki. It is a non-operational environment and its textual content is outdated.
Please visit our production wiki at https://wiki.gentoo.org
Actualizar GCC
Este documento guía al usuario a través del proceso de actualizar GCC.
Please note that downgrading GCC might have unwanted side effects. Refer to the troubleshooting section for some commonly reported issues.
Versión corta
La siguiente sección ofrece una introducción rápida a las actualizaciones de GCC (y lo fáciles que son). Si desea leer el razonamiento completo detrás de las actualizaciones de GCC, por favor, continue con explicación de cómo actualizar GCC.
Si está actualizando GCC entonces no necesita hacer nada salvo cambiar la versión del compilador y reconstruir libtool:
root #
emerge --ask --oneshot sys-devel/gcc
root #
emerge -u sys-devel/gcc
root #
gcc-config -l
[1] i686-pc-linux-gnu-4.4.5 * [2] i686-pc-linux-gnu-4.5.3
root #
gcc-config 2
root #
env-update && source /etc/profile
root #
emerge --ask --oneshot sys-devel/libtool
If you are upgrading from gcc 4.x to gcc 5.x or later, additional instructions apply; please see then the separate page Upgrading from gcc-4.x to gcc-5.x.
Comprobar la versión actual y desinstalar la antigua:
root #
gcc --version
root #
emerge --ask --depclean =sys-devel/gcc-4.4.5
After that, verify system integrity running revdep-rebuild:
root #
revdep-rebuild
Enjoy the new compiler!
Explicación de cómo actualizar GCC
Las actualizaciones de GCC siempre han sido rodeadas de un aura de misterio, con sugerencias que van desde "No hace falta hacer nada" hasta "Tendrá que reconstruir el sistema completo, dos veces". La mayoría de estas medias informaciones vienen de la confusión que rodea las incompatibilidades del ABI. Antes, unas palabras sobre libtool.
libtool y fix_libtool_files.sh
La razón por la cual necesitamos reconstruir libtool después de actualizar las versiones de gcc es debida a su función principal: libtool reúne un conjunto de herramientas que agregan código específico en un interfaz genérico permitiendo que las aplicaciones se construyan contra librerías compartidas sin tener que manejar aspectos específicos en cada plataforma de estas librerías. Para que realice su función correctamente, el guión libtool utiliza varias localizaciones en la librería con la versión de gcc previamente fijada dentro de ella.
Cambios en el ABI
Un ABI o ,Interfaz Binaria para Aplicaciones (en inglés Application Binary Interface), es un conjunto de convenciones usadas por todas las herramientas que manejan representaciones binarias de los programas, incluyendo compiladores, ensambladores, enlazadores y soporte en tiempo de ejecución (fuente: GCC Binary Compatibility). Al cambiar el ABI usado para aplicaciones binarias y librerías, existirá el riesgo de obtener errores de enlazado o programas funcionando incorrectamente si no se reconstruyen todas las librerías que usen el código C++.
Si, C++, ya que la mayoría de las incompatibilidades suceden en el ABI de C++. Si se está actualizando a GCC 4.1 o GCC 5.1 probablemente se encuentren problemas en el ABI. Por ello también se utiliza la orden revdep-rebuild contra libstdc++.so.5 (desde GCC 3 hacia GCC 4.1), o libstdc++.so.6 (desde GCC 4 hacia GCC 5.1).
root #
revdep-rebuild --library 'libstdc\+\+.so.6' -- --exclude gcc
Asi que, ¿Por qué se requiere esto para GCC hasta las versiones 3.4.0, 4.1 ó 5.1? A partir de estas versiones, GCC usa un ABI compatible a futuro, que elimina la necesidad de reconstruir las aplicaciones y librerías. Por supuesto que no se pueden dar garantía indefinidamente, pero cuando ocurra nuevamente una incompatibilidad, definitivamente la documentaremos aquí. En este caso la versión de la librería libstdc++.so probablemente será superior.
El caso especial C++11 (y C++14)
Aunque GCC (o más específicamente libstdc++) trata en la medida de lo posible de garantizar la estabilidad del ABI, esta garantía no se extiende a todas las partes de C++ dentro de libstdc++. Formalmente en las versiones a partir de la 3.4, GCC/libstdc++ únicamente garantiza la estabilidad del ABI de C++98/C++03 y ninguno más. Esto es crucial para los paquetes que dependen de C++11. GCC únicamente garantiza la estabilidad del ABI de C++11 a partir de la versión 5.1. Esto implica que el cambio (aunque sea mínimo) en una versión de gcc (digamos de la 4.7.3 a la 4.7.4) puede causar la ruptura del ABI para los binarios que se han construido con código de C++11.
Para obtener más información y ver algunos ejemplos, echar un vistazo a:
- bug #513386
- 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
¿Qué paquetes se sabe que deben reconstruirse?
La siguiente tabla indica los paquetes que si se instalan, se necesitarán reconstruir y el motivo por el cual se necesitan reconstruir.
Paquete | La reconstrucción es necesaria debido a ... |
---|---|
sys-devel/libtool | La aplicación libtool tiene las rutas definidas de forma inamovible hacia librerías internas de GCC |
sys-devel/llvm | Depende de la versión exacta de gcc, pueden aparecer errores en el enlazado con otros ebuilds que hagan uso de LLVM (por ejemplo media-libs/mesa) si no se reconstruye |
root #
emerge --ask --oneshot --usepkg=n --verbose sys-devel/libtool sys-devel/llvm sys-devel/clang
Existen también casos conocidos donde un conjunto de paquetes se deben construir con el mismo compilador. Aunque la versión de estos paquetes la suelen aumentar los mantenedores de los paquetes a la vez que la del compilador (de forma que se construyan con la misma versión de GCC), el escoger selectivamente reinstalaciones de algunos de estos paquetes puede traer problemas. Los paquetes de qt-* son un ejemplo de esto.
Algunos juran que al aparecer una nueva versión de GCC, se debe reconstruir hasta el último paquete del sistema. Por supuesto, esto no tiene sentido, ya que de todas formas hay muchas aplicaciones que no usan GCC en su proceso de construcción e instalación y por tanto nunca serían afectados por estos cambios.
Sin embargo, esto no significa que estén completamente equivocados: las versiones recientes de GCC suelen incluir soporte mejorado para los conjuntos de instrucciones de los procesadores, lo que podría influenciar el desempeño de algunas aplicaciones positivamente. Aunque se estima que estas mejoras sean generalmente marginales, en algunos casos (especialmente en aplicaciones que usan intensivamente el CPU) podrían traer mejoras notables.
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 also most time-consuming) 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
Users are urged to try this approach before reporting any bugs that might have been caused by a GCC upgrade.
(Note that 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.)
Resolución de problemas
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
Durante las actualizaciones puede que obtenga un error como el siguiente:
cmake_bootstrap_28021_test: /usr/lib/gcc/i486-pc-linux-gnu/4.1.2/libstdc++.so.6: version `GLIBCXX_3.4.11' not found
Esto significa que está intentando construir un paquete con una versión de GCC más antigua que el usado para construir algunas de sus librerías dependientes. ¿Recuerde cuando dijimos que el ABI C++ era compatible a futuro? Esto es cierto, pero segura solamente que versiones más recientes (o iguales) de GCC se pueden utilizar para construir aplicaciones y librerías enlazadas (en comparación con la versión de GCC usada para construir esas librerías).
Para reconstruir todos los paquetes que dependen de libstdc++, echar un vistazo a la sección previa sobre revdep-rebuild.
Ver también
- Actualizar GCC hasta la versión 4.1, la versión anterior a este documento.
- Actualizar de gcc-4.x a gcc-5.x
- Página Wiki 'Changes/GCC6' de Fedora