Distcc

From Gentoo Wiki
Jump to: navigation, search
This page is a translated version of the page Distcc and the translation is 76% complete.

Other languages:
English • ‎español • ‎français • ‎italiano • ‎日本語 • ‎한국어 • ‎polski • ‎русский • ‎Türkçe • ‎中文(中国大陆)‎


Resources

Distcc est un programme conçu pour répartir des tâches de compilation à travers un réseau vers des hôtes participants. Il comprend un serveur, distccd, et un client, distcc. Distcc peut travailler en toute transparence avec ccache, Portage et Automake moyennant un minimum de configuration.

Si vous envisagez d'utiliser distcc pour vous aider à préparer la chaîne des outils de compilation pour une installation de Gentoo, assurez vous de lire préalablement la section concernant l'utilisation de distcc pour l'amorçage (compilation des outils de compilation).

Installation

Avant de configurer distcc, commençons par nous intéresser à l'installation de sys-devel/distcc sur tous les hôtes.

Dépendances communes à tous les hôtes

Afin d'utiliser distcc, tous les ordinateurs sur votre réseau doivent posséder la même version de GCC. Pour être plus précis, mélanger 3.3.x (avec x variable) est accepté, mais mélanger 3.3.x avec 3.2.x peut conduire à des erreurs de compilation ou des erreurs en exécution.

Installation du logiciel

Distcc comprend un utilitaire de surveillance graphique des tâches de compilation externes envoyées par un ordinateur. La présence de celui-ci est contrôlée par l'option gtk de la variable USE.

Une fois la variable USE configurée, installez le packet sys-devel/distcc.

root #emerge --ask sys-devel/distcc
Important
Rappelez-vous que vous devez installer sys-devel/distcc sur tous les ordinateurs participants.

Démarrage automatique du daemon distcc

Afin de mettre en place le démarrage automatique de distccd, suivez les instructions suivantes, en fonction du système d'initialisation que vous utilisez.

Avec OpenRC

Éditez le fichier /etc/conf.d/distccd en fonction de vos besoins et assurez-vous de définir la directive --allow pour seulement les hôtes auxquels vous accordez votre confiance. Pour une sécurité renforcée, utilisez aussi la directive --listen afin de dire au daemon distccd quelles adresses IP écouter (pour les systèmes multi-adresses). Des informations complémentaires sur la sécurité avec distcc sont disponibles à l'adresse Distcc Security Design.

L'exemple suivant autorise les clients distcc tournant sur 192.168.0.4 et 192.168.0.5 à se connecter au serveur distccd local.

FILE /etc/conf.d/distccdAutorisation de connexion depuis des clients spécifiques au serveur distccd
DISTCCD_OPTS="--port 3632 --log-level notice --log-file /var/log/distccd.log -N 15 --allow 192.168.0.4 --allow 192.168.0.5"
Important
Il est important d'utiliser --allow et --listen. Lisez la page de manuel de distccd (distccd manpage) ou le document sur la sécurité cité précédemment pour en savoir plus.

Maintenant démarrez votre daemon distccd sur tous les ordinateurs participants :

root #rc-update add distccd default
root #rc-service distccd start

Avec systemd

Éditez /etc/systemd/system/distccd.service.d/00gentoo.conf afin d'ajouter les clients au format CIDR. Voici un exemple:

FILE /etc/systemd/system/distccd.service.d/00gentoo.confConfiguration d'ALLOWED_SERVERS
Environment="ALLOWED_SERVERS=192.168.1.0/24"
Note
Le nom "ALLOWED_SERVERS" peut porter à confusion, étant donné qu'il indique quels clients ont le droit de se connecter au serveur distccd local. Quoi qu'il en soit, c'est la variable dont la valeur est utilisée par le service distccd pour l'option --allow – se référer à /usr/lib/systemd/system/distccd.service.

Recharger les nouvelles configurations:

root #systemctl daemon-reload

Activer le démarrage automatique de distccd et démarrer le service :

root #systemctl enable distccd
root #systemctl start distccd

Configuration

Jetons maintenant un œil à la configuration de distcc.

Spécification des hôtes participants

Utilisez la commande distcc-config pour définir la liste des participants.

