Manualinux
http://www.nvu.com http://www.gimp.org InicioPresentaciónActualizacionesManualesDescargasNoticiasAgradecimientoEnlaces

Entornos GráficosAplicaciones

DesarrolloEmuladoresInternetJuegosMultimediaSistema

Instalar Dependencias para GCCInstalar Java en GNU/Linux

Instalar GCC desde cero

Página - 1Página - 2




Instalar GCC desde cero




Copyright

Copyright © José Luis Lara Carrascal  2007-2021   http://manualinux.eu



Sumario

Introducción
Instalar GCC 11.2.0
Configurar el sistema para el uso de GCC 11.2.0
Establecer el RPATH correspondiente
Optimizaciones de CPU para GCC
Niveles de optimización soportados por GCC
Optimizaciones adicionales para GCC
Instalar GCC 10.3.0
Configurar el sistema para el uso de GCC 10.3.0
Instalar GCC 9.4.0
Configurar el sistema para el uso de GCC 9.4.0
Instalar GCC 8.5.0
Configurar el sistema para el uso de GCC 8.5.0
Instalar GCC 7.5.0
Configurar el sistema para el uso de GCC 7.5.0
Instalar GCC 6.5.0
Configurar el sistema para el uso de GCC 6.5.0
Enlaces




Introducción  

Con la publicación de este manual se oficializa dentro de la web el apartado dedicado a este indispensable compilador, y se incluye la versión más reciente del mismo, además de las otras versiones más recientes de otras series del compilador predefinido del mundo GNU/Linux.

De lo que se trata es de que podamos siempre compilar un programa, y para eso tendremos que tener dos o tres versiones diferentes de GCC, aunque el número de versiones que podamos llegar a tener es ilimitado. La configuración del sistema para que puedan convivir las diferentes versiones de GCC es otro de los aspectos (incluso yo diría el más importante) más destacable de este documento.

Los lenguajes soportados en la compilación de GCC son los que habitualmente uso: C, C++ y Objetive C. Para terminar, y al igual que expliqué en la introducción del manual del Kernel, esto no es un manual genérico de instalación de GCC, sino la radiografía de las instalaciones que un usuario de GNU/Linux viene haciendo hace ya unos cuantos años, sin haber tenido casi nunca, ningún tipo de problema en la convivencia de las diferentes versiones de GCC que tiene en su sistema GNU/Linux. Desde el 8 de mayo de 2012 se incluye también la instalación del lenguaje Fortran. Y desde el 13 de marzo de 2015, la instalación del lenguaje Java, que ha sido retirado a partir de GCC 7.

Desde el 2 de mayo de 2018, la instalación de la versión principal de GCC, se ha actualizado a un sistema de 64 bits multiarquitectura. El resto de versiones (salvo actualizaciones), de momento, se mantienen en la arquitectura de procesador de 32 bits. A día de hoy, con la presencia de Clang como compilador alternativo de GCC, se reduce a casos muy específicos de código escrito en Java o Fortran, la obligación de tener instaladas versiones anteriores de GCC. Aún así, el manual seguirá incluyendo estas versiones, aunque yo termine borrando de mi sistema, la mayoría de ellas, una vez las haya compilado para poder actualizar este documento.

Desde el 13 de marzo de 2020, sólo se actualizará la versión actual del compilador, dejando la mayoría de las otras como histórico de este manual. Si saliera alguna versión anterior, se actualizarán los enlaces de descarga y el nombre del compilador en la sección que toque, pero no se actualizará el proceso de compilación en sí. También se incluye a partir de esta fecha, las optimizaciones de CPU y adicionales que se incluyen en otros manuales para compilar la versión actual de GCC. 

Desde el 11 de abril de 2021, se retira del manual, la instalación de todas las versiones inferiores a GCC 6, y se suprimen las definiciones de CPU de los fabricantes VIA e IDT de la tabla de optimizaciones de GCC, por obsoletas y, a día de hoy, poco funcionales.



Instalar GCC 11.2.0

Instalación

Dependencias

Herramientas de Compilación


Entre paréntesis la versión con la que se ha compilado GCC 11.2.0 para la elaboración de este documento.

* GCC - (11.1.0)
* Gawk - (5.1.0)
* M4 - (1.4.19)
* Libtool - (2.4.6)
* Make - (4.3)
* Bison - (3.7.6)
* Flex - (2.6.4)
* Automake - (1.16.4)
* Autoconf - (2.71)
* Gettext - (0.21)
* Gperf - (3.1)
* Texinfo - (6.8)

Librerías de Desarrollo

* Gmp - (6.2.1)
* Mpfr - (4.1.0)
* Mpc - (1.2.1)
* ISL - (0.18)
* Libzstd - (1.5.0)



Descarga

gcc-11.2.0.tar.xz

Optimizaciones

$ export {C,CXX}{FLAGS,FLAGS_FOR_TARGET}='-O3 -march=znver2 -mtune=znver2'

Donde pone znver2 se indica el procesador respectivo de cada sistema seleccionándolo de la siguiente tabla:
* La opción '-march=' establece el procesador mínimo con el que funcionará el programa compilado, la opción '-mtune=' el procesador específico para el que será optimizado. 

* Los valores separados por comas, son equivalentes, es decir, que lo mismo da poner '-march=k8' que '-march=athlon64'.

* En versiones de GCC 3.2 e inferiores se utiliza la opción '-mcpu=' en lugar de '-mtune='.
Valores CPU
Genéricos
Intel
AMD

Optimizaciones adicionales

Optimizaciones adicionales
Graphite
$ export {C,CXX}{FLAGS,FLAGS_FOR_TARGET}+=' -ftree-loop-linear -floop-strip-mine -floop-block'

Extracción y Configuración  Bloc de Notas Información general sobre el uso de los comandos

$ tar Jxvf gcc-11.2.0.tar.xz
$ mkdir gcc-build_11.2.0
$ cd gcc-build_11.2.0
$ ../gcc-11.2.0/configure --enable-shared --enable-threads=posix \
--enable-__cxa_atexit --enable-clocale=gnu --enable-languages=c,c++,fortran,objc \
--prefix=/opt/gcc11 --program-suffix=11 --with-build-config=bootstrap-O3


Explicación de los comandos

mkdir gcc-build_11.2.0
: Creamos un directorio de compilación, ya que GCC no permite que se compile directamente en el directorio de las fuentes.
--enable-shared : Compila las librerías compartidas.
--enable-threads=posix : Selecciona la librería genérica POSIX/Unix98 para el soporte de hilos.
--enable-__cxa_atexit : Opción necesaria para una correcta compilación de c++.
--enable-clocale=gnu : Evita un error en la generación de las locales, en el caso de que estén incompletas.
--enable-languages=c,c++,fortran,objc : Compila los lenguajes de programación C, C++, Fortran y Objetive C.
--prefix=/opt/gcc11 : Instala el compilador en /opt/gcc11.

--program-suffix=11 : Añadimos un sufijo a los binarios ejecutables instalados para poder diferenciarlos de otras versiones de GCC que tengamos instaladas en nuestro sistema, empezando por la principal del mismo. En mi caso particular no utilizo esta opción porque esta versión es de facto la principal de mi sistema y referencia para la documentación de este sitio web. En la lista de archivos de las estadísticas de compilación e instalación de este paquete, no aparece este sufijo.

--with-build-config=bootstrap-O3 : Complementamos las optimizaciones establecidas en el manual (CFLAGS, CXXFLAGS, CFLAGS_FOR_TARGET, CXXFLAGS_FOR_TARGET) con esta que añade el nivel de optimización -O3 al proceso de compilación (modo bootstrap), y evitamos con todo el combinado que el parámetro de depuración -g, se use en la mayor parte del mismo. 

Parámetros de configuración opcionales

--with-build-config=bootstrap-lto : Aplica la optimización LTO en las fases 2 y 3 del proceso de compilación. Esta optimización sólo se aplica a los binarios ejecutables, nunca a las librerías (aunque estas si contienen código LTO). En lugar de reducir el tamaño de los binarios, estos aumentan (excepto los ubicados en el directorio bin). La ganancia de velocidad que añade a la combinación O3+CPU+Graphite es de un 10/15 %. Los requerimientos de memoria pueden llegar a picos de 13 GB sin ningún problema (tmpfs montado en /tmp), en la segunda fase de compilación. El proceso de enlazado LTO alarga de manera considerable el proceso de compilación, casi dobla el tiempo requerido para una compilación normal.

Usuarios con 4 GB de memoria RAM o menos, abstenerse de utilizar este parámetro. Los usuarios con 8 GB de RAM y tmpfs montado en /tmp, deberán de establecer una variable de entorno TMPDIR, para que los archivos temporales no se escriban en la memoria (puede llegar a los 1,4 GB de requerimiento de espacio para archivos temporales) y así, dejarla sólo para el proceso de compilación. Si el directorio temporal está en otro disco duro, mejor que mejor. Un ejemplo:

$ su
# mkdir -p /mnt/debian/cache
# chmod 777 /mnt/debian/cache
# exit
$ export TMPDIR=/mnt/debian/cache

Este parámetro se puede combinar con el predefinido que se incluye en este manual, de la siguiente forma: --with-build-config="bootstrap-O3 bootstrap-lto"

A partir de GCC 11, si no tenemos como mínimo 16 GB de memoria RAM, no recomiendo el uso de esta optimización.

--with-build-config=bootstrap-lto-lean : Es igual que la anterior, pero sólo se aplica en la fase 3 de compilación. El principal problema de aplicar este parámetro es que la ganancia de velocidad es menor, y no merece la pena hacer uso del mismo, respecto al parámetro anterior, aunque se tarde menos en compilar el paquete.

Este parámetro se puede combinar con el predefinido que se incluye en este manual, de la siguiente forma: --with-build-config="bootstrap-O3 bootstrap-lto-lean"

--disable-bootstrap : Si por la razón que sea, tenemos que volver a recompilar el paquete, utilizando el mismo compilador de la versión que vamos a instalar, añadiendo esta opción evitaremos que el compilador se recompile a sí mismo, y anularemos el proceso predefinido de compilación en tres fases. Si la versión utilizada es de la misma serie, también se puede utilizar esta opción, aunque conlleva una pérdida de rendimiento en los binarios ejecutables resultantes. Realizar antes una copia de seguridad de la versión instalada, porque la instalación de la nueva versión sobreescribirá los archivos de la misma.

--with-default-libstdcxx-abi=gcc4-compatible : Hace compatible la versión de Libstdc++ de esta versión, con binarios compilados con versiones de la serie 4 de GCC y versiones inferiores a la 3.9 de Clang, además de las versiones superiores de GCC que se hayan compilado con esta misma opción de configuración del paquete.

Compilación

$ make BOOT_CFLAGS="${CFLAGS}"

Explicación de los comandos

