Instalar GCC

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

Librarias requeridas:

Una sería de librerías requeridas para poder lograr la implementación de GCC son necesarias, entre las que encontramos:

Todas estás librerías serán instaladas en el directorio /opt/util_compiler, por lo que los prefix requeridos deben apuntar a esa ruta.

TIP: Al momento de realizar el ./configure podemos indicar qué compilador instalado en el sistema podemos utilizar para la compilación mediante la variable de entorno CC. En este ejemplo se indica la versión 8 de gcc.

./configure CC=gcc-8

GMP

Descargar el paquete de gmp. Actualmente se está utilizando la versión 6.1.0

wget ftp://gcc.gnu.org/pub/gcc/infrastructure/gmp-6.1.0.tar.bz2

Una vez descargado ejecutamos los siguientes pasos:

bunzip2 gmp-6.1.0.tar.bz2
tar xvf gmp-6.1.0.tar
cd gmp-6.1.0
./configure --disable-shared --enable-static --prefix=/opt/util_compiler/
make
make check

Luego instalar como súper usuario (root)

make install

MPFR

Descargar la versión actual (3.1.4) de MPFR desde la siguiente urlftp://gcc.gnu.org/pub/gcc/infrastructure/mpfr-3.1.4.tar.bz2 usando wget,

wget ftp://gcc.gnu.org/pub/gcc/infrastructure/mpfr-3.1.4.tar.bz2

Ejecutar los siguientes pasos:

bunzip2 mpfr-3.1.4.tar.bz2
tar xvf mpfr-3.1.4.tar
cd mpfr-3.1.4
./configure --disable-shared --enable-static --prefix=/opt/util_compiler --with-gmp=/opt/util_compiler
make && make check

Y como super usuario

make install

MPC

Descargar e instalar la versión 1.0.3 siguiendo los siguientes pasos:

wget ftp://gcc.gnu.org/pub/gcc/infrastructure/mpc-1.0.3.tar.gz
tar zxvf mpc-1.0.3.tar.gz
cd mpc-1.0.3
./configure --disable-shared --enable-static --prefix=/opt/util_compiler --with-gmp=/opt/util_compiler --with-mpfr=/opt/util_compiler
make -j<cpu a utilizar> && make check

Como usuario root:

make install

ISL

La versión a utilizar será 0.16.1

wget ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-0.16.1.tar.bz2
./configure --with-gmp-prefix=/opt/util_compiler --disable-shared --enable-static --prefix=/opt/util_compiler
make -j<cpu a utilizar>

Como usuario root:

make install

GCC 7.1.0

Descargar el source desde la url oficial, https://ftp.gnu.org/gnu/gcc/gcc-7.1.0/gcc-7.1.0.tar.gz y descomprimir

Podemos ver el listado de otras versiones disponibles en https://ftp.gnu.org/gnu/gcc/

wget https://ftp.gnu.org/gnu/gcc/gcc-7.1.0/gcc-7.1.0.tar.gz

tar xvf gcc-7.1.0.tar.gz

Creamos un directorio de compilación, ya que las últimas versiones de GCC no permite que se compile directamente en el directorio de las fuentes,

mkdir build_gcc

cd build_gcc

El siguiente paso es compilar

../gcc-7.1.0/configure --enable-shared --enable-threads=posix --enable-__cxa_atexit \
--enable-clocale=gnu --enable-languages=c,c++,fortran,objc \
--prefix=/path/to/install --disable-multilib \
--with-gmp=/opt/util_compiler \
--with-mpc=/opt/util_compiler \
--with-mpfr=/opt/util_compiler \
--with-isl=/opt/util_compiler
make -j<cpu a utilizar>

El prefix podría ser: --prefix=/opt/gcc/v7.1.0

La razón de los comandos efectuados en el config vea aquí

Errores conocidos (compilando gcc 7.1.0 utilizando gcc 8.3.0):

"error: dereferencing pointer to incomplete type ‘struct ucontext’"

ver: https://github.com/openwrt/packages/issues/7202

OK, i have solved this problem temporary. Here is a very ugly solution.

build_gcc/x86_64-pc-linux-gnu/libgcc/md-unwind-support.h

Fix1:@line 61:
if (*(unsigned char *)(pc+0) == 0x48
      && *(unsigned long long *)(pc+1) == RT_SIGRETURN_SYSCALL)
    {
      // struct ucontext *uc_ = context->cfa;
        ucontext_t *uc_ = context->cfa;
      /* The void * cast is necessary to avoid an aliasing warning.
         The aliasing warning is correct, but should not be a problem
         because it does not alias anything.  */
      sc = (struct sigcontext *) (void *) &uc_->uc_mcontext;
    }