Voici quelques exemples de définition d’hôtes. Dans la plupart des cas, des variations des lignes 1 et 2 suffisent. Cette dernière inclue la syntaxe /limit afin d'informer distcc du nombre maximal de taches à lancer sur le nœud. Plus d'informations sur la syntaxe employée aux lignes 3 et 4 sont disponibles sur le manuel de distcc.

CODE Exemples de définition d'hôtes participant
192.168.0.1          192.168.0.2                       192.168.0.3
192.168.0.1/2        192.168.0.2                       192.168.0.3/10
192.168.0.1:4000/2   192.168.0.2/1                     192.168.0.3:3632/4
@192.168.0.1         @192.168.0.2:/usr/bin/distccd     192.168.0.3

There are also several other methods of setting up hosts. See the distcc man page (man distcc) for more details.

Si la machine locale doit elle aussi compiler, indiquez localhost dans la liste des hôtes participants. À l'inverse, si la machine locale ne participe pas à la compilation (ce qui est souvent le cas), omettez la de la liste. Sur une machine lente, utiliser localhost peut ralentir les choses. Assurez vous de la performance de votre configuration en effectuant des tests.

Configurons distcc afin d'utiliser les hôtes mentionnés par la première ligne de l'exemple :

root #/usr/bin/distcc-config --set-hosts "192.168.0.1 192.168.0.2 192.168.0.3"

Distcc also supports a pump mode, by invoking the pump command. This may significantly reduce build time when multiple files are compiled in parallel. It caches preprocessed headers on the server side and, as a result, gets rid of repeated uploading and preprocessing of these header files.

To configure a host for pump mode, add the ,cpp,lzo suffix to the hosts definitions. Pump mode requires both cpp and lzo flags (regardless of the files being C or C++).

root #/usr/bin/distcc-config --set-hosts "192.168.0.1,cpp,lzo 192.168.0.2,cpp,lzo 192.168.0.3,cpp,lzo"

Utiliser distcc avec Portage

Il est aisé de configurer Portage pour qu'il utilise distcc. Il suffit pour cela d'activer la fonctionnalité distcc et de choisir une valeur décente pour le nombre de taches de compilation simultanées (étant donné que distcc augmente le nombre de ressources disponible pour la compilation).

Set the MAKEOPTS variable and FEATURES variable as shown below.

Une stratégie courante consiste à

  • mettre pour valeur de N le double du nombre "total" (locaux + distants) de cœurs du processeur + 1, et
  • mettre pour valeur de M le nombre de cœurs du processeur local.

The use of -lM in the MAKEOPTS variable will prevent spawning too many tasks when some of the distcc cluster hosts are unavailable (increasing the amount of simultaneous jobs on the other systems) or when an ebuild is configured to disallow remote builds (such as with gcc). This is accomplished by refusing to start additional jobs when the system load is at or above the value of M.

FILE /etc/portage/make.confConfiguration de MAKEOPTS et FEATURES
# Remplacez N et M avec les bonnes valeurs, comme calculé précédemment
MAKEOPTS="-jN -lM"
FEATURES="distcc distcc-pump"
Note
Distcc’s pump mode may significantly reduce build time for big packages. Consider the Specifying participating hosts section for more details.

For instance, when there are two quad-core host PCs running distccd and the local PC has a dual core CPU, then the MAKEOPTS variable could look like this:

FILE /etc/portage/make.conf
# 2 remote hosts with 4 cores each = 8 cores remote
# 1 local host with 2 cores = 2 cores local
# total number of cores is 10, so N = 2*10+1 and M=2
MAKEOPTS="-j21 -l2"

While editing the make.conf file, make sure that it does not have -march=native in the CFLAGS or CXXFLAGS variables. distccd will not distribute work to other machines if march is set to native. The appropriate -march= value can be obtained by running the following command:

user $gcc -v -E -x c -march=native -mtune=native - < /dev/null 2>&1 | grep cc1 | perl -pe 's/ -mno-\S+//g; s/^.* - //g;'

Pour plus d'information, consultez Résolution de -march=native pour distcc

Utiliser distcc avec automake

This is, in some cases, easier than the Portage setup. All that is needed is to update the PATH variable to include /usr/lib/distcc/bin/ in front of the directory that contains gcc (/usr/bin/). However, there is a caveat. If ccache is used, then put the distcc location after the ccache one:

root #export PATH="/usr/lib/ccache/bin:/usr/lib/distcc/bin:${PATH}"