BOOT_CFLAGS="${CFLAGS}" : Se sincronizan las optimizaciones aplicadas en el manual con las utilizadas en el modo de compilación de 3 fases (bootstrap). Esto no es necesario hacerlo si utilizamos un compilador de la misma serie y añadimos en el proceso de configuración, el parámetro --disable-bootstrap.

Parámetros de compilación opcionales  

-j$(getconf _NPROCESSORS_ONLN): Establece el número de procesos de compilación en paralelo, en función del número de núcleos e hilos que tenga nuestro procesador, tomando como referencia la información mostrada por el sistema con el comando correspondiente. Si nuestro procesador es mononúcleo de un solo hilo, no añadir esta opción.

Instalación como root

$ su -c "make install-strip"

Borrar las locales adicionales instaladas

$ su
# for i in be ca da de el eo fi fr hr id ja nl pt_BR \
ru sr sv tr tk uk vi zh_CN zh_TW ; do \
rm -rf /opt/gcc11/share/locale/$i &> /dev/null ; \
done

Borrar los directorios y archivos de instalación que hacen referencia a la versión 11.1.0, sobreescrita por esta nueva versión

Hacer sólo esto si estamos actualizando desde la versión anterior instalada siguiendo las instrucciones de este manual. Con los siguientes comandos, borramos los directorios y archivos de instalación de la versión anterior.

# find /opt/gcc11 -name '*11.1.0' | xargs rm -rf

Estadísticas de Compilación e Instalación de GCC 11.2.0

Estadísticas de Compilación e Instalación de GCC 11.2.0
CPU AMD Ryzen 3 3100 4-Core Processor
MHz 3593.246
RAM 16 GB
Sistema de archivos XFS
Versión del Kernel 5.12.19-ck1 SMP PREEMPT x86_64
Modo de frecuencia de la CPU performance
Versión de Glibc 2.33
Enlazador dinámico GNU gold (Binutils 2.37) 1.16
Compilador GCC 11.1.0 + Ccache 4.3
Parámetros de optimización -03 -march=znver2 -mtune=znver2 -ftree-loop-linear -floop-strip-mine -floop-block -flto=jobserver
Parámetros de compilación BOOT_CFLAGS="${CFLAGS}" -j8
Ocupación de espacio en disco del proceso de compilación 6,5 GB
Tiempo de compilación 1h 22' 34"
Archivos instalados 1.640
Mostrar/Ocultar la lista de archivos instalados
Enlaces simbólicos creados 47
Mostrar/Ocultar la lista de enlaces simbólicos creados
Ocupación de espacio en disco 320,6 MB

Desinstalación como root

1) MODO TRADICIONAL

En el directorio de compilación ejecutamos el siguiente comando:

$ su -c "make uninstall"

2) MODO MANUALINUX

El principal inconveniente del comando anterior es que tenemos que tener el directorio de compilación en nuestro sistema para poder desinstalar el programa. En algunos casos esto supone muchos megas de espacio en disco. Con el paquete de scripts que pongo a continuación logramos evitar el único inconveniente que tiene la compilación de programas, y es el tema de la desinstalación de los mismos sin la necesidad de tener obligatoriamente una copia de las fuentes compiladas.

gcc-11.2.0-scripts.tar.gz

$ su
# tar zxvf gcc-11.2.0-scripts.tar.gz
# cd gcc-11.2.0-scripts
# ./Desinstalar_gcc-11.2.0

La desinstalación del compilador no incluye las librerías compartidas (.so) para evitar problemas de dependencias en el caso de que hayamos compilado algún programa con esta versión de GCC.

Copia de Seguridad como root

Con este otro script creamos una copia de seguridad de los binarios compilados, recreando la estructura de directorios de los mismos en un directorio de copias de seguridad (copibin) que se crea en el directorio /var. Cuando se haya creado el paquete comprimido de los binarios podemos copiarlo como usuario a nuestro home y borrar el que ha creado el script de respaldo, teniendo en cuenta que si queremos volver a restaurar la copia, tendremos que volver a copiarlo al lugar donde se ha creado.

$ su
# tar zxvf gcc-11.2.0-scripts.tar.gz
# cd gcc-11.2.0-scripts
# ./Respaldar_gcc-11.2.0

Restaurar la Copia de Seguridad como root

Y con este otro script (que se copia de forma automática cuando creamos la copia de respaldo del programa) restauramos la copia de seguridad como root cuando resulte necesario.

$ su
# cd /var/copibin/restaurar_copias
# ./Restaurar_gcc-11.2.0

Soporte de optimizaciones para nuevos procesadores en GCC 11

En GCC 11 se añade soporte de optimizaciones para los siguientes procesadores:

Procesadores Parámetros de optimización
Genéricos
Procesador genérico con soporte de instrucciones X86-64 (MMX, SSE, SSE2, LAHFSAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3) y extensiones 64-bit. -march=x86-64-v2 -mtune=x86-64-v2
Procesador genérico con soporte de instrucciones X86-64 (MMX, SSE, SSE2, LAHFSAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3, AVX, AVX2, F16C, FMA, LZCNT, MOVBE, XSAVE, XSAVEC, FMA4) y extensiones 64-bit. -march=x86-64-v3 -mtune=x86-64-v3
Procesador genérico con soporte de instrucciones X86-64 (MMX, SSE, SSE2, LAHFSAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3, AVX, AVX2, F16C, FMA, LZCNT, MOVBE, XSAVE, XSAVEC, AVX512*, FMA4) y extensiones 64-bit. -march=x86-64-v4 -mtune=x86-64-v4
Intel
Intel Alderlake con soporte de instrucciones x86-64 (MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VNNI, AVX512BF16, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE, AMX-INT8, AVX-VNNI) y extensiones 64-bit. -march=alderlake -mtune=alderlake
Intel Rocket Lake con soporte de instrucciones x86-64 (MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI, AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ, AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES) y extensiones 64-bit -march=rocketlake -mtune=rocketlake
Intel Sapphire Rapids con soporte de instrucciones x86-64 (MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VNNI, AVX512BF16, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT, ENQCMD, CLDEMOTE, PTWRITE, WAITPKG, SERIALIZE, TSXLDTRK, UINTR, AMX-BF16, AMX-TILE, AMX-INT8 and AVX-VNNI) y extensiones 64-bit -march=sapphirerapids -mtune=sapphirerapids
AMD
Procesadores basados en AMD Family 19h core con soporte de instrucciones x86-64 (BMI, BMI2, CLWB, F16C, FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA, CLZERO, AES, PCLMUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT, RDPID, WBNOINVD, PKU, VPCLMULQDQ, VAES) y extensiones 64-bit -march=znver3 -mtune=znver3



Configurar el sistema para el uso de GCC 11.2.0 

1) /etc/ld.so.conf  Nota importante

Añadimos la ruta a las librerías en el archivo /etc/ld.so.conf.

