Distcc/Compilación cruzada

From Gentoo Wiki
< Distcc
Jump to:navigation Jump to:search
This page is a translated version of the page Distcc/Cross-Compiling and the translation is 100% complete.


Esta guía le muestra al lector cómo configurar distcc para realizar compilación cruzada entre diferentes arquitecturas de procesador.

Compilación cruzada con distcc

Introducción

distcc es una herramienta que permite compartir la carga de compilación de software entre varios computadores en una red. Mientras todos los computadores usen las mismas herramientas de sistema (toolchain) construidas para la misma arquitectura de procesador no hace falta ninguna configuración especial para distcc.

Esta guía ofrece instrucciones sobre cómo configurar distcc para compilar en distintas arquitecturas.

Hacer emerge de la utilidades necesarias

En primer lugar necesitará hacer emerge de crossdev en cada uno de los equipos involucrados en el proceso de compilación. La herramienta crossdev hace más fácil la construcción de herramientas de sistema para arquitecturas de forma cruzada. Su uso es sencillo: crossdev -t sparc construirá un conjunto de herramientas de sistema cruzado para la arquitectura sparc. Esto incluye binutils, gcc, glibc y linux-headers.

Necesitará hacer emerge de la cadena de herramientas para compilación cruzada adecuada en todos los equipos que vayan a participar. Si necesita más ayuda, lance crossdev --help.

Si desea realizar un ajuste fino de la cadena de herramientas de compilación cruzada, a continuación se muestra un guión que producirá una línea de comandos con las versiones exactas de los paquetes de desarrollo cruzado que deben ser construidos en los equipos que participan en la compilación (El guión se debe lanzar en el equipo destino).

CÓDIGO Guión para realizar un ajuste fino de las herramientas de desarrollo
#!/bin/bash
BINUTILS_VER=$(qatom -F '%{PV}' $(qfile -v $(realpath /usr/bin/ld) | cut -d' ' -f1))
GCC_VER=$(qatom -F '%{PV}' $(qfile -v $(realpath /usr/bin/gcc) | cut -d' ' -f1))
KERNEL_VER=$(qatom -F '%{PV}' $(qlist -Ive sys-kernel/linux-headers))
LIBC_VER=$(qatom -F '%{PV}' $(qlist -Ive sys-libs/glibc))
echo "crossdev --b '~${BINUTILS_VER}' --g '~${GCC_VER}' --k '~${KERNEL_VER}' --l '~${LIBC_VER}' -t $(portageq envvar CHOST)"

A continuación necesitará hacer emerge de distcc en todas las máquinas involucradas en el proceso. Esto incluye la máquina en la que lanzará emerge y las máquinas con los compiladores cruzados. Por favor, lea la Documentación sobre Distcc de Gentoo para obtener más información acerca de cómo configurar y usar distcc.

Nota
Las versiones actuales de crossdev tienen un ajuste -S (--stable) para instalar únicamente las versiones estables de las herramientas de compilación (esto es, crossdev -t i686-pc-linux-gnu --stable --ex-gcc --ex-gdb --portage --pretend). Sin esta opción, crossdev instala los últimos paquetes experimentales de la herramientas de compilación!. Cuando se utiliza esta opción ya no es necesario el guión de arriba a menos que se hayan desenmascarado versiones específicas de los paquetes de herramientas o ficheros de cabecera.

Notas específicas de las arquitecturas

Nota
Se puede obtener la arquitectura echando un vistazo a la variable CHOST del destino de la compilación en /etc/make.conf. Cuando se ensambla el nombre de arquitectura para la opción crossdev -t, crossdev intentará de buen grado instalar las herramientas utilizando el nombre de la arquitectura que se ha ensamblado para los nombres de los directorios dentro de /usr (esto es, /usr/i686-pc-linux-gnu/, /usr/i686-linux-gnu/, ...). Para arreglar esto se debe indicar cada nombre de arquitectura ensamblado o nombre de directorio a crossdev --clean para desinstalarlo o eliminar manualmente los directorios dentro del sistema.