Fix2:@line144
    {
      struct rt_sigframe {
        int sig;
        siginfo_t *pinfo;
        void *puc;
        siginfo_t info;
        // struct ucontext uc;
        ucontext_t uc;
      } *rt_ = context->cfa;

"error: dereferencing pointer to incomplete type ‘struct ucontext’"

ver https://wiyogo.com/articles/2019/how-to-easily-build-an-old-gcc-in-fedora-29.html

  1. remove the included header in the line 157,
  2. remove its usage in the line 250 which contains this code:
    unsigned struct_ustat_sz = sizeof(struct ustat);

Instalar

make install-strip

Característica importante

A partir de GCC 7 se ha introducido una nueva función ("divmoddi4()") en libgcc para poder dividir un entero de 64 bits en sistemas de 32 bits (en los de 64 no es necesaria porque ya lo hace la CPU), rompiendo la compatibilidad de esta librería con versiones anteriores de GCC, e impidiendo una correcta compilación y ejecución de los binarios escritos en C, que requieran de un enlazado contra libgcc_s.so. Ni siquiera el establecimiento de un RPATH en el proceso de compilación, garantiza una compilación exitosa, ya que en el mismo momento que una dependencia esté enlazada contra la versión principal de libgcc del sistema o cualquier otra de otra versión, la compilación no se podrá llevar a cabo, mostrando mensajes de error similares al siguiente:

/opt/gcc44/lib/libgcc_s.so.1: version `GCC_7.0.0' not found (required by /usr/lib/libcairo.so.2)

La única solución posible a esto pasa por recompilar todo el código escrito en C que esté enlazado contra la versión de libgcc que tengamos en nuestro sistema, estableciendo esta versión como la principal, y sustituyendo el enlace simbólico de libgcc_s.so ubicado en /usr/lib por otro que apunte a la ruta de instalación de GCC 7. La solución es drástica, pero no existe otra posible. Bueno, sí existe, pasarnos a un sistema de 64 bits, con el trabajo extra que conlleva tener que compilar librerías duplicadas, o simplemente, no utilizar esta versión de GCC para compilar programas o librerías.

Agregar a GCC por defecto

Creamos el fichero gcc.sh en /etc/profile.d/ con el siguiente contenido:

GCC_PATH=/path/to/ggc/install
export PATH={$GCC_PATH}/bin:$PATH
export MANPATH=${GCC_PATH}/share/man:$MANPATH
export LD_LIBRARY_PATH=$GCC_PATH/lib64:$LD_LIBRARY_PATH

(no olvidar la cabecera #!/bin/sh)

Creamos links simbólicos para aplicaciones cc y c++

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

Probamos

cc --version
cc (GCC) 7.1.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

c++ --version
c++ (GCC) 7.1.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

GCC 6.4.0

Descargamos desde la url https://ftp.gnu.org/gnu/gcc/gcc-6.4.0/gcc-6.4.0.tar.gz utilizando wget y descomprimimos

wget https://ftp.gnu.org/gnu/gcc/gcc-6.4.0/gcc-6.4.0.tar.gz
tar xvf gcc-6.4.0.tar.gz

Procedemos a compilar:

mkdir build_gcc
cd build_gcc
../gcc-6.3.0/configure --enable-shared --enable-threads=posix --enable-__cxa_atexit \
--enable-clocale=gnu --enable-languages=c,c++,fortran,objc \
--prefix=/path/to/install --disable-multilib \
--with-gmp=/opt/util_compiler \
--with-mpc=/opt/util_compiler \
--with-mpfr=/opt/util_compiler \
--with-isl=/opt/util_compiler
make -j<cpu a utilizar>

La razón de los comandos efectuados en el config vea aquí

Instalamos como root

make install-strip

GCC 6.3.0

Descargamos desde la url https://ftp.gnu.org/gnu/gcc/gcc-6.3.0/gcc-6.3.0.tar.gz utilizando wget y descomprimimos

wget https://ftp.gnu.org/gnu/gcc/gcc-6.3.0/gcc-6.3.0.tar.gz
tar xvf gcc-6.3.0.tar.gz

Procedemos a compilar:

mkdir build_gcc
cd build_gcc
../gcc-6.3.0/configure --enable-shared --enable-threads=posix --enable-__cxa_atexit \
--enable-clocale=gnu --enable-languages=c,c++,fortran,objc \
--prefix=/path/to/install --disable-multilib \
--with-gmp=/opt/util_compiler \
--with-mpc=/opt/util_compiler \
--with-mpfr=/opt/util_compiler \
--with-isl=/opt/util_compiler
make -j<cpu a utilizar>

La razón de los comandos efectuados en el config vea aquí

Instalamos como root

make install-strip

Podemos editar (crear) el archivo $HOME/.bachrc y agregar las siguientes lineas:

GCC_PATH=/ruta/gcc-920
export PATH=$GCC_PATH/bin/:$PATH
export MANPATH=$GCC_PATH/share/man:$MANPATH
export LD_LIBRARY_PATH=$GCC_PATH/lib64:$LD_LIBRARY_PATH

Este script se ejecutará al ingreasar a la cuenta de usuario o bien podemos directamente ejecutarlo:

source .bashrc

Explicación de los comandos utilizados en el configure

Opcionales:

Referencias

http://manualinux.eu/gcc.html

https://stackoverflow.com/questions/9450394/how-to-install-gcc-piece-by-piece-with-gmp-mpfr-mpc-elf-without-shared-libra

cluster/gcc (última edición 2021-04-21 20:07:05 efectuada por AlejandroValdes)