Actualizar 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 100% complete.
Other languages:
Deutsch • ‎English • ‎español • ‎italiano • ‎русский • ‎中文(中国大陆)‎ • ‎日本語 • ‎한국어

Este documento guía a los usuarios a través del proceso de cambiar a las versiones actuales de GCC.

Por favor, tenga en cuenta que desactualizar GCC podría suponer la aparición de efectos laterales no deseados. Eche un vistazo a la sección de resolución de problemas para ver más problemas de los que se informa habitualmente.

Versión corta

Esta sección es un rápido acercamiento a las actualzaciones de GCC (y lo fáciles que son de realizar). Se ofrecen más detalles en la siguiente sección en la que se explica cómo actualizar GCC.

La mayoría de actualizaciones son tan sencillas de realizar como cambiar la versión del compilador (en este ejemplo lo hacemos de la 5.4.0 a la 6.4.0) y a continuación reconstruimos libtool:

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
Nota
Si está actualizando desde gcc 4.x a gcc 5.x o superior, se pueden aplicar instrucciones adicionales, por favor lea entonces la página Actualizar desde gcc-4.x a gcc-5.x.

Comprobar el número de la versión actual y a continuación desinstalar la versión antigua:

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

Una vez hecho esto, verifique la integridad del sistema lanzando revdep-rebuild:

root #revdep-rebuild

¡Disfrute de su nuevo compilador!

Explicación de cómo actualizar GCC

La actualización de GCC siempre ha sido desconcertante, con sugerencias que van desde "los usuarios no necesitan hacer nada" hasta "los usuarios necesitarán reconstruir todo el sistema dos veces". La mayor parte de este miedo, incertidumbre y duda proviene de la confusión que rodea a la incompatibilidad ABI, algo que hoy en día rara vez ocurre (y cuando lo haga, se anunciará). Pero primero un apunte rápido sobrelibtool.

libtool

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

Sí, C++, ya que la mayoría de las incompatibilidades ocurren dentro de la ABI de C++. Si está actualizando a GCC 4.1 o GCC 5.1, probablemente encontrará problemas de ABI. Para evitar esto, el comando revdep-rebuild debe ejecutarse sobre la biblioteca libstdc++.so.5 al pasar de GCC 3 a GCC 4.1, o libstdc++.so.6 al pasar de GCC 4 a GCC 5.1.

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

Asi que, ¿Por qué se requiere esto para GCC hasta las versiones 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í y publicaremos una noticia. 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:

¿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
sys-devel/clang Dependiendo de la versión exacta de gcc puede verse afectado por sys-devel/llvm.
root #emerge --ask --oneshot --usepkg=n --verbose sys-devel/libtool sys-devel/llvm sys-devel/clang

Algunas colecciones de paquetes deben construirse con el mismo compilador (por ejemplo, los distintos paquetes qt-*). Por lo general, los mantenedores de paquetes actualizan estos paquetes simultáneamente, por lo que siempre se compilarán con la misma versión de GCC. Las reinstalaciones selectivas de estos paquetes pueden resultar problemáticas.

Reconstruyendo todo

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 influir en el desempeño de algunas aplicaciones positivamente.

Aparte de estos benificios "benignos", reconstruir todo desde cero puede ser necesario en algunos casos para corregir problemas que no paracen tener ninguna causa obvia.

Algunos problemas de software son intrínsecamente difíciles de diagnosticar y, sin embargo, podrían resolverse simplemente reconstruyendo uno o más paquetes apropiados. Si tal problema ha surgido después de una actualización de GCC y persiste después de usar el método revdep-rebuild descrito anteriormente (y después de reconstruir cualquier otro paquete obviamente relevante), una reconstrucción completa del sistema puede ser la respuesta.

La forma más "segura" (pero también que consume más tiempo) de lograr esto es usar la opción --emptytree (-e) de emerge para reconstruir el conjunto system y luego el conjunto world:

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

Se recomienda encarecidamente a los usuarios que lo intenten de esta forma antes de informar de problemas que podrían ser causados por la actualización de GCC.

(Tenga en cuenta que los comandos anteriores harán que los paquetes en el conjunto "system" se reconstruyan dos veces, lo cual es necesario para estar absolutamente seguro de que todos los paquetes se compilan en el mismo entorno [presumiblemente] "libre de problemas". Cualquier problema que persista después de hacer esto se debe a "auténticos errores" que deben informarse o a una configuración deficiente del sistema).

Resolución de problemas

Reconstruir boost

Si se necesita reconstruir el paquete dev-libs/boost, se obtendrá el siguiente mensaje:

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

Se puede reconstruir con:

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:

CÓDIGO No se encuentra GLIBCXX_x.y.z
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 que es más antigua que la usada 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 las instrucciones dadas por revdep-rebuild indicadas arriba.

Ver también

Referencias