Subarquitecturas Intel x86

Si está realizando una compilación cruzada entre distintas subarquitecturas de Intel x86 (por ejemplo i586 e i686), deberá construir una cadena de herramientas completa para el CHOST deseado o de lo contrario la construcción fallará. Esto es debido a que i586 e i686 son realmente CHOSTs diferentes a pesar del hecho de que ambos se consideran "x86". Por favor, recuerde esto cuando construya cadenas de herramientas de compilación cruzada. Por ejemplo, si la máquina destino es una i586 esto significa que debe construir cadenas de herramientas de compilación cruzada para i586 en sus máquinas participantes i686.

SPARC

El uso de crossdev -t sparc podría fallar arrojando los siguientes errores:

CÓDIGO Errores mostrados cuando se lanza crossdev -t sparc
linker with -z relro support required
support for the tls_model attribute is required
this configuration requires -mlong-double-128 support

Si esto sucede, intente utilizar la siguiente orden:

user $crossdev --lenv "CC=sparc-unknown-linux-gnu-gcc" -t sparc-unknown-linux-gnu

Configurar distcc para realizar compilaciones cruzadas correctas

Nota
La solución alternativa tal y como se describe en esta sección ya no es necesaria desde distcc-3.2, ya que la funcionalidad para reemplazar las llamadas al compilador con el nombre completo del compilador ya se han implementado en el propio distcc desde esa versión.

En la configuración por defecto de distcc, la compilación cruzada "no" funcionará correctamente. El problema es que muchos paquetes llaman a gcc en lugar de usar el nombre completo (por ejemplo, sparc-unknown-linux-gnu-gcc). Cuando esta tarea de compilación se distribuye a un equipo participante, se invoca al compilador nativo en lugar del compilador cruzado.

Por suerte, existe una solución a este pequeño problema. Lo único que se requiere es un guión o envoltorio y algunos enlaces simbólicos en el equipo que lanza la orden emerge. Usaremos un equipo Sparc como ejemplo. Donde quiera que vea sparc-unknown-linux-gnu más abajo, sustitúyalo por su propio CHOST (por ejemplo, x86_64-pc-linux-gnu para un equipo AMD64). Al hacer emerge de distcc, el directorio /usr/lib/distcc/bin tendrá el siguiente aspecto:

Nota
Las siguientes órdenes se deben lanzar únicamente en la máquina que invoca a emerge. No realice estos pasos en el resto de máquinas participantes.
root #cd /usr/lib/distcc/bin
root #ls -l
total 0
lrwxrwxrwx 1 root root 15 Dec 23 20:13 c++ -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 Dec 23 20:13 cc -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 Dec 23 20:13 g++ -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 Dec 23 20:13 gcc -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 Dec 23 20:13 sparc-unknown-linux-gnu-c++ -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 Dec 23 20:13 sparc-unknown-linux-gnu-g++ -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 Dec 23 20:13 sparc-unknown-linux-gnu-gcc -> /usr/bin/distcc 

Esto es lo que debe hacer:

root #rm c++ g++ gcc cc

A continuación crearemos un guión nuevo para esta máquina. Use su editor de texto preferido y cree un archivo con el siguiente texto, luego guárdelo como sparc-unknown-linux-gnu-wrapper. Recuerde cambiar el CHOST (en este caso sparc-unknown-linux-gnu) a la definición de CHOST del equipo que correrá emerge.

CÓDIGO El nuevo guión envoltorio
#!/bin/bash
exec /usr/lib/distcc/bin/sparc-unknown-linux-gnu-g${0:$[-2]} "$@"

A continuación haremos que el guión sea ejecutable y crearemos los enlaces simbólicos adecuados:

root #chmod a+x sparc-unknown-linux-gnu-wrapper
root #ln -s sparc-unknown-linux-gnu-wrapper cc
root #ln -s sparc-unknown-linux-gnu-wrapper gcc
root #ln -s sparc-unknown-linux-gnu-wrapper g++
root #ln -s sparc-unknown-linux-gnu-wrapper c++