include ld.so.conf.d/*.conf
/usr/X11R6/lib
/usr/lib
/usr/lib/qt3/lib
/usr/local/lib
/opt/e17/lib
/opt/gcc11/lib64
/opt/gcc11/lib

Cuando lo hayamos editado y guardado ejecutamos la actualización de la caché de las librerías compartidas.

$ su -c "ldconfig -v"

2) Añadir la ruta a los binarios y las páginas de manual a nuestro PATH

2a) Variable de entorno PATH de usuario

Editamos el archivo de nuestro home, ~/.bashrc (si no existe lo creamos) y añadimos lo siguiente al final del mismo.

export PATH=/opt/gcc11/bin:$PATH
export MANPATH=/opt/gcc11/share/man:$MANPATH


2b) Variable de entorno PATH del sistema

Si queremos establecer una variable de entorno global del sistema, abrimos un editor de texto y añadimos lo siguiente:

#!/bin/sh

export PATH=/opt/gcc11/bin:$PATH
export MANPATH=/opt/gcc11/share/man:$MANPATH


Lo guardamos con el nombre gcc.sh, y lo instalamos en /etc/profile.d.

$ su -c "install -m755 gcc.sh /etc/profile.d"

Tenemos que cerrar el emulador de terminal y volverlo a abrir para que la variable de entorno aplicada sea efectiva. Es conveniente guardar una copia de este script para posteriores instalaciones de nuestro sistema. La ventaja de utilizar el directorio /etc/profile.d es que es común a todas las distribuciones y nos evita tener que editar otros archivos del sistema como por ejemplo, /etc/profile.

Para comprobar que la nueva versión aparece en el PATH basta teclear la palabra gcc, y pulsar el tabulador (la tecla de las dos flechas que está al lado de la letra Q en el teclado) para que autocomplete la lista de ejecutables disponibles relacionados con este comando, ejemplo:

[jose@localhost ~]$ gcc
gcc           gcc44         gcc49         gcc-ar49      gccbug43      gcc-nm47      gcc-ranlib47
gcc32         gcc45         gcc5          gcc-ar5       gccbug44      gcc-nm48      gcc-ranlib48
gcc34         gcc46         gcc-ar        gccbug32      gccbug45      gcc-nm49      gcc-ranlib49
gcc42         gcc47         gcc-ar47      gccbug34      gccmakedep    gcc-nm5       gcc-ranlib5
gcc43         gcc48         gcc-ar48      gccbug42      gcc-nm        gcc-ranlib

En mi caso no aparece el número del compilador porque siempre lo coloco como compilador principal del sistema, es decir, no lo instalo con la opción del sufijo correspondiente. En el caso de que queramos que nuestra flamante versión sea la que utilice el sistema por defecto (cuidado con esto, leerse la sección del RPATH), sólo tenemos que editar los enlaces simbólicos que las distribuciones (no sé si todas) suelen crear a los binarios de sus respectivos compiladores, pongo el ejemplo de Mandriva, pero es perfectamente válido para todas.

Sobreescribo los enlaces pertinentes en el directorio /usr/bin, en el caso de Mandriva también se puede hacer en /etc/alternatives que es a donde apuntan los que están en /usr/bin.

# ln -sf /opt/gcc11/bin/gcc /usr/bin/gcc
# ln -sf /opt/gcc11/bin/g++ /usr/bin/g++
# ln -sf /opt/gcc11/bin/cpp /usr/bin

Antes de sobreescribirlos comprobar visualmente que son enlaces simbólicos, que cada distribución es un mundo. Y ahora cuando teclee en la ventana de terminal, gcc --version, me saldrá la que he instalado. Podemos comprobar también que el binario g++ funciona sin ningún problema.

[jose@localhost ~]$ gcc --version
gcc (GCC) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc.
Esto es software libre; vea el código para las condiciones de copia.  NO hay
garantía; ni siquiera para MERCANTIBILIDAD o IDONEIDAD PARA UN PROPÓSITO EN
PARTICULAR

[jose@localhost ~]$ g++ --version
g++ (GCC) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc.
Esto es software libre; vea el código para las condiciones de copia.  NO hay
garantía; ni siquiera para MERCANTIBILIDAD o IDONEIDAD PARA UN PROPÓSITO EN
PARTICULAR

En el caso de que no existan los enlaces simbólicos cc y c++ apuntando a /usr/bin/gcc y /usr/bin/g++, ya sea de forma directa o a través de los enlaces simbólicos, /etc/alternatives/cc y /etc/alternatives/c++, los creamos dentro del directorio /usr/bin.

# ln -sf /usr/bin/gcc /usr/bin/cc
# ln -sf /usr/bin/g++ /usr/bin/c++

Y comprobamos que funcionan correctamente.

[jose@localhost ~]$ cc --version
cc (GCC) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc.
Esto es software libre; vea el código para las condiciones de copia.  NO hay
garantía; ni siquiera para MERCANTIBILIDAD o IDONEIDAD PARA UN PROPÓSITO EN
PARTICULAR

[jose@localhost ~]$ c++ --version
c++ (GCC) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc.
Esto es software libre; vea el código para las condiciones de copia.  NO hay
garantía; ni siquiera para MERCANTIBILIDAD o IDONEIDAD PARA UN PROPÓSITO EN
PARTICULAR

En cambio, si no queremos que la versión instalada sea la que usamos por defecto, cada vez que queramos hacer uso de la misma deberemos de ejecutar las variables de entorno pertinentes, aunque esto no siempre es efectivo con todos los programas y puede que algunas veces tengamos que editar directamente los archivos Makefile, edición que explico en este mismo apartado.

a) Antes de ejecutar el script configure

$ export LDFLAGS+=' -L/usr/lib64 -L/usr/local/lib64'
$ export CC=gcc11 CXX=g++11 {FC,F90,F95,F77}=gfortran11

La variable de entorno LDFLAGS es requerida en sistemas de 64 bits multiarquitectura, para que el enlazador dinámico no muestre avisos de incompatibilidad de arquitectura, por duplicación de versiones de 32 y 64 bits de una misma librería. Además que, esto puede provocar errores de configuración en los paquetes.

Que podemos convertir en un alias de Bash, para reducir los comandos. Abrimos con un editor de texto, el archivo de configuración personal, ~/.bashrc, si no existe lo creamos, y añadimos lo siguiente al final del contenido del mismo:

alias ldpath="export LDFLAGS=' -L/usr/lib64 -L/usr/local/lib64'"
alias envgcc11="export CC=gcc11 CXX=g++11 {FC,F90,F95,F77}=gfortran11"

Ahora bastará teclear los comandos ldpath y envgcc11, para establecer las variables de entorno pertinentes.

[jose@localhost ~]$ envgcc11; ldpath
[jose@localhost ~]$ echo $CC $CXX $FC $LDFLAGS
gcc11 g++11 gfortran11 -L/usr/lib64 -L/usr/local/lib64

Esto lo podemos aplicar con todas las versiones de GCC tratadas en este manual. Sólo hay que cambiar el número del sufijo de la versión, y el número del alias a utilizar.

En el caso particular de Fortran existe un problema, y es que los scripts de configuración tipo GNU Autotools, hacen caso omiso a las variables de entorno de uso de compilador Fortran y buscan siempre el binario ejecutable gfortran. Para solventar esto nos creamos un alias de Bash, que crea una variable de entorno PATH temporal en el directorio /tmp, y enlaza el binario ejecutable numerado de la versión correspondiente del compilador. También nos creamos otro alias que deshace lo que el primero realiza.

Abrimos con un editor de texto, el archivo de configuración personal, ~/.bashrc, si no existe lo creamos, y añadimos lo siguiente al final del contenido del mismo:

alias envgfortran11="mkdir -p /tmp/bin; ln -sf /opt/gcc11/bin/gfortran11 /tmp/bin/gfortran; export PATH=/tmp/bin:$PATH"
alias ungfortran11="rm -rf /tmp/bin"

Ahora bastará teclear el comando envgfortran10, para que éste sea el utilizado por el correspondiente script de configuración.

[jose@localhost ~]$ envgfortran11
[jose@localhost ~]$ gfortran --version
GNU Fortran (GCC) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc.

GNU Fortran viene SIN GARANTÍA, a la extensión permitida por ley.
Puede distribuir copias de GNU Fortran
bajo los términos de la Licencia Pública General GPL.
Para más información sobre estos asuntos, vea el fichero llamado COPYING

En lo que concierne a la compilación de código escrito en Java (retirado a partir de GCC 7), tendremos que editar los correspondientes archivos Makefile que contenga el paquete, y sustituir el nombre del binario ejecutable (si está numerado), la ruta a la librería de ejecución (libgcj) y las CLASSPATH (/opt/gcc6/share/java), para que apunten al directorio de instalación de esta versión de GCC. La compilación con Java, admite las mismas optimizaciones de CPU y optimizaciones adicionales que el resto de lenguajes de programación soportados por el compilador, además de otros parámetros específicos que podemos consultar en la correspondiente página de manual (man gcj6), o en la documentación en línea del mismo. 

b) Comprobar que se ha establecido la variable y está usando la versión 11.2.0

Existen muchas maneras pero hay una que no falla y es la salida de información en la ventana de terminal cuando ejecutamos el script configure, y la ejecución del comando make que pone en marcha a GCC, más ejemplos: 

Ejemplo 1: Salida de información cuando ejecutamos el script de configuración

[jose@localhost e16-0.16.8.15]$ ./configure
checking for a BSD-compatible install... /bin/install -c
checking whether build environment is sane... yes
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether to enable maintainer-specific portions of Makefiles... no
checking for gcc... gcc11

un poquito más abajo comprueba la existencia de g++

checking whether we are using the GNU C++ compiler... yes
checking whether g++11 accepts -g... yes
checking dependency style of g++10... gcc3
checking how to run the C++ preprocessor... g++11 -E


Ejemplo 2: El proceso de compilación nos quita las últimas dudas que tengamos

if gcc11 -DHAVE_STRERROR -DFATAL_EXIT_CODE=1 -DSUCCESS_EXIT_CODE=1 -DGCC_INCLUDE_DIR=\"/usr/include\" -DGPLUSPLUS_INCLUDE_DIR=\"/usr/include\" -DTOOL_INCLUDE_DIR=\"/usr/bin\" -DHOST_BITS_PER_LONG=32 -DBITS_PER_UNIT=8 -DHOST_BITS_PER_INT=32 -DBITS_PER_WORD=16 -DTARGET_BELL=7 -DTARGET_BS=8 -DTARGET_FF=12 -DTARGET_NEWLINE=10 -DTARGET_CR=13 -DTARGET_TAB=9 -DTARGET_VT=11 -I. -I. -I.. -I.. -I..  -I/usr/X11R6/include   -g -O2 -MT cpplib.o -MD -MP -MF ".deps/cpplib.Tpo" -c -o cpplib.o cpplib.c; \

2c) Lectura de las páginas de manual

$ man gcc11
$ man gfortran11

c) Establecer el modo de compilación de 32 bits en sistemas de 64 bits multiarquitectura

Para compilar código de 32 bits en sistemas de 64 bits multiarquitectura, estableceremos las siguientes variables de entorno:

$ export LDFLAGS+=' -L/usr/lib -L/usr/local/lib'
$ export CC='gcc11 -m32' CXX='g++11 -m32' {FC,F90,F95,F77}='gfortran11 -m32'

Que también convertiremos en alias de Bash, un ejemplo:

alias ldpath-32="export LDFLAGS+=' -L/usr/lib -L/usr/local/lib'"
alias envgcc11-32="export CC='gcc11 -m32' CXX='g++11 -m32' {FC,F90,F95,F77}='gfortran11 -m32'"

No olvidar que en algunos paquetes configurados con las GNU Autotools, tendremos que añadir la opción de configuración --build=i686-pc-linux-gnu para poder llevar a buen puerto el proceso de compilación. Y, en otros que intervenga el ensamblador, es posible que tengamos que establecer la siguiente variable de entorno, antes de configurar el paquete:

$ export ASFLAGS="--32"

Esto en concreto sólo me ha pasado con un paquete configurado para CMake, que ahora no recuerdo cuál es. Creo que es el de Vulkan.



Establecer el RPATH correspondiente para una correcta compilación de los binarios escritos en C++ y Fortran, o binarios que contengan código OpenMP

El RPATH es la ruta preferente de búsqueda de directorios que contengan librerías de ejecución contra las que se enlazarán los binarios resultantes de un proceso de compilación. Cuando existen en nuestro sistema librerías de ejecución con el mismo nombre pero con diferente ABI, tendremos que establecer un RPATH en el proceso de compilación, que enlace de forma correcta el binario compilado contra la librería de ejecución que le corresponda. En el caso de GCC, los binarios escritos en C++, tenemos que enlazarlos contra la versión de libstdc++.so del compilador utilizado, los binarios escritos en Fortran, contra la versión de libgfortran.so y los binarios que contengan código OpenMP, contra la versión de libgomp.so del mismo compilador utilizado.

El establecimiento de un RPATH en el proceso de compilación que produzca un resultado exitoso, estará siempre condicionado por las dependencias del paquete a compilar. Si queremos compilar por ejemplo, qBittorrent con una versión diferente a la principal del sistema, no nos resultará posible, porque sus dependencias escritas en C++: Qt, Boost y Libtorrent-rasterbar, estarán enlazadas contra la versión de libstdc++.so proporcionada por la distribución de turno. La recompilación de esas dependencias nos llevaría de facto, a la actualización completa de los paquetes escritos en dichos lenguajes de programación, e implicaría convertir la versión instalada por nosotros, en la versión principal del sistema.

Dicho de una manera muy escueta: Todas las librerías compartidas de un sistema GNU/Linux por más de una aplicación, que estén escritas en C++ y Fortran, o contengan código OpenMP, tendrán que haber sido compiladas por una misma versión de GCC, si no queremos volvernos locos, y hacer el sistema completamente inoperativo. Por otra parte, el RPATH establecido por el usuario puede ser sobreescrito por otros establecidos por el script de configuración del paquete. De ahí, que en muchos manuales de esta web, se sugiera el renombrado temporal de la versión de libstdc++.so proporcionada por la distribución de turno, antes de compilar el paquete e instalarlo, para posteriormente volver a restaurar dicho enlace.

Otro recurso final cuando no resultan posibles otros, es recurrir a la utilidad PatchELF para añadir el RPATH a los binarios resultantes de la compilación cuando los tengamos ya instalados en nuestro sistema. Dicho esto, a continuación explico cómo establecer el RPATH con los sistemas de compilación más habituales de nuestro sistema. A pesar de esta información, siempre nos encontraremos con problemas, que pondrán a prueba nuestra experiencia como usuarios compiladores de código fuente y nuestro ingenio e imaginación como seres presuntamente inteligentes que somos.

En sistemas de 64 bits multiarquitectura, en el modo de compilación de 32 bits, sustituir lib64 por lib, en la ruta a establecer.

1) GNU Autotools

C++
$ export LDFLAGS="-Wl,-rpath,/opt/gcc11/lib64 -lstdc++"
$ ./configure

Fortran
$ export LDFLAGS="-Wl,-rpath,/opt/gcc11/lib64 -lgfortran"
$ ./configure

OpenMP
$ export LDFLAGS="-Wl,-rpath,/opt/gcc11/lib64 -lgomp"
$ ./configure

2) GNU Makefile

En este caso, comprobamos primero que el archivo o archivos Makefile contiene la variable LDFLAGS, y si es así, le añadimos el signo +, para que no sea fija, y poder establecer nuestras propias variables de entorno. Un ejemplo:

Antes
LDFLAGS = -L/usr/X11R6/lib -lImlib2 -lm -g -ggdb

Después
LDFLAGS += -L/usr/X11R6/lib -lImlib2 -lm -g -ggdb

Cuando lo tengamos editado, establecemos el RPATH correspondiente y ejecutamos el comando make.

export LDFLAGS="-Wl,-rpath,/opt/gcc11/lib64 -lstdc++"
$ make

3) CMake

Establecemos el RPATH y ejecutamos el comando correspondiente de configuración. Las versiones más antiguas de CMake no sincronizan de forma automática la variable de entorno LDFLAGS con las variables equivalentes de CMake.

$ export LDFLAGS="-Wl,-rpath,/opt/gcc11/lib64 -lstdc++"
$ cmake ..

Recordar que el código fuente de los programas y librerías escritos en C++ se distinguen por la extensión de archivo que puede ser:

archivo.cc
archivo.cp
archivo.cxx
archivo.cpp
archivo.CPP
archivo.c++
archivo.C


Y en el caso de Fortran, pueden ser:

archivo.f90
archivo.f95
archivo.f03
archivo.f
archivo.for

Y también lo podemos saber por los mensajes que se muestran en la terminal en el proceso de compilación, al utilizarse g++ para el mismo:

if g++ -DHAVE_CONFIG_H -I. -I. -I..   -I/usr/local/include -I/usr/X11R7/include -DSHAPE -DXFT  -DNLS -DLOCALEPATH=\"/usr/local/share/blackbox/nls\" -DDEFAULTMENU=\"/usr/local/share/blackbox/menu\" -DDEFAULTSTYLE=\"/usr/local/share/blackbox/styles/Gray\" -I../lib  -O3 -march=k6-2 -mtune=k6-2 -mmmx -m3dnow 

Para facilitar las cosas, podemos crear alias de Bash, como hemos hecho anteriormente para el uso de compilador. Un ejemplo:

alias lstdc++10="export LDFLAGS+=" -Wl,-rpath,/opt/gcc11/lib64 -lstdc++"
alias lgfortran10="export LDFLAGS+=" -Wl,-rpath,/opt/gcc11/lib64 -lgfortran"
alias lgomp10="export LDFLAGS+=" -Wl,-rpath,/opt/gcc11/lib64 -lgomp"

En sistemas de 64 bits multiarquitectura los complementamos con los siguientes alias, para el modo de compilación de 32 bits.

alias lstdc++10-32="export LDFLAGS+=" -Wl,-rpath,/opt/gcc11/lib -lstdc++"
alias lgfortran10-32="export LDFLAGS+=" -Wl,-rpath,/opt/gcc11/lib -lgfortran"
alias lgomp10-32="export LDFLAGS+=" -Wl,-rpath,/opt/gcc11/lib -lgomp"



Optimizaciones de CPU para GCC

El parámetro más común utilizado en la mayor parte de los manuales ubicados en esta web, es el siguiente, lo cual no significa que sea el único posible. En determinados procesos de compilación, el uso del nivel '-O3' puede provocar la típica 'violación de segmento', cuando vayamos a ejecutar el programa.

En sistemas de 32 bits, y en paquetes de código fuente específico (en código escrito en Fortran sobre todo), el uso de optimizaciones de cpu para procesadores de 64 bits, puede provocar errores en el proceso de compilación. Para evitar esto, basta añadir el parámetro '-m32', a la variable de optimización establecida previamente. Un ejemplo:

$ export {C,CXX}FLAGS+=' -m32'

En la mayoría de los casos, y desde GCC 4.2, el parámetro 'native' hace uso de la instrucción 'cpuid' que detecta la cpu que tengamos en nuestro ordenador y aplica las optimizaciones referentes a la misma. Algunos paquetes de código fuente (mplayer, gmp, etc.) utilizan este sistema, en los scripts de configuración de los mismos.

$ export {C,CXX}FLAGS='-O3 -march=znver2 -mtune=znver2'

Donde pone znver2 se indica el procesador respectivo de cada sistema seleccionándolo de la siguiente tabla:
* La opción '-march=' establece el procesador mínimo con el que funcionará el programa compilado, la opción '-mtune=' el procesador específico para el que será optimizado. 

* Los valores separados por comas, son equivalentes, es decir, que lo mismo da poner '-march=k8' que '-march=athlon64'.

* En versiones de GCC 3.2 e inferiores se utiliza la opción '-mcpu=' en lugar de '-mtune='.
Valores CPU
Genéricos
Intel
AMD

Niveles de optimización soportados por GCC

Niveles de optimización soportados por GCC
-O Produce un binario de tamaño reducido, sin aplicar optimizaciones que alarguen el proceso de compilación, con la idea de hacer que se ejecute más rápido.
-O1
El proceso de compilación requiere de más tiempo y memoria para llevarse a cabo.
-O2 En comparación con -O Incrementa el tiempo de compilación para realizar un mayor número de optimizaciones en el binario generado.
-O3
Activa todas las optimizaciones soportadas por el nivel -O2, además de añadir 9 parámetros más de optimización.
-O0
Sin optimizaciones. Es el nivel más rápido para compilar programas y genera el código más depurable. Es el nivel predefinido de GCC.
-Os
Lo mismo que -O2, con optimizaciones adicionales para reducir el tamaño del binario resultante.
-Ofast
Activa todas las optimizaciones de -O3, junto con otras optimizaciones agresivas que pueden violar el estricto cumplimiento de los estándares del lenguaje de programación. Esta opción está disponible a partir de GCC 4.6.
-Og Activa todas las optimizaciones que no interfieran en la generación de un código binario más depurable.

Para saber exactamente las optimizaciones activadas y desactivadas según el nivel de optimización aplicado, ejecutamos el siguiente comando en una ventana de terminal. Sustituir lo que está en rojo, por el nivel de optimización del que se desee saber, las optimizaciones aplicadas.

$ gcc -O3 -Q --help=optimizers

Optimizaciones adicionales para GCC

Optimizaciones adicionales para GCC
Graphite
-ftree-loop-linear -floop-strip-mine -floop-block Activa la optimización Graphite. Puede provocar errores de compilación y de ejecución en determinados paquetes. Para poder hacer uso de la misma, GCC tiene que haberse compilado con soporte de ISL. El soporte de la optimización Graphite fue introducido a partir de GCC 4.4.

La optimización Graphite consiste en utilizar la representación de la figura geométrica del poliedro para ejecutar en paralelo los bucles de programación que contenga el código fuente de un programa, en el binario resultante del proceso de compilación, acelerando de forma considerable el tiempo de ejecución del mismo.

A estos parámetros se le puede añadir también de forma opcional y experimental, -fgraphite-identity -floop-parallelize-all. Pero pueden provocar violación de segmento tanto en el proceso de compilación como en la ejecución de los binarios resultantes del mismo, al interferir con otras opciones de optimización de GCC que se activan en función del nivel de optimización utilizado.
IPA
-fipa-pta Activa la optimización IPA (Análisis de Propagación Interprocedural) en su modo más agresivo. Otras variantes se activan de forma automática en función del nivel de optimización utilizado en el proceso de compilación. Puede provocar errores de compilación y de ejecución en determinados paquetes. Desactivado por defecto, al requerir de más memoria en el proceso de compilación y aumentar de forma considerable el tiempo de compilación en paquetes de código de gran tamaño. El soporte de la optimización IPA fue introducido a partir de GCC 4.2.

En este enlace (en inglés) podemos encontrar un ejemplo de cómo opera este modo concreto de la optimización IPA.
LTO
-fuse-linker-plugin -flto
Activa la optimización LTO. Pueden provocar errores de compilación y de ejecución en determinados paquetes. El soporte de optimizaciones LTO fue introducido a partir de GCC 4.5.

Si tenemos un procesador multinúcleo, podemos activar el uso de hilos, pasándole al parámetro el número de núcleos que tenga nuestro procesador. Si por ejemplo es un Dual-Core, utilizaremos el parámetro -flto=2.

A partir de GCC 10 se puede utilizar el parámetro -flto=auto y, el compilador detectará de forma automática el número de núcleos de nuestro procesador.

Tener en cuenta que el uso de esta optimización ralentiza el proceso de compilación, sobre todo cuando se tiene que procesar gran cantidad de archivos objeto (*.o), para generar un binario compartido.

Para hacer un uso correcto de esta optimización es necesario utilizar como enlazador dinámico predefinido, el binario ejecutable ld.gold, cuya instalación se explica en el manual de instalación de Binutils. Aunque la optimización también funciona con el normal, siempre y cuando haya sido compilado con soporte de plugins, pero el proceso de compilación es más lento.
Preguntas y Respuestas sobre las optimizaciones LTO
¿En qué consiste la aplicación de las optimizaciones LTO?
LTO son las siglas del inglés Link Time Optimization, en español comprensible y extendido, optimización del tiempo de enlazado en un proceso de compilación de binarios ejecutables. Cuando se produce el proceso de crear un archivo binario ejecutable, con los correspondiente archivos objeto, el compilador vuelca en el disco la representación interna (GIMPLE) del programa compilado en secciones especiales, tratando un conjunto de archivos objeto (*.o), requerido para crear el ejecutable, como si fuera un único archivo objeto, y aplicando la correspondiente optimización al mismo. Esto conlleva una considerable reducción del tamaño final del binario ejecutable compilado, que es básicamente la principal cualidad de esta optimización, cuando se utiliza sin el parámetro -fuse-linker-plugin.
¿Por qué tengo que utilizar el enlazador dinámico ld.gold?
Porque es más potente (multihilo) y rápido que el tradicional ld, para realizar este tipo de tareas. Además, con el uso del enlazador dinámico ld.gold y el parámetro -fuse-linker-plugin, permitimos a GCC poder extraer también archivos objeto (*.o) con GIMPLE, de las librerías de ejecución que intervienen en el proceso de enlazado, ampliando el código a optimizar y aumentando la calidad del ejecutable generado. 
¿Por qué cuando compilo un programa con optimizaciones LTO me muestra los siguientes mensajes de aviso?
BFD: obt/obt_libobt_la-display.o: plugin needed to handle lto object
BFD: obt/obt_libobt_la-keyboard.o: plugin needed to handle lto object
A partir de la versión 2.25 de Binutils se ha introducido un mensaje de aviso, que nos indica cuándo en un proceso de compilación con optimizaciones LTO y generación añadida de librerías estáticas, los programas ar, ranlib y nm del paquete de Binutils no cargan correctamente el plugin proporcionado por GCC para este cometido, requerido para que estos programas puedan manejar archivos objeto con código LTO.

Para solventar este problema, GCC desde la versión 4.7, proporciona unos ejecutables intermedios (gcc-ar, gcc-ranlib y gcc-nm) que se encargan de enviar los correspondientes parámetros de ubicación del plugin, a estos programas. Pero claro, para que estos ejecutables puedan intervenir en el proceso de compilación, tendremos que establecer las correspondientes variables de entorno AR, RANLIB y NM. Variables de entorno, que no todos los paquetes permiten cambiar al vuelo, sobre todo la primera, obligándonos a tener que modificar posteriormente los correspondientes archivos Makefile de turno. Las variables de entorno a establecer nos quedarían así:
$ export AR=gcc-ar RANLIB=gcc-ranlib NM=gcc-nm
Si la versión de GCC a utilizar es una diferente a la principal que tengamos en el sistema, o en el caso particular de este manual, fuera otra de las versiones tratadas en el mismo, las variables de entorno nos quedarían así, Un ejemplo con GCC 4.9.
$ export AR=gcc-ar49 RANLIB=gcc-ranlib49 NM=gcc-nm49
Si por ejemplo, utilizamos esto con Fluxbox, la variable AR permanece inalterable porque en el archivo Makefile.in, el archivo base de configuración tomado para crear el archivo Makefile correspondiente, viene de forma fija el programa a utilizar, es decir, el comando ar de Binutils. Esto lo solucionamos de forma rápida añadiendo una interrogación delante del término AR, cómo se ve en el ejemplo siguiente:
AR? = ar
¿Por qué cuando compilo un programa o librería que incluye librerías estáticas, con optimizaciones LTO, y lo instalo con el comando 'make install-strip', me muestra los siguientes mensajes de aviso?
libtool: install: strip --strip-debug /usr/local/lib/libtorrent-rasterbar.a
BFD: /usr/local/lib/stBfRbEY/web_connection_base.o: plugin needed to handle lto object
BFD: /usr/local/lib/stBfRbEY/alert.o: plugin needed to handle lto object
BFD: /usr/local/lib/stBfRbEY/allocator.o: plugin needed to handle lto object
BFD: /usr/local/lib/stBfRbEY/asio.o: plugin needed to handle lto object
El programa strip de Binutils, no está diseñado para poder eliminar símbolos de depuración en librerías estáticas que contengan archivos objeto con código LTO, es decir, no soporta la carga de plugins. La única solución posible a esto, si queremos eliminar dichos símbolos, porque el archivo es relativamente grande, pasa por realizar una segunda compilación del paquete sin las optimizaciones LTO activadas y con el parámetro --disable-shared, para que sólo compile las librerías estáticas. Pero existe un problema importante: si hacemos una segunda compilación del paquete, sólo en modo estático, la instalación del mismo también será en modo estático, sobreescribiendo los archivos de información (*.la) y (*.pc) que utilizan otros paquetes para saber qué tipo de librerías (compartidas o estáticas) están instaladas en nuestro sistema.

Aunque tengamos instaladas las librerías compartidas, éstas no aparecerán en los archivos de información pertinentes y, por lo tanto, las compilaciones en las que intervengan estas dependencias, la integración de los mismas, siempre será estática, aumentando de forma considerable el tamaño del binario ejecutable generado.

Así que el único método posible, es la instalación manual de las librerías estáticas, sin ejecutar el comando 'make install-strip'. A continuación pongo un ejemplo de proceso de configuración e instalación con el paquete de Libtorrent-rasterbar, en lo que concierne a la instalación manual en modo estático.
$ ./configure --disable-dependency-tracking --disable-shared
$ make
$ su
# install -sm644 src/.libs/libtorrent-rasterbar.a /usr/local/lib
# ranlib /usr/local/lib/libtorrent-rasterbar.a
Hacer sólo esto en procesos de compilación, con librerías estáticas relativamente grandes. Con archivos pequeños no merece la pena alargar el proceso de compilación del paquete, para obtener una reducción de tamaño ridícula.

Tener en cuenta que por norma general, las librerías estáticas que contienen código LTO, ocupan mucho más espacio que las normales. En el caso particular del ejemplo de libtorrent-rasterbar.a, el aumento es de 40 MB más de tamaño, respecto a la compilada de forma normal. Hasta que el programa strip no sea modificado para poder manejar código LTO, esto representa un problema añadido en el uso de estas optimizaciones.
OpenMP
-ftree-parallelize-loops=2 OpenMP es una API de programación creada única y exclusivamente para aprovechar la potencia de los procesadores multinúcleo, si el nuestro no lo es, no es necesario seguir leyendo esto. Esta optimización sólo es operativa en aquellos paquetes de código fuente que están previamente preparados para utilizarla, ImageMagick, Blender, Inkscape, etc.

El script de configuración comprueba si el compilador soporta el parámetro -fopemp y lo activa por defecto, con lo que nosotros sólo necesitamos añadir de forma opcional el parámetro -ftree-parallelize-loops=2, cambiando el número 2 por el número de núcleos que tenga nuestro procesador.

El uso de esta optimización requiere, si utilizamos una versión de GCC diferente a la principal del sistema, que el binario resultante de la compilación se enlace contra la librería libgomp de la versión de GCC con la que hemos compilado el paquete. Un ejemplo de variable de entorno a utilizar:

$ export LDFLAGS+=' -Wl,-rpath,/opt/gcc7/lib -lgomp'
PGO
-fprofile-generate=ruta a directorio

-fprofile-use=ruta a directorio
PGO son las siglas con las que se conoce a la optimización Profile Guided Optimization (Optimización Guiada por Perfiles). El compilador recopila información del total de funciones y bloques de datos que contiene el binario ejecutable, tanto en el proceso de compilación como en una posterior ejecución del mismo. Dichos datos serán utilizados en un segundo proceso de compilación, pudiendo utilizarlos en posteriores procesos de compilación, siempre y cuando, el código fuente no sea alterado de forma significativa.

La optimización PGO se divide en dos modos: instrumentación (la que explico aquí) y muestreo, que requiere del uso de aplicaciones externas como Perf y AutoFDO, realizando todo el proceso de forma manual por parte del usuario: ejecución del binario compilado con perf para obtener las muestras y su posterior conversión con AutoFDO a un formato legible por GCC.

A diferencia de las otras optimizaciones explicadas en este manual, ésta requiere de un proceso más elaborado para su aplicación, que explico a continuación:

1) Creamos un directorio de ubicación de los perfiles de optimización guiada con permisos de escritura para todos los usuarios.

$ su
# mkdir -p /var/pgo
# chmod 777 /var/pgo

2) Establecemos la variable de entorno de generación del perfil de optimización con la ruta del directorio de perfiles de optimización que hemos creado, más el nombre del paquete que vamos a compilar, por ejemplo, mc.

$ export {C,CXX}FLAGS+=' -fprofile-generate=/var/pgo/mc

3) Ejecutamos el script de configuración pertinente y compilamos el paquete. Instalamos el paquete y lo ejecutamos. Si el paquete de código fuente contiene tests, lo mejor para recopilar información es ejecutar en el mismo make check después de haber compilado el mismo (nos ahorramos tener que instalarlo). En unos paquetes esto resulta efectivo (por ejemplo, ImageMagick o POV-Ray), en otros, al ser los tests muy básicos, lo mejor es ejecutar la aplicación.

4) Volvemos a recompilar el paquete. Tenemos dos opciones, una es empezar de cero con las variables de entorno y añadir la siguiente, volviendo a ejecutar el script de configuración, después de haber limpiado el directorio de compilación con el comando make distclean o make clean según esté configurado:

$ export {C,CXX}FLAGS+=' -fprofile-use=/var/pgo/mc

La otra más rápida consiste en modificar los archivos Makefile de forma masiva, modificando el parámetro aplicado, con el siguiente comando (sólo válida si las optimizaciones iniciales y finales son las mismas):

$ find . -name 'Makefile' | xargs sed -i 's:fprofile-generate:fprofile-use:g'

Una vez los hayamos modificado, ejecutamos make clean; make y volvemos a instalar el paquete. El perfil de optimización creado lo podemos cargar de forma directa en la siguiente compilación, siempre y cuando el código fuente no haya sido alterado de forma significativa. Ya se encargará el compilador de avisarnos de esto.

Tener en cuenta que si creamos el perfil con el parámetro -O2 -g, sin ningún tipo de  optimización adicional, obtendremos más información que nos servirá para aplicar una optimización PGO más efectiva. Lo cual no quiere decir que no se pueda realizar el proceso con las mismas optimizaciones en el comienzo y en el final del mismo.

$ export {C,CXX}FLAGS+=' -fprofile-use=/var/pgo/mc

Para acelerar todo esto, siempre es bueno crearse unas funciones de Bash. Abrimos con un editor de texto, el archivo ~/.bashrc, si no existe lo creamos y añadimos lo siguiente al final del mismo:

optgcc-gpgo () { dir="$1"; export {C,CXX}FLAGS+=" -fprofile-generate=/var/pgo/$dir"; }

optgcc-upgo () { dir="$1"; export {C,CXX}FLAGS+=" -fprofile-use=/var/pgo/$dir"; }


Guardamos el archivo, abrimos una ventana de terminal, y ahora simplemente basta ejecutar el alias correspondiente para añadir la variable de entorno de esta optimización más el nombre del directorio que definamos para ubicar los datos del perfil.

Primer proceso de compilación
$ optgcc-gpgo mc

Segundo proceso de compilación
$ optgcc-upgo mc

Errores posibles de la aplicación de la optimización PGO

1) En aquellos procesos de compilación que se produzcan mensajes de error similares a éste:

undefined reference to '__gcov_init'" and "undefined reference to '__gcov_merge_add'

Establecemos la siguiente variable de entorno antes de configurar el paquete:

$ export LDFLAGS+=" -lgcov --coverage"

2) En procesos de compilación, sobre todo con las GNU Autotools, al ejecutar el script de configuración en la 2ª fase de compilación, si se produce el siguiente error (visible en el archivo de registro config.log, ya que en la terminal nos saldrá el mensaje típico de que el compilador no puede crear ejecutables):

conftest.cpp:13:1: error: number of counters in profile data for function 'main' does not match its profile data (counter 'arcs', expected 8 and have 1) [-Werror=coverage-mismatch]

Lo solucionamos estableciendo la siguiente variable de entorno antes de ejecutar el script de configuración:

$ export {C,CXX}FLAGS+=" -Wno-error=coverage-mismatch"

3) Si el error se produce en el proceso de compilación, un ejemplo con POV-Ray:

./base/image/colourspace.h:139:104: error: valor de perfil corrupto: la cuenta del perfilador ic (230260 de 230250) es inconsistente con la cuenta bloque-básico (230250)
  139 |     return Colour(p->Encode(c.red()), p->Encode(c.green()), p->Encode(c.blue()), c.filter(), c.transm());

Añadimos también la siguiente variable de entorno para corregirlo, antes de ejecutar el script de configuración del paquete:

$ export {C,CXX}FLAGS+=" -fprofile-correction"


Para añadirlas a las variables de entorno de optimización de CPU que hayamos establecido, basta ejecutar los comandos siguientes:

Graphite
$ export {C,CXX}FLAGS+=' -ftree-loop-linear -floop-strip-mine -floop-block'

IPA
$ export {C,CXX}FLAGS+=' -fipa-pta'

LTO
$ export {C,CXX}FLAGS+=' -fuse-linker-plugin -flto'

OpenMP (sólo en aquellos paquetes en los que se active por defecto el parámetro -fopenmp)
$ export {C,CXX}FLAGS+=' -ftree-parallelize-loops=2'

Donde pone 2 se indica el número de núcleos de nuestro procesador, si sólo tiene uno, no utilizar esta optimización. 



Instalar GCC 10.3.0

Instalación

Dependencias

Herramientas de Compilación


Entre paréntesis la versión con la que se ha compilado GCC 10.3.0 para la elaboración de este documento.

* GCC - (10.2.0)
* Gawk - (5.1.0)
* M4 - (1.4.18)
* Libtool - (2.4.6)
* Make - (4.3)
* Bison - (3.7.6)
* Flex - (2.6.4)
* Automake - (1.16.3)
* Autoconf - (2.71)
* Gettext - (0.21)
* Gperf - (3.1)
* Texinfo - (6.7)

Librerías de Desarrollo

* Gmp - (6.2.1)
* Mpfr - (4.1.0)
* Mpc - (1.2.0)
* ISL - (0.18)
* Libzstd - (1.4.9)



Descarga

gcc-10.3.0.tar.xz

Optimizaciones

Optimizaciones adicionales

Optimizaciones adicionales
Graphite
$ export {C,CXX}{FLAGS,FLAGS_FOR_TARGET}+=' -ftree-loop-linear -floop-strip-mine -floop-block'

Extracción y Configuración  Bloc de Notas Información general sobre el uso de los comandos

$ tar Jxvf gcc-10.3.0.tar.xz
$ mkdir gcc-build_10.3.0
$ cd gcc-build_10.3.0
$ ../gcc-10.3.0/configure --enable-shared --enable-threads=posix \
--enable-__cxa_atexit --enable-clocale=gnu --enable-languages=c,c++,fortran,objc \
--prefix=/opt/gcc9 --program-suffix=9 --with-build-config=bootstrap-O3


Explicación de los comandos

mkdir gcc-build_10.3.0
: Creamos un directorio de compilación, ya que GCC no permite que se compile directamente en el directorio de las fuentes.
--enable-shared : Compila las librerías compartidas.
--enable-threads=posix : Selecciona la librería genérica POSIX/Unix98 para el soporte de hilos.
--enable-__cxa_atexit : Opción necesaria para una correcta compilación de c++.
--enable-clocale=gnu : Evita un error en la generación de las locales, en el caso de que estén incompletas.
--enable-languages=c,c++,fortran,objc : Compila los lenguajes de programación C, C++, Fortran y Objetive C.
--prefix=/opt/gcc9 : Instala el compilador en /opt/gcc9.

--program-suffix=9 : Añadimos un sufijo a los binarios ejecutables instalados para poder diferenciarlos de otras versiones de GCC que tengamos instaladas en nuestro sistema, empezando por la principal del mismo. 

--with-build-config=bootstrap-O3 : Complementamos las optimizaciones establecidas en el manual (CFLAGS, CXXFLAGS, CFLAGS_FOR_TARGET, CXXFLAGS_FOR_TARGET) con esta que añade el nivel de optimización -O3 al proceso de compilación (modo bootstrap), y evitamos con todo el combinado que el parámetro de depuración -g, se use en la mayor parte del mismo. 

Parámetros de configuración opcionales

--with-build-config=bootstrap-lto: Aplica la optimización LTO en las fases 2 y 3 del proceso de compilación. Este parámetro se puede combinar con el predefinido que se incluye en este manual, de la siguiente forma: --with-build-config="bootstrap-O3 bootstrap-lto"

--with-build-config=bootstrap-lto-lean : Es igual que la anterior, pero sólo se aplica en la fase 3 de compilación. El principal problema de aplicar este parámetro es que la ganancia de velocidad es menor, y no merece la pena hacer uso del mismo, respecto al parámetro anterior, aunque se tarde menos en compilar el paquete.

Este parámetro se puede combinar con el predefinido que se incluye en este manual, de la siguiente forma: --with-build-config="bootstrap-O3 bootstrap-lto-lean"

--disable-bootstrap : Si por la razón que sea, tenemos que volver a recompilar el paquete, utilizando el mismo compilador de la versión que vamos a instalar, añadiendo esta opción evitaremos que el compilador se recompile a sí mismo, y anularemos el proceso predefinido de compilación en tres fases. Si la versión utilizada es de la misma serie, también se puede utilizar esta opción, aunque conlleva una pérdida de rendimiento en los binarios ejecutables resultantes. Realizar antes una copia de seguridad de la versión instalada, porque la instalación de la nueva versión sobreescribirá los archivos de la misma.

--with-default-libstdcxx-abi=gcc4-compatible : Hace compatible la versión de Libstdc++ de esta versión, con binarios compilados con versiones de la serie 4 de GCC y versiones inferiores a la 3.9 de Clang, además de las versiones superiores de GCC que se hayan compilado con esta misma opción de configuración del paquete.

Compilación

$ make BOOT_CFLAGS="${CFLAGS}"

BOOT_CFLAGS="${CFLAGS}" : Se sincronizan las optimizaciones aplicadas en el manual con las utilizadas en el modo de compilación de 3 fases (bootstrap). Esto no es necesario hacerlo si utilizamos un compilador de la misma serie y añadimos en el proceso de configuración, el parámetro --disable-bootstrap.

Parámetros de compilación opcionales  

-j$(getconf _NPROCESSORS_ONLN): Establece el número de procesos de compilación en paralelo, en función del número de núcleos e hilos que tenga nuestro procesador, tomando como referencia la información mostrada por el sistema con el comando correspondiente. Si nuestro procesador es mononúcleo de un solo hilo, no añadir esta opción.

Instalación como root

$ su -c "make install-strip"

Borrar las locales adicionales instaladas

$ su
# for i in be ca da de el eo fi fr hr id ja nl pt_BR \
ru sr sv tr tk uk vi zh_CN zh_TW ; do \
rm -rf /opt/gcc10/share/locale/$i &> /dev/null ; \
done

Borrar los directorios y archivos de instalación que hacen referencia a la versión 10.2.0, sobreescrita por esta nueva versión

Hacer sólo esto si estamos actualizando desde la versión anterior instalada siguiendo las instrucciones de este manual. Con los siguientes comandos, borramos los directorios y archivos de instalación de la versión anterior.

# find /opt/gcc10 -name '*10.2.0' | xargs rm -rf

Estadísticas de Compilación e Instalación de GCC 10.3.0

Estadísticas de Compilación e Instalación de GCC 10.3.0
CPU AMD Ryzen 3 3100 4-Core Processor
MHz 3593.246
RAM 8 GB
Sistema de archivos XFS
Versión del Kernel 5.11.12-ck1 SMP PREEMPT x86_64
Modo de frecuencia de la CPU performance
Versión de Glibc 2.33
Enlazador dinámico GNU gold (Binutils 2.36.1) 1.16
Compilador GCC 10.2.0 + Ccache 4.2.1
Parámetros de optimización -03 -march=znver2 -mtune=znver2 -ftree-loop-linear -floop-strip-mine -floop-block -flto=jobserver
Parámetros de compilación BOOT_CFLAGS="${CFLAGS}" -j8
Ocupación de espacio en disco del proceso de compilación 5,9 GB
Tiempo de compilación 1h 21' 06"
Archivos instalados 1.584
Mostrar/Ocultar la lista de archivos instalados
Enlaces simbólicos creados 49
Mostrar/Ocultar la lista de enlaces simbólicos creados
Ocupación de espacio en disco 315,0 MB

Desinstalación como root

1) MODO TRADICIONAL

En el directorio de compilación ejecutamos el siguiente comando:

$ su -c "make uninstall"

2) MODO MANUALINUX

gcc-10.3.0-scripts.tar.gz

$ su
# tar zxvf gcc-10.3.0-scripts.tar.gz
# cd gcc-10.3.0-scripts
# ./Desinstalar_gcc-10.3.0

La desinstalación del compilador no incluye las librerías compartidas (.so) para evitar problemas de dependencias en el caso de que hayamos compilado algún programa con esta versión de GCC.

Copia de Seguridad como root

$ su
# tar zxvf gcc-10.3.0-scripts.tar.gz
# cd gcc-10.3.0-scripts
# ./Respaldar_gcc-10.3.0

Restaurar la Copia de Seguridad como root

$ su
# cd /var/copibin/restaurar_copias
# ./Restaurar_gcc-10.3.0

Soporte de optimizaciones para nuevos procesadores en GCC 10

En GCC 10 se añade soporte de optimizaciones para los siguientes procesadores:

Procesadores Parámetros de optimización
Intel
Intel Cooperlake con soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VNNI, AVX512BF16 y extensiones 64-bit. -march=cooperlake -mtune=cooperlake
Intel Tigerlake con soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VBMI, AVX512IFMA, SHA, CLWB, UMIP, RDPID, GFNI, AVX512VBMI2, AVX512VPOPCNTDQ, AVX512BITALG, AVX512VNNI, VPCLMULQDQ, VAES, PCONFIG, WBNOINVD, MOVDIRI, MOVDIR64B, AVX512VP2INTERSECT y extensiones 64-bit. -march=tigerlake -mtune=tigerlake



Configurar el sistema para el uso de GCC 10.3.0

1) /etc/ld.so.conf

Añadimos la ruta a las librerías en el archivo /etc/ld.so.conf.

include ld.so.conf.d/*.conf
/usr/X11R6/lib
/usr/lib
/usr/lib/qt3/lib
/usr/local/lib
/opt/e17/lib
/opt/gcc11/lib64
/opt/gcc11/lib
/opt/gcc10/lib64
/opt/gcc10/lib

Cuando lo hayamos editado y guardado ejecutamos la actualización de la caché de las librerías compartidas.

$ su -c "ldconfig -v"

2) Añadir la ruta a los binarios y las páginas de manual a nuestro PATH

2a) Variable de entorno PATH de usuario

Editamos el archivo de nuestro home, ~/.bashrc (si no existe lo creamos) y añadimos lo siguiente al final del mismo.

export PATH=/opt/gcc10/bin:$PATH
export MANPATH=/opt/gcc10/share/man:$MANPATH


Si estamos siguiendo el manual lo añadimos a la variable de entorno anterior.

export PATH=/opt/gcc11/bin:/opt/gcc10/bin:$PATH
export MANPATH=/opt/gcc11/share/man:/opt/gcc10/share/man:$MANPATH

2b) Variable de entorno PATH del sistema

Si queremos establecer una variable de entorno global del sistema, abrimos un editor de texto y añadimos lo siguiente.

#!/bin/sh

export PATH=/opt/gcc10/bin:$PATH
export MANPATH=/opt/gcc10/share/man:$MANPATH


Si estamos siguiendo el manual lo añadimos a la variable de entorno anterior.

#!/bin/sh

export PATH=/opt/gcc11/bin:/opt/gcc10/bin:$PATH
export MANPATH=/opt/gcc11/share/man:/opt/gcc10/share/man:$MANPATH

Lo guardamos con el nombre gcc.sh, y lo instalamos en /etc/profile.d.

$ su -c "install -m755 gcc.sh /etc/profile.d"

Tenemos que cerrar el emulador de terminal y volverlo a abrir para que la variable de entorno aplicada sea efectiva. Es conveniente guardar una copia de este script para posteriores instalaciones de nuestro sistema. La ventaja de utilizar el directorio /etc/profile.d es que es común a todas las distribuciones y nos evita tener que editar otros archivos del sistema como por ejemplo, /etc/profile.

2c) Lectura de las páginas de manual

$ man gcc10
$ man gfortran9

3) Uso de GCC 10.3.0

Esto está ampliamente explicado en este apartado, sólo cambia el número del sufijo de la versión a utilizar.

$ export LDFLAGS+=' -L/usr/lib64 -L/usr/local/lib64'
$ export CC=gcc10 CXX=g++10 {FC,F90,F95,F77}=gfortran10

En cuanto a la creación de los alias de Bash para facilitar la ejecución de las variables. Abrimos con un editor de texto, el archivo de configuración personal, ~/.bashrc, si no existe lo creamos, y añadimos lo siguiente al final del contenido del mismo:

alias ldpath="export LDFLAGS+=' -L/usr/lib64 -L/usr/local/lib64'"
alias envgcc10="export CC=gcc10 CXX=g++10 {FC,F90,F95,F77}=gfortran10"


Para el caso específico que ya explico más arriba de uso de compilador Fortran con las GNU Autotools, añadimos lo siguiente:

alias envgfortran10="mkdir -p /tmp/bin; ln -sf /opt/gcc10/bin/gfortran10 /tmp/bin/gfortran; export PATH=/tmp/bin:$PATH"
alias ungfortran10="PATH=`echo $PATH | sed -e 's:/tmp/bin::'`; rm -rf /tmp/bin"

Y si queremos añadir también alias para las variables de entorno LDFLAGS para establecer el RPATH correspondiente, en compilación de código escrito en C++, Fortran, y compatible con OpenMP, nos quedaría así:

alias lstdc++10="export LDFLAGS+=" -Wl,-rpath,/opt/gcc10/lib64 -lstdc++"
alias lgfortran10="export LDFLAGS+=" -Wl,-rpath,/opt/gcc10/lib64 -lgfortran"
alias lgomp10="export LDFLAGS+=" -Wl,-rpath,/opt/gcc10/lib64 -lgomp"

En sistemas de 64 bits multiarquitectura los complementamos con los siguientes alias, para el modo de compilación de 32 bits.

alias lstdc++10-32="export LDFLAGS+=" -Wl,-rpath,/opt/gcc10/lib -lstdc++"
alias lgfortran10-32="export LDFLAGS+=" -Wl,-rpath,/opt/gcc10/lib -lgfortran"
alias lgomp10-32="export LDFLAGS+=" -Wl,-rpath,/opt/gcc10/lib -lgomp"



Instalar GCC 9.4.0

Instalación

Dependencias

Herramientas de Compilación


Entre paréntesis la versión con la que se ha compilado GCC 9.4.0 para la elaboración de este documento.

* GCC - (11.1.0)
* Gawk - (5.0.1)
* M4 - (1.4.18)
* Libtool - (2.4.6)
* Make - (4.3)
* Bison - (3.7.6)
* Flex - (2.6.4)
* Automake - (1.16.3)
* Autoconf - (2.71)
* Gettext - (0.21)
* Gperf - (3.1)
* Texinfo - (6.7)

Librerías de Desarrollo

* Gmp - (6.2.1)
* Mpfr - (4.1.0)
* Mpc - (1.2.1)
* ISL - (0.18)



Descarga

gcc-9.4.0.tar.xz

Optimizaciones

Optimizaciones adicionales

Optimizaciones adicionales
Graphite
$ export {C,CXX}{FLAGS,FLAGS_FOR_TARGET}+=' -ftree-loop-linear -floop-strip-mine -floop-block'

Extracción y Configuración  Bloc de Notas Información general sobre el uso de los comandos

$ tar Jxvf gcc-9.4.0.tar.xz
$ mkdir gcc-build_9.4.0
$ cd gcc-build_9.4.0
$ ../gcc-9.4.0/configure --enable-shared --enable-threads=posix \
--enable-__cxa_atexit --enable-clocale=gnu --enable-languages=c,c++,fortran,objc \
--prefix=/opt/gcc9 --program-suffix=9 --with-build-config=bootstrap-O3


Explicación de los comandos

mkdir gcc-build_9.4.0
: Creamos un directorio de compilación, ya que GCC no permite que se compile directamente en el directorio de las fuentes.
--enable-shared : Compila las librerías compartidas.
--enable-threads=posix : Selecciona la librería genérica POSIX/Unix98 para el soporte de hilos.
--enable-__cxa_atexit : Opción necesaria para una correcta compilación de c++.
--enable-clocale=gnu : Evita un error en la generación de las locales, en el caso de que estén incompletas.
--enable-languages=c,c++,fortran,objc : Compila los lenguajes de programación C, C++, Fortran y Objetive C.
--prefix=/opt/gcc9 : Instala el compilador en /opt/gcc9.

--program-suffix=9 : Añadimos un sufijo a los binarios ejecutables instalados para poder diferenciarlos de otras versiones de GCC que tengamos instaladas en nuestro sistema, empezando por la principal del mismo. 

--with-build-config=bootstrap-O3 : Complementamos las optimizaciones establecidas en el manual (CFLAGS, CXXFLAGS, CFLAGS_FOR_TARGET, CXXFLAGS_FOR_TARGET) con esta que añade el nivel de optimización -O3 al proceso de compilación (modo bootstrap), y evitamos con todo el combinado que el parámetro de depuración -g, se use en la mayor parte del mismo. 

Parámetros de configuración opcionales

--with-build-config=bootstrap-lto: Aplica la optimización LTO en las fases 2 y 3 del proceso de compilación. Este parámetro se puede combinar con el predefinido que se incluye en este manual, de la siguiente forma: --with-build-config="bootstrap-O3 bootstrap-lto"

--with-build-config=bootstrap-lto-lean : Es igual que la anterior, pero sólo se aplica en la fase 3 de compilación. El principal problema de aplicar este parámetro es que la ganancia de velocidad es menor, y no merece la pena hacer uso del mismo, respecto al parámetro anterior, aunque se tarde menos en compilar el paquete.

Este parámetro se puede combinar con el predefinido que se incluye en este manual, de la siguiente forma: --with-build-config="bootstrap-O3 bootstrap-lto-lean"

--disable-bootstrap : Si por la razón que sea, tenemos que volver a recompilar el paquete, utilizando el mismo compilador de la versión que vamos a instalar, añadiendo esta opción evitaremos que el compilador se recompile a sí mismo, y anularemos el proceso predefinido de compilación en tres fases. Si la versión utilizada es de la misma serie, también se puede utilizar esta opción, aunque conlleva una pérdida de rendimiento en los binarios ejecutables resultantes. Realizar antes una copia de seguridad de la versión instalada, porque la instalación de la nueva versión sobreescribirá los archivos de la misma.

--with-default-libstdcxx-abi=gcc4-compatible : Hace compatible la versión de Libstdc++ de esta versión, con binarios compilados con versiones de la serie 4 de GCC y versiones inferiores a la 3.9 de Clang, además de las versiones superiores de GCC que se hayan compilado con esta misma opción de configuración del paquete.

Compilación

$ make BOOT_CFLAGS="${CFLAGS}"

Explicación de los comandos

BOOT_CFLAGS="${CFLAGS}" : Se sincronizan las optimizaciones aplicadas en el manual con las utilizadas en el modo de compilación de 3 fases (bootstrap). Esto no es necesario hacerlo si utilizamos un compilador de la misma serie y añadimos en el proceso de configuración, el parámetro --disable-bootstrap.

Parámetros de compilación opcionales  

-j$(getconf _NPROCESSORS_ONLN) : Establece el número de procesos de compilación en paralelo, en función del número de núcleos e hilos que tenga nuestro procesador, tomando como referencia la información mostrada por el sistema con el comando correspondiente. Si nuestro procesador es mononúcleo de un solo hilo, no añadir esta opción.

Instalación como root

$ su -c "make install-strip"

Borrar las locales adicionales instaladas

$ su
# for i in be ca da de el eo fi fr hr id ja nl pt_BR \
ru sr sv tr tk uk vi zh_CN zh_TW ; do \
rm -rf /opt/gcc9/share/locale/$i &> /dev/null ; \
done

Borrar los directorios y archivos de instalación que hacen referencia a la versión 9.3.0, sobreescrita por esta nueva versión

Hacer sólo esto si estamos actualizando desde la versión anterior instalada siguiendo las instrucciones de este manual. Con los siguientes comandos, borramos los directorios y archivos de instalación de la versión anterior.

# find /opt/gcc9 -name '*9.3.0' | xargs rm -rf

Estadísticas de Compilación e Instalación de GCC 9.4.0

Estadísticas de Compilación e Instalación de GCC 9.4.0
CPU AMD Ryzen 3 3100 4-Core Processor
MHz 3593.246
RAM 16 GB
Sistema de archivos XFS
Versión del Kernel 5.12.9-ck1 SMP PREEMPT x86_64
Modo de frecuencia de la CPU performance
Versión de Glibc 2.33
Enlazador dinámico GNU gold (Binutils 2.36.1) 1.16
Compilador GCC 11.1.0 + Ccache 4.3
Parámetros de optimización -03 -march=znver2 -mtune=znver2 -ftree-loop-linear -floop-strip-mine -floop-block -flto=jobserver
Parámetros de compilación BOOT_CFLAGS="${CFLAGS}" -j8
Ocupación de espacio en disco del proceso de compilación 5,4 GB
Tiempo de compilación 56' 08"
Archivos instalados 1.580
Mostrar/Ocultar la lista de archivos instalados
Enlaces simbólicos creados 49
Mostrar/Ocultar la lista de enlaces simbólicos creados
Ocupación de espacio en disco 270,5 MB

Desinstalación como root

1) MODO TRADICIONAL

En el directorio de compilación ejecutamos el siguiente comando:

$ su -c "make uninstall"

2) MODO MANUALINUX

El principal inconveniente del comando anterior es que tenemos que tener el directorio de compilación en nuestro sistema para poder desinstalar el programa. En algunos casos esto supone muchos megas de espacio en disco. Con el paquete de scripts que pongo a continuación logramos evitar el único inconveniente que tiene la compilación de programas, y es el tema de la desinstalación de los mismos sin la necesidad de tener obligatoriamente una copia de las fuentes compiladas.

gcc-9.4.0-scripts.tar.gz

$ su
# tar zxvf gcc-9.4.0-scripts.tar.gz
# cd gcc-9.4.0-scripts
# ./Desinstalar_gcc-9.4.0

La desinstalación del compilador no incluye las librerías compartidas (.so) para evitar problemas de dependencias en el caso de que hayamos compilado algún programa con esta versión de GCC.

Copia de Seguridad como root

Con este otro script creamos una copia de seguridad de los binarios compilados, recreando la estructura de directorios de los mismos en un directorio de copias de seguridad (copibin) que se crea en el directorio /var. Cuando se haya creado el paquete comprimido de los binarios podemos copiarlo como usuario a nuestro home y borrar el que ha creado el script de respaldo, teniendo en cuenta que si queremos volver a restaurar la copia, tendremos que volver a copiarlo al lugar donde se ha creado.

$ su
# tar zxvf gcc-9.4.0-scripts.tar.gz
# cd gcc-9.4.0-scripts
# ./Respaldar_gcc-9.4.0

Restaurar la Copia de Seguridad como root

Y con este otro script (que se copia de forma automática cuando creamos la copia de respaldo del programa) restauramos la copia de seguridad como root cuando resulte necesario.

$ su
# cd /var/copibin/restaurar_copias
# ./Restaurar_gcc-9.4.0

Soporte de optimizaciones para nuevos procesadores en GCC 9

En GCC 9 se añade soporte de optimizaciones para los siguientes procesadores:

Procesadores Parámetros de optimización
Intel
Intel Cascadelake con soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, PKU, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, FMA, BMI, BMI2, F16C, RDSEED, ADCX, PREFETCHW, CLFLUSHOPT, XSAVEC, XSAVES, AVX512F, CLWB, AVX512VL, AVX512BW, AVX512DQ, AVX512CD, AVX512VNNI y extensiones 64-bit. -march=cascadelake -mtune=cascadelake
Intel Goldmont con soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PCLMUL, RDRND, XSAVE, XSAVEOPT, FSGSBASE y extensiones 64-bit. -march=goldmont -mtune=goldmont
Intel Goldmont Plus con soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PCLMUL, RDRND, XSAVE, XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, UMIP y extensiones 64-bit. -march=goldmont-plus -mtune=goldmont-plus
Intel Tremont con soporte de instrucciones MOVBE, MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, POPCNT, AES, PCLMUL, RDRND, XSAVE, XSAVEOPT, FSGSBASE, PTWRITE, RDPID, SGX, UMIP, GFNI-SSE, CLWB, ENCLV y extensiones 64-bit. -march=tremont -mtune=tremont
AMD
Procesadores basados en AMD Family 17h core con soporte de instrucciones x86-64 (BMI, BMI2, ,CLWB, F16C, FMA, FSGSBASE, AVX, AVX2, ADCX, RDSEED, MWAITX, SHA, CLZERO, AES, PCL_MUL, CX16, MOVBE, MMX, SSE, SSE2, SSE3, SSE4A, SSSE3, SSE4.1, SSE4.2, ABM, XSAVEC, XSAVES, CLFLUSHOPT, POPCNT y extensiones 64-bit). -march=znver2 -mtune=znver2

Problemas de GCC 9 con las locales cuando compilamos determinados paquetes (ya sucedía con GCC 8 y Wine)

Este problema cuyos mensajes de error suelen ser similares ya sucedía con Wine y GCC 8 (En un principio yo pensaba que era un problema con Graphite):

during GIMPLE pass: wrestrict
En la función 'convert_bitmap.constprop':
en pp_format, en pretty-print.c:1387
 static int convert_bitmap(char *data, int size)
            ^~~~~~~~~~~~~~

Pero ahora también sucede con el Kernel, Python3, etc. Y, esperemos que no se convierta en algo crónico.

during GIMPLE pass: wrestrict
En la función 'ftrace_dump':
en pp_format, en pretty-print.c:1393
 8553 | void ftrace_dump(enum ftrace_dump_mode oops_dump_mode)
      |      ^~~~~~~~~~~
Por favor, envíe un informe completo de errores,
con el código preprocesado si es apropiado.
Véase <https://gcc.gnu.org/bugs/> para instrucciones.

La solución es tan simple como establecer las locales del sistema en C con la siguiente variable de entorno antes de compilar nada:

$ export LC_ALL=C

En el caso del kernel esto no sirve porque el archivo Makefile contiene una variable de anulación que tenemos que comentar:

# Avoid funny character set dependencies
#unexport LC_ALL
LC_COLLATE=C
LC_NUMERIC=C
export LC_COLLATE LC_NUMERIC

O, como he hecho con el kernel proporcionado por esta web, dejarla así y nos ahorramos tener que establecer nada en la línea de comandos:

# Avoid funny character set dependencies
LC_ALL=C
export LC_ALL



Configurar el sistema para el uso de GCC 9.4.0

1) /etc/ld.so.conf

Añadimos la ruta a las librerías en el archivo /etc/ld.so.conf.

include ld.so.conf.d/*.conf
/usr/X11R6/lib
/usr/lib
/usr/lib/qt3/lib
/usr/local/lib
/opt/e17/lib
/opt/gcc11/lib64
/opt/gcc11/lib
/opt/gcc9/lib64
/opt/gcc9/lib

Cuando lo hayamos editado y guardado ejecutamos la actualización de la caché de las librerías compartidas.

$ su -c "ldconfig -v"

2) Añadir la ruta a los binarios y las páginas de manual a nuestro PATH

2a) Variable de entorno PATH de usuario

Editamos el archivo de nuestro home, ~/.bashrc (si no existe lo creamos) y añadimos lo siguiente al final del mismo.

export PATH=/opt/gcc9/bin:$PATH
export MANPATH=/opt/gcc9/share/man:$MANPATH


Si estamos siguiendo el manual lo añadimos a la variable de entorno anterior.

export PATH=/opt/gcc10/bin:/opt/gcc9/bin:$PATH
export MANPATH=/opt/gcc10/share/man:/opt/gcc9/share/man:$MANPATH

2b) Variable de entorno PATH del sistema

Si queremos establecer una variable de entorno global del sistema, abrimos un editor de texto y añadimos lo siguiente.

#!/bin/sh

export PATH=/opt/gcc9/bin:$PATH
export MANPATH=/opt/gcc9/share/man:$MANPATH


Si estamos siguiendo el manual lo añadimos a la variable de entorno anterior.

#!/bin/sh

export PATH=/opt/gcc10/bin:/opt/gcc9/bin:$PATH
export MANPATH=/opt/gcc10/share/man:/opt/gcc9/share/man:$MANPATH

Lo guardamos con el nombre gcc.sh, y lo instalamos en /etc/profile.d.

$ su -c "install -m755 gcc.sh /etc/profile.d"

Tenemos que cerrar el emulador de terminal y volverlo a abrir para que la variable de entorno aplicada sea efectiva. Es conveniente guardar una copia de este script para posteriores instalaciones de nuestro sistema. La ventaja de utilizar el directorio /etc/profile.d es que es común a todas las distribuciones y nos evita tener que editar otros archivos del sistema como por ejemplo, /etc/profile.

2c) Lectura de las páginas de manual

$ man gcc9
$ man gfortran9

3) Uso de GCC 9.4.0

Esto está ampliamente explicado en este apartado, sólo cambia el número del sufijo de la versión a utilizar.

$ export LDFLAGS+=' -L/usr/lib64 -L/usr/local/lib64'
$ export CC=gcc9 CXX=g++9 {FC,F90,F95,F77}=gfortran9

En cuanto a la creación de los alias de Bash para facilitar la ejecución de las variables. Abrimos con un editor de texto, el archivo de configuración personal, ~/.bashrc, si no existe lo creamos, y añadimos lo siguiente al final del contenido del mismo:

alias ldpath="export LDFLAGS+=' -L/usr/lib64 -L/usr/local/lib64'"
alias envgcc9="export CC=gcc9 CXX=g++9 {FC,F90,F95,F77}=gfortran9"


Para el caso específico que ya explico más arriba de uso de compilador Fortran con las GNU Autotools, añadimos lo siguiente:

alias envgfortran9="mkdir -p /tmp/bin; ln -sf /opt/gcc9/bin/gfortran9 /tmp/bin/gfortran; export PATH=/tmp/bin:$PATH"
alias ungfortran9="PATH=`echo $PATH | sed -e 's:/tmp/bin::'`; rm -rf /tmp/bin"

Y si queremos añadir también alias para las variables de entorno LDFLAGS para establecer el RPATH correspondiente, en compilación de código escrito en C++, Fortran, y compatible con OpenMP, nos quedaría así:

alias lstdc++9="export LDFLAGS+=" -Wl,-rpath,/opt/gcc9/lib64 -lstdc++"
alias lgfortran9="export LDFLAGS+=" -Wl,-rpath,/opt/gcc9/lib64 -lgfortran"
alias lgomp9="export LDFLAGS+=" -Wl,-rpath,/opt/gcc9/lib64 -lgomp"

En sistemas de 64 bits multiarquitectura los complementamos con los siguientes alias, para el modo de compilación de 32 bits.

alias lstdc++9-32="export LDFLAGS+=" -Wl,-rpath,/opt/gcc9/lib -lstdc++"
alias lgfortran9-32="export LDFLAGS+=" -Wl,-rpath,/opt/gcc9/lib -lgfortran"
alias lgomp9-32="export LDFLAGS+=" -Wl,-rpath,/opt/gcc9/lib -lgomp"




Foro Galería Blog


Página - 1Página - 2

Actualizado el 28-07-2021

Instalar GCC desde cero

Instalar Dependencias para GCCInstalar Java en GNU/Linux