Como ya sabemos por este articulo anterior es posible configurar Gentoo para que la compilación de los ebuilds se distribuya entre diferentes nodos de compilación, pero este método tenÃa una limitación y es que todos los equipos debÃan compartir arquitectura. En este manual vamos a solventar el problema y conseguiremos que distcc compile para otra arquitectura distinta a la que está corriendo.
En mi caso voy a configurar un servidor de compilación con arquitectura amd64 y una RaspBerryPi con arquitectura ARM.
Lo primero será instalar distcc tanto en los servidores de compilación como en la Rasp:
Para que la magia sea posible tendremos que instalar crossdev en el servidor ya que son las herramientas necesarias para compilar las toolchains para otra arquitectura:
Ahora necesitaremos mantener dos profiles, unos para la arquitectura del server y otro para la de la rasp, para ello es preciso tener los ebuilds de /etc/portage en formato directorio:
!/bin/bash
PROFILE_DIR="/etc/portage"
if [ ! -e ${PROFILE_DIR} ]; then
mkdir ${PROFILE_DIR};
fi;
for PACK_DIR in package.accept_keywords package.keywords package.use package.unmask package.mask; do
CUR_DIR="${PROFILE_DIR}/${PACK_DIR}"
if [ ! -e ${CUR_DIR} ]; then
mkdir ${CUR_DIR}
fi
if [ -e ${CUR_DIR} -a ! -d ${CUR_DIR} ]; then
mv ${CUR_DIR} ${CUR_DIR}.moving
mkdir ${CUR_DIR}
mv ${CUR_DIR}.moving ${CUR_DIR}/monolithic
fi
done
echo "Completed!"
Compilamos las toolchains:
Si la compialción falla podemos intentarlo del siguiente modo:
Añadimos la ip de la RaspberryPi a la configuración de distcc:
DISTCCD_OPTS="${DISTCCD_OPTS} --allow IP_RASP/32"
Terminamos de configurar distcc:
chown distcc /var/log/distccd.log
rc-update add distccd default
/etc/init.d/distccd start
En la Rasp:
MAKEOPTS="-jN -lM"
FEATURES="distcc buildpkg"
NOTA: N = Nº de equipos que compilarán código(local y remotos) + 1, M = Nº de cores locales, M se utiliza cuando la compilación sea local.
- distcc –> Utiliza discc para repartir la carga de compilación ;)
- buildpkg –> Generará paquetes binarios para todos los paquetes que ordene compilar, asà podremos utilizar esta rasp como servidor de paquetes.
DISTCCD_OPTS="--port 3632 --log-level notice --log-file /var/log/distccd.log -N 15 --allow 1.1.1.1"
NOTA: En realidad la Rasp no compilará código para nadie pero en versiones recientes de distcc nos obliga a configurar al menos una ip asà que le metemos 1.1.1.1
A distcc tendremos que indicarle la arquitectura a emplear, lo que haremos será un script intermedio:
ls -la
lrwxrwxrwx 1 root root 15 abr 7 16:30 armv6j-hardfloat-linux-gnueabi-c++ -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 abr 7 16:30 armv6j-hardfloat-linux-gnueabi-g++ -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 abr 7 16:30 armv6j-hardfloat-linux-gnueabi-gcc -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 abr 7 16:30 c++ -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 abr 7 16:30 cc -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 abr 7 16:30 g++ -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 abr 7 16:30 gcc -> /usr/bin/distcc
#!/bin/bash
exec /usr/lib/distcc/bin/armv6j-hardfloat-linux-gnueabi-g${0:$[-2]} "$@"
chmod a+x /usr/lib/distcc/bin/armv6j-hardfloat-linux-gnueabi-wrapper
ln -s armv6j-hardfloat-linux-gnueabi-wrapper cc
ln -s armv6j-hardfloat-linux-gnueabi-wrapper gcc
ln -s armv6j-hardfloat-linux-gnueabi-wrapper g++
ln -s armv6j-hardfloat-linux-gnueabi-wrapper c++
ls -la
lrwxrwxrwx 1 root root 15 abr 7 16:30 armv6j-hardfloat-linux-gnueabi-c++ -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 abr 7 16:30 armv6j-hardfloat-linux-gnueabi-g++ -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 abr 7 16:30 armv6j-hardfloat-linux-gnueabi-gcc -> /usr/bin/distcc
-rwx--x--x 1 root root 85 abr 7 16:34 armv6j-hardfloat-linux-gnueabi-wrapper
lrwxrwxrwx 1 root root 38 abr 7 16:35 c++ -> armv6j-hardfloat-linux-gnueabi-wrapper
lrwxrwxrwx 1 root root 38 abr 7 16:35 cc -> armv6j-hardfloat-linux-gnueabi-wrapper
lrwxrwxrwx 1 root root 38 abr 7 16:35 g++ -> armv6j-hardfloat-linux-gnueabi-wrapper
lrwxrwxrwx 1 root root 38 abr 7 16:35 gcc -> armv6j-hardfloat-linux-gnueabi-wrapper
chown distcc /var/log/distccd.log
rc-update add distccd default
/etc/init.d/distccd start
Podemos ver a que servidor de compilación se están ditribuyendo las tareas desde la rasp con:
Y podemos ver desde el server de compilación que parte del software se está compilando con:
NOTA: Hay que decir que esto NO funciona como la seda, parece ser que de vez en cuando en el servidor de compilación veamos errores del tipo:
distccd[24197] (dcc_readx) ERROR: unexpected eof on fd5
distccd[24197] (dcc_r_token_int) ERROR: read failed while waiting for token "DOTI"
distccd[24197] (dcc_job_summary) client: 192.168.69.13:32797 OTHER exit:0 sig:0 core:0 ret:108 time:0ms
Pero la compilación sigue distribuyendo la carga, asà que…