Cuando haya terminado, /usr/lib/distcc/bin tendrá el siguiente aspecto:

root #ls -l
total 4
lrwxrwxrwx 1 root root 25 Jan 18 14:20 c++ -> sparc-unknown-linux-gnu-wrapper
lrwxrwxrwx 1 root root 25 Jan 18 14:20 cc -> sparc-unknown-linux-gnu-wrapper
lrwxrwxrwx 1 root root 25 Jan 18 14:20 g++ -> sparc-unknown-linux-gnu-wrapper
lrwxrwxrwx 1 root root 25 Jan 18 14:20 gcc -> sparc-unknown-linux-gnu-wrapper lrwxrwxrwx 1 root root 15 Nov 21 10:42 sparc-unknown-linux-gnu-c++ -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 Nov 21 10:42 sparc-unknown-linux-gnu-g++ -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 Jul 27 10:52 sparc-unknown-linux-gnu-gcc -> /usr/bin/distcc
-rwxr-xr-x 1 root root 70 Jan 18 14:20 sparc-unknown-linux-gnu-wrapper
Nota
En las nuevas versiones de distcc ya no son necesarios los siguientes pasos, se puede hacer en su lugar emerge de distcc en el cliente con el ajuste USE crossdev habilitado para obtener el mismo resultado.

A continuación queremos asegurarnos de que estos envoltorios están disponibles después de actualizar el paquete distcc ya que se sobrescribirán los enlaces simbólicos. Podemos hacer esto a través del fichero /etc/portage/bashrc que tiene el siguiente aspecto:

ARCHIVO /etc/portage/bashrc
case ${CATEGORY}/${PN} in
                 sys-devel/distcc | sys-devel/gcc | sys-devel/clang)
			if [ "${EBUILD_PHASE}" == "postinst" ]; then
				/usr/local/sbin/distcc-fix &
			fi
		;;
esac

A continuación, crear uno de los siguientes ficheros según aplique. Si no está utilizando clang:

ARCHIVO /usr/local/sbin/distcc-fix
#!/bin/bash                     
sleep 20
# Extramenos $TUPLE desde make.conf para evitar tener que editar el guión para cada arquitectura.
TUPLE=$(portageq envvar CHOST)
GCC_VER=$(gcc-config -c|cut -d "-" -f5)
cd /usr/lib/distcc/bin
rm cc c++ gcc g++ gcc-${GCC_VER} g++-${GCC_VER} ${TUPLE}-wrapper
echo '#!/bin/bash' > ${TUPLE}-wrapper
echo "exec ${TUPLE}-g\${0:\$[-2]}" "\"\$@\"" >> ${TUPLE}-wrapper
chmod 755 ${TUPLE}-wrapper
ln -s ${TUPLE}-wrapper cc
ln -s ${TUPLE}-wrapper c++
ln -s ${TUPLE}-wrapper gcc
ln -s ${TUPLE}-wrapper g++
ln -s ${TUPLE}-wrapper gcc-${GCC_VER}
ln -s ${TUPLE}-wrapper g++-${GCC_VER}

Si está usando clang:

