Compilation distribuée sur un réseau local
Suite à la discussion avec Jeko concernant Arch Linux ARM sur un Raspberry Pi 2 et la possibilité d'utiliser Ghost — sachant que Ghost fonctionne idéalement avec Node.js 0.10 et que ne sont disponibles que les versions 0.8 (ne fonctionne pas) et 0.12 (support instable pour le moment) pour Arch Linux ARM —, j'ai essayé de compiler Node.js en version 0.10 sur mon Raspberry Pi 2 (sans succès pour le moment, on ne s'improvise pas mainteneur de projet).
- Mes premières compilations échouaient.
- Ça prend du temps de compiler sur un Raspberry Pi, même un deuxième du nom.
- Pour vérifier que mon PKGBUILD (recette de compilation pour Arch Linux qui intègre le produit de celle-ci au gestionnaire de paquets) était correct, je relançais à chaque fois une compilation.
- Ça prend du temps de compiler sur un Raspberry Pi…
Maître : Raspberry Pi 2
J'allais donc certainement y passer des jours à coups d'essai-erreur, corriger le PKGBUILD, tester, recorriger suite à une nouvelle erreur. Mais en jetant un œil au fichier de configuration /etc/makepkg.conf
— makepkg
étant l'utilitaire permettant de construire les paquets sur base d'un PKGBUILD sous Arch Linux —, je vis qu'il était possible de distribuer la compilation sur mon réseau local : les machines sur mon réseau allaient pouvoir servir à compiler pour le Raspeberry et ainsi lui alléger la tâche. Le programme mentionné dans ledit fichier de configuration est distcc.
#########################################################################
# BUILD ENVIRONMENT
#########################################################################
#
# Defaults: BUILDENV=(!distcc color !ccache check !sign)
# A negated environment option will do the opposite of the comments below.
#
#-- distcc: Use the Distributed C/C++/ObjC compiler
#-- color: Colorize output messages
#-- ccache: Use ccache to cache compilation
#-- check: Run the check() function if present in the PKGBUILD
#-- sign: Generate PGP signature file
#
BUILDENV=(distcc color ccache check !sign)
Pour activer la distribution de la compilation du code, il faut donc enlever le point d'exclamation devant distcc
. J'en ai aussi profité pour activer le cache de compilation ccache
. Du coup, j'ai dû installer les deux programmes :
pacman -Sy distcc ccache --needed
Deux sections supplémentaires doivent être peuplées dans /etc/makepkg.conf
:
-
MAKEFLAGS, les arguments qui seront envoyés à la commande
make
. Où « X » est la somme du nombre maximal de threads par serveur (machine pouvant exécuter la compilation).#-- Make Flags: change this for DistCC/SMP systems MAKEFLAGS="-jX"
-
DISTCC_HOSTS, l'argument à ajouter sont les adresses IP des serveurs qui vont accueillir la compilation. Chaque adresse est suivie d'une barre oblique ("/") et du nombre de tâches qui pourront être lancées sur ce serveur. De plus, il est une pratique courante de définir le nombre de tâches par machine comme la somme du nombre de cœurs physiques (cœurs par socket) et du nombre de threads par cœurs (dans le cadre de la technologique hyper-threading), le tout plus 1. Sur l'Intel i7-3667U de Karl, la commande
nproc
me renvoie la valeur 4, qui est la première somme. Je déclarerai 5 tâches dans la configuration dedistcc
. Sur mon réseau local, karl a l'adresse fixe 192.168.1.69. Ma configuration dedistcc
sera donc la suivante :#-- If using DistCC, your MAKEFLAGS will also need modification. In addition, #-- specify a space-delimited list of hosts running in the DistCC cluster. DISTCC_HOSTS="192.168.1.69/5"
Documentation concernant la compilation distribuée :
- Distributed Compiling par Arch Linux ARM ;
- Distcc - Configuration sur ArchWiki.
Esclave :
Pour pouvoir compiler des paquets pour architecture ARM (armv7l dixit lscpu
) sur ma machine x86_64 (c'est-à-dire d'une architecture pour une autre, soit de la compilation croisée), j'ai installé distccd-alarm sur la machine qui « aidera » le RPi à compiler, installation qui permet d'automatiser rapidement le déploiement. Il suffit de
-
Cloner le dépôt
git clone https://github.com/WarheadsSE/PKGs.git
-
Aller au dossier contenant
distccd-alarm
cd PKGs/distccd-alarm
-
Lancer la compilation et l'installation des paquets
makepkg -sric
Où :
-s
/--syncdeps
installe les dépendances manquantes ;-r
/--rmdeps
désinstalle les dépendances superflues après compilation ;-i
/--install
installe le paquet si la compilation s'est bien passée ;-c
/--clean
nettoie le dossier de compilation après celle-ci.
Cela installe trois paquets, distccd-alarm-armv{5,6h,7h}
, pour plusieurs types d'architecture ARM. Celle qui m'intéresse pour le Raspberry Pi 2 est l'ARMv7.
Plusieurs choses à savoir pour déployer cela, donc
-
Les fichiers de configuration des trois paquets se trouvent dans le dossier
/etc/conf.d/
:/etc/conf.d/distccd-armv{5,6h,7h}
. J'y autorise tout mon réseau local à dialoguer avec ma machine :PATH=/usr/local/x-tools-armv7h/x-tools7h/arm-unknown-linux-gnueabihf/bin:$PATH DISTCC_ARGS="--user nobody --allow 192.168.1.0/24"
-
Lancer le processus
systemd
lié :systemctl start distccd-armv{5,6h,7h}.service
Finalement, il ne reste plus qu'à compiler ses paquets sur le Raspberry Pi. Si le code est en C, C++, Objective C ou Objective C++, il sera compilé par les autres machines, plus puissantes, qui sont déclarées disponibles sur le réseau local.
Documentation concernant la compilation croisée :
- Distcc Cross-Compiling par Arch Linux ARM ;
- Distcc - Cross Compiling with distcc : Other architectures sur ArchWiki.
En test : configuration Avahi
Plutôt que de déclarer des adresses IP fixes, j'aimerais plutôt utiliser les possibilités d'Avahi. Si mon routeur déconne (il déconne souvent) ou si je change d'environnement, je n'ai pas envie de changer chaque adresse IP dans ma configuration, donc de me rappeler de chaque endroit où j'ai modifié cela. Sur le papier, utiliser Avahi avec distcc
permet d'utiliser de façon souple les cœurs disponibles, qu'importe le nombre de machines sur le réseau, etc.
Pour ce faire, il faut activer le support d'Avahi par distcc
:
- Sur les machines esclaves, ajouter
--zeroconf
au serveurdistccd-armv{5,6h,7h}.service
, donc dans le fichier de configuration/etc/conf.d/distccd-armv{5,6h,7h}
si vous utilisez aussidistccd-alarm
. - Sur la machine hôte, ajouter la ligne
+zeroconf
au fichier$HOME/.distcc/hosts
.
La commande avahi-browse -r _distcc._tcp
permet dès lors d'afficher les machines se déclarant sur le réseau local sous Avahi. Par exemple chez moi :
+ eth0 IPv4 distcc@karl Distributed Compiler local
= eth0 IPv4 distcc@karl Distributed Compiler local
hostname = [karl.local]
address = [192.168.1.69]
port = [3632]
txt = ["cc_machine=arm-unknown-linux-gnueabihf" "cc_version=5.1.1" "gnuhost=x86_64-unknown-linux-gnu" "distcc=3.2rc1" "cpus=4" "txtvers=1"]
On voit donc que la machine « karl » annonce qu'elle a 4 cœurs de CPU a « prêter » pour compiler.
Je dois encore parfaire cette configuration chez moi. Si le serveur de compilation distribuée semble pourtant bien configuré, du côté de la machine maîtresse cela semble cafouiller, puisqu'elle n'arrive pas à déléguer la compilation aux autres machines sur le réseau.
Documentation sur la distribution de la compilation via Avahi :