Put this in the user's ~/.bashrc or equivalent file to have the PATH set every time the user logs in, or set it globally through an /etc/env.d/ file.

Au lieu de simplement appeler make, ajoutez s'y un paramètre d'invocation -jN (où N est un entier naturel). La valeur de N dépend du réseau et du type des ordinateurs utilisés pour la compilation. Une approche heuristique pour trouver la bonne valeur a été donné plus tôt dans cet article.

Utiliser distcc pour amorcer

Utiliser distcc pour amorcer (c'est à dire construire une chaîne d'outils avant d'installer le reste du système) requiert quelques étapes supplémentaires.

Étape 1: configurer Portage

Démarrez la nouvelle machine avec un LiveCD de Gentoo Linux et suivez les instructions d'installation tout en tenant compte des instructions sur le démarrage présentes dans la FAQ de Gentoo comme source d'information sur l'amorçage. Configurez ensuite Portage pour utiliser distcc:

FILE {{{filename}}}Configurer Portage pour utiliser distcc
FEATURES="distcc"
MAKEOPTS="-jN"

Mettez aussi à jour la variable PATH de votre session d'installation:

root #export PATH="/usr/lib/ccache/bin:/usr/lib/distcc/bin:${PATH}"

Étape 2: obtenir distcc

Installez sys-devel/distcc:

root #USE='-*' emerge --nodeps sys-devel/distcc

Étape 3: configurer distcc

Exécutez la commande distcc-config --install pour configurer distcc; remplacez les host# de l'exemple par les adresses IP ou les noms d'hôte des nœuds participant.

root #/usr/bin/distcc-config --set-hosts "localhost host1 host2 host3 ..."

Distcc est maintenant configuré pour l’amorçage ! Continuez avec les instructions d'installation officielles et n'oubliez pas de lancer emerge distcc après avoir fait emerge @system. Cela permet d'être sûr que toutes les dépendances nécessaires sont installées.

Note
Pendant l’amorçage et lors le l'exécution de emerge @system, distcc peut sembler non utilisé. Ceci est prévisible, car certains ebuilds ne fonctionnent pas bien avec distcc et l'ont intentionnellement désactivé.

Suppléments distcc

L'application distcc a quelques fonctionnalités supplémentaires et des outils pour aider à travailler dans un environnement distcc.

Surveillant distcc

Distcc arrive avec deux utilitaires de surveillance. L'un, à base de texte, est toujours compilé et est appelé distccmon-text. Le lancer pour la première fois peut paraître confus, mais il est en fait facile à utiliser. Si le programme est utilisé sans paramètre, il ne s'actionnera qu'une seule fois. Cependant, s'il lui est passé un nombre N, il se mettra à jour toutes les N secondes (avec N l'argument qui lui a été passé).

user $distccmon-text 10

L'autre utilitaire de surveillance n'est activé qu'à travers l'option gtk de la variable USE. Celui-ci est basé sur GTK+, tourne dans un environnement X et est très agréable. Pour Gentoo, le surveillant graphique a été renommé distccmon-gui pour éviter la confusion. Il était originellement appelé distccmon-gnome.

user $distccmon-gui

Pour surveiller l'utilisation de distcc par Portage:

root #DISTCC_DIR="/var/tmp/portage/.distcc/" distccmon-text 10
root #DISTCC_DIR="/var/tmp/portage/.distcc/" distccmon-gui
Important
If the distcc directory is elsewhere, change the DISTCC_DIR variable accordingly.

A trick is to set DISTCC_DIR in environment variables:

root #echo 'DISTCC_DIR="/var/tmp/portage/.distcc/"' >> /etc/env.d/02distcc

Mettez maintenant l'environnement à jour:

root #env-update
root #source /etc/profile

Pour finir, démarrez l'application graphique:

root #distccmon-gui

Utiliser SSH pour les communications de distcc

Configurer distcc via SSH demande d'éviter quelques pièges. Tout d'abord, générez une paire de clés SSH sans définir le mot de passe. Restez conscient du fait que Portage compile les programmes en tant que l'utilisateur Portage (ou en tant que root si FEATURES="userpriv" n'est pas défini). Le dossier home de l'utilisateur Portage est /var/tmp/portage/, ce qui veut dire que les clés doivent être stockées dans /var/tmp/portage/.ssh/.

root #ssh-keygen -b 2048 -t rsa -f /var/tmp/portage/.ssh/id_rsa

Ensuite, créez une section pour chacun des hôtes dans le fichier de configuration SSH :

FILE /var/tmp/portage/.ssh/configAjouter des sections par hôte
Host test1
    HostName 123.456.789.1
    Port 1234
    User UserName
 
Host test2
    HostName 123.456.789.2
    Port 1234
    User UserName

Envoyez la clef publique à chaque nœud de compilation:

root #ssh-copy-id -i /var/tmp/portage/.ssh/id_rsa.pub UserName@CompilationNode

Assurez-vous également que chaque hôte est disponible dans le fichier known_hosts:

root #ssh-keyscan -t rsa <compilation-node-1> <compilation-node-2> [...] > /var/tmp/portage/.ssh/known_hosts

Fix the file ownership as follows:

root #chown -R portage:portage /var/tmp/portage/.ssh/

Pour mettre en place les hôtes test1 et test2, lancez:

root #/usr/bin/distcc-config --set-hosts "@test1 @test2"

Notez le signe @ (symbole @) qui spécifie les hôtes SSH à distcc.

Pour finir, indiquez à distcc quel binaire SSH utiliser"

FILE /etc/portage/make.conf
DISTCC_SSH="ssh"

Il n'est pas nécessaire de lancer le script d'initialisation (initscript) sur les hôtes lorsque distcc communique via SSH.

Testing

To test distcc, write a simple Hello distcc program and run distcc in verbose mode to see if it communicates properly.

FILE main.c
#include <stdio.h>
 
int main() {
    printf("Hello distcc!\n");
    return 0;
}

Next, turn on verbose mode, compile the program using distcc and link the generated object file into an executable:

user $export DISTCC_VERBOSE=1
user $distcc gcc -c main.c -o main.o # or 'pump distcc <...>'
user $gcc main.o -o main
Note
Replace distcc command with pump distcc for use pump mode.

There should be a bunch of output about distcc finding its configuration, selecting the host to connect to, starting to connect to it, and ultimately compile main.c. If the output does not list the desired distcc hosts, check the configuration.

Finally, ensure the compiled program works properly. To test each host, enumerate each compile host in the hosts file.

user $./main
Hello distcc!

Dépannage

Si un problème apparaît lors de l'utilisation de distcc, cette section pourra peut être aider à le résoudre.

ERROR: failed to open /var/log/distccd.log

Au jour du 22 Janvier 2015, la création du fichier distccd.log dans /var/log/ echoue lors de l'emergement. Ceci semble n'affecter que la version 3.1-r8 de distcc. Ce bug est en cours de correction (plus plus d'information, voir bug #477630). Il est possible de contourner le problème en créant manuellement le fichier de log, lui assigner un propriétaire convenable et redémarrer le daemon de distcc.

root #mkdir -p /var/log/distcc
root #touch /var/log/distcc/distccd.log
root #chown distcc:daemon /var/log/distcc/distccd.log

Continuez par mettre à jour le chemin de /var/log présent dans le fichier de configuration de distcc /etc/conf.d/distccd afin de pointer vers le dossier distcc créé dans l’étape précédente.

FILE /etc/conf.d/distccdUpdating log path
DISTCCD_OPTS="--port 3632 --log-level notice --log-file /var/log/distcc/distccd.log -N 15

Pour finir, redémarrez le service distccd:

root #/etc/init.d/distccd restart

Quelques paquets n'utilisent pas distcc

Lorsque certains paquets sont installés, les utilisateurs remarqueront que la compilation de certain d'entre-eux n'est pas répartie (et ils ne sont pas compilés en parallèle). Ceci peut survenir du fait que le Makefile du paquet ne prenne pas en charge les opérations en parallèle, ou que le mainteneur du ebuild les ai explicitement désactivées suite à un problème connu.

Parfois distcc peut faire échouer la compilation d'un paquet. Si cela arrive, ayez s'il vous plaît l’amabilité de le rapporter.

Versions mélangées de GCC

Si l'environnement héberge plusieurs versions différentes de GCC, il est probable que des problèmes étranges se produisent. La solution est alors de faire en sorte que tous les hôtes aient la même version de GCC.

De récentes mises à jour de Portage ont fait que Portage utilise ${CHOST}-gcc (tiret gcc) au lieu de gcc . Ceci veut dire que si des machines i686 sont mélangées avec d'autres types (i386, i586), des soucis de compilation se présenteront. Un contournement à cela peut consister à lancer :

root #export CC='gcc' CXX='c++'

It is also possible to set the CC and CXX variables in /etc/portage/make.conf to the values list in the command above.

Important
Faire cela redéfinit explicitement quelques comportements de Portage et peut conduire à des résultats étranges dans le futur. Ne faites cela que si mélanger les CHOSTs est inévitable.
Note
Having the right version of gcc as a slot on a server isn’t enough. Portage uses distcc as a replacement for the compiler referenced by the CHOST variable (i.e. x86_64-pc-linux-gnu) and distccd invokes it by exactly same name. The right version of gcc should be a default system’s compiler on all involved compilation hosts.

-march=native

À partir de GCC 4.3.0, le compilateur prend en charge l'option -march=native, qui active l’auto-détection des processeurs et les optimisations qui valent la peine d’être activées sur le processeur faisant tourner GCC. Cela pose un problème lors de l'utilisation de distcc, car cela engendre le mélange de codes optimisés pour différents processeurs. Par exemple, faire tourner distcc avec -march=native sur un réseau de nœuds contenant un système utilisant un AMD Athlon et un système utilisant un Intel Pentium mélangera du code compilé sur chacun des hôtes. Une partie du code compilé sera alors optimisée pour AMD Athlon tandis qu'une autre sera optimisée pour Intel Pentium.

Prenez garde à cette avertissement:

Warning
Do not use -march=native or -mtune=native in the CFLAGS or CXXFLAGS variables of make.conf when compiling with distcc.

Pour connaître les options que GCC activera lorsqu'il est appelé avec -march=native, exécutez ce qui suit :

user $gcc -march=native -E -v - </dev/null 2>&1 | grep cc1
/usr/libexec/gcc/x86_64-pc-linux-gnu/4.7.3/cc1 -E -quiet -v - -march=corei7-avx \
  -mcx16 -msahf -mno-movbe -mno-aes -mpclmul -mpopcnt -mno-abm -mno-lwp -mno-fma \
  -mno-fma4 -mno-xop -mno-bmi -mno-bmi2 -mno-tbm -mavx -mno-avx2 -msse4.2 -msse4.1 \
  -mno-lzcnt -mno-rdrnd -mno-f16c -mno-fsgsbase --param l1-cache-size=32 \
  --param l1-cache-line-size=64 --param l2-cache-size=6144 -mtune=corei7-avx

Get more output from emerge logs

It is possible to obtain more logging by enabling verbose mode. This is accomplished by adding DISTCC_VERBOSE to /etc/portage/bashrc:

FILE /etc/portage/bashrcEnabling verbose logging
export DISTCC_VERBOSE=1

The verbose logging can then be found in /var/tmp/portage/$CATEGORY/$PF/temp/build.log.

Keep in mind that the first distcc invocation visible in build.log isn’t necessary the first distcc call during a build process. For example a build server can get a one-minute backoff period during the configuration stage when some checks are performed using a compiler (distcc sets a backoff period when compilation on a remote server failed, it doesn’t matter whether it failed on local machine or not).

Dig into the /var/tmp/portage/$CATEGORY/$PF/work/ directory to investigate such situations. Find other logs, or call make explicitly from within the working directory.

Another interesting variable to use is DISTCC_SAVE_TEMPS. When set, it saves the standard output/error from a remote compiler which, for Portage builds, results in files in the /var/tmp/portage/$CATEGORY/$PF/temp/ directory.

FILE /etc/portage/bashrcSaving temporary output
export DISTCC_SAVE_TEMPS=1

Articles connexes

  • Le Guide de la compilation croisée avec distcc explique comment utiliser une architecture pour compiler des programmes pour une autre architecture avec discc. Cela peut simplement concerner l'utilisation d'un Athlon (i686) pour compiler un programme destiné à un K6-2 (i586), ou l'utilisation d'un SPARC pour compiler un programme destiné à un PowerPC.

Ressources externes


This article is based on a document formerly found on our main website gentoo.org.
The following people contributed to the original document: Lisa Seelye, Mike Frysinger, Erwin, Sven Vermeulen, Lars Weiler, Tiemo Kieft and nightmorph
They are listed here as the 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 the history page.