ARCHIVO /usr/local/sbin/distcc-fix
#!/bin/bash	                
# Compatible con clang, ahora sus ebuilds >chromium-65 utilizarán distcc tal y como lo hacían antes ;) 
sleep 20
# Extraemos $TUPLE desde make.conf para evitar tener que editar el guión para cada arquitectura.
TUPLE=$(portageq envvar CHOST)
GCC_VER=$(gcc-config -c|cut -d "-" -f5)
CLANG_VER=$(clang --version|grep version|cut -d " " -f3|cut -d'.' -f1,2)
cd /usr/lib/distcc/bin
rm cc c++ gcc g++ gcc-${GCC_VER} g++-${GCC_VER} clang clang++ clang-${CLANG_VER} clang++-${CLANG_VER} ${TUPLE}-wrapper ${TUPLE}-clang-wrapper 
echo '#!/bin/bash' > ${TUPLE}-wrapper
echo "exec ${TUPLE}-g\${0:\$[-2]}" "\"\$@\"" >> ${TUPLE}-wrapper
echo '#!/bin/bash' > ${TUPLE}-clang-wrapper
echo "exec ${TUPLE}-\$(basename \${0}) \"\$@\"" >> ${TUPLE}-clang-wrapper
chmod 755 ${TUPLE}-wrapper
chmod 755 ${TUPLE}-clang-wrapper
ln -s ${TUPLE}-wrapper cc
ln -s ${TUPLE}-wrapper c++
ln -s ${TUPLE}-wrapper gcc
ln -s ${TUPLE}-wrapper g++
ln -s ${TUPLE}-wrapper gcc-${GCC_VER}
ln -s ${TUPLE}-wrapper g++-${GCC_VER}
ln -s ${TUPLE}-clang-wrapper clang
ln -s ${TUPLE}-clang-wrapper clang++
ln -s ${TUPLE}-clang-wrapper clang-${CLANG_VER}
ln -s ${TUPLE}-clang-wrapper clang++-${CLANG_VER}

Asignar los permisos apropiados:

root #chmod 755 /usr/local/sbin/distcc-fix

¡Enhorabuena!. Probablemente tenga ahora una configuración de compilación cruzada con distcc en funcionamiento.

Como funciona esto

Cuando llamamos a distcc, comprueba que se ha invocado (por ejemplo, como i686-pc-linux-gnu-gcc, sparc-unknown-linux-gnu-g++, etc.). Entonces, cuando distcc distribuya la tarea de compilación a un equipo participante, pasa también el mismo nombre con el que se llamó. El demonio distcc en el equipo participante busca un binario con el mismo nombre. Si solo ve gcc, buscará gcc, que probablemente será el compilador nativo en el equipo participante si la arquitectura no es la misma que el equipo que corre emerge. Cuando pasamos el nombre "completo" del compilador (por ejemplo sparc-unknown-linux-gnu-gcc), entonces no habrá confusión.

Resolución de problemas

Esta sección cubre algunos problemas comunes cuando se utiliza distcc para realizar una compilación cruzada.

Remote host distccd COMPILE ERRORS

Cuando se lee el mensaje COMPILE ERRORS dentro del fichero /var/log/distccd.log de un equipo remoto, lea las notas de arriba que se refieren a la especificación correcta del nombre de arquitectura (esto es, crossdev -t $DESTINO).

Otra solución es desinstalar y volver a instalar las herramientas de compilación crossdev usando la opción crossdev --clean o asegurándose de que ya no existe /usr/$TARGET e instalar completamente el compilador cruzado a continuación.

Se recomienda editar el fichero /usr/$DESTINO/etc/portage/make.conf, del equipo remoto y asegurarse de que los valores de la variable CFLAGS son los mismos en todos los equipos que participan en las operaciones de compilación. También asegúrese de que los ajustes USE para el compilador cruzado son suficientes si construyó GCC con USE=graphite en el cliente, necesitará también una línea como cross-i686-pc-linux-gnu/gcc graphite en /etc/portage/package.use.

Failed to exec $DESTINO-unknown-linux-gnu-gcc: No such file or directory

Los guiones envoltorio pueden fallar en su ejecución incluso con los permisos correctos:

CÓDIGO Mensaje de error del guión envoltorio
distcc[6195] (dcc_execvp) ERROR: failed to exec i686-unknown-linux-gnu-gcc: No such file or directory

Para arreglar esto, asegúrese de haber creado el guión envoltorio con el nombre completo de la arquitectura destino:

user $ls -alh /usr/lib/distcc/bin/c++
/usr/lib/distcc/bin/c++ ->./i686-pc-linux-gnu-wrapper

Véase también

  • Crossdev — a set of bash scripts that utilize emerge to provide a system integrated cross-compilation capability.

This page is based on a document formerly found on our main website gentoo.org.
The following people contributed to the original document: Andrew Gaffney, Joshua Saddler
They are listed here because wiki history does not allow for any external attribution. If you edit the wiki article, please do not add yourself here; your contributions are recorded on each article's associated history page.