Distcc/Compilation croisée

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 85% complete.
Outdated translations are marked like this.


Ce guide explique comment configurer distcc pour la compilation croisée à travers différentes architectures de processeur.

La compilation croisée avec distcc

Introduction

distcc est un outil qui vous permet de partager les tâches de compilation d'un logiciel sur plusieurs ordinateurs d'un réseau. Tant que les ordinateurs du réseau utilisent tous la même chaîne d'outils compilée pour la même architecture, aucune configuration spéciale de distcc n'est requise.

Ce guide fournit des instructions sur la configuration de distcc afin de permettre la compilation pour des architectures différentes.

Installer les utilitaires nécessaires

Tout d'abord, vous devez installer crossdev sur toutes les machines qui seront impliquées dans le processus de compilation. crossdev est un outil qui permet une compilation facile de la chaîne des outils de compilation croisée. Son utilisation est assez directe : crossdev -t sparc compile une chaîne d'outils complète ciblant l'architecture SPARC. Ceci inclut binutils, gcc, glibc, et linux-headers.

Il vous faudra emerger la chaîne d'outils de compilation croisée sur toute les machines aidant à la compilation. Si vous avez besoin d'aide supplémentaire, tentez de lancer crossdev --help.

Si vous voulez régler finement la chaine de compilation croisée (cross-toolchain), voici un script qui produira une ligne de commande avec la version exacte du paquet de développement croisé à construire sur les machines assistantes (le script est à exécuter depuis la machine cible).

CODE Script pour régler finement les outils de compilation croisée
#!/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)"

Ensuite il vous faudra installer distcc sur toutes les machines qui sont impliquées dans le processus. Ceci inclut la machine qui doit exécuter emerge et les machines disposant du compilateur croisé (cross-compiler). Reportez-vous à la Documentation Gentoo de Distcc pour plus d'informations sur la manière de paramétrer et d'utiliser distcc.

Remarque
Les versions actuelles de crossdev ont une option -S (--stable) pour se limiter à l'installation des versions stables des outils de compilation (par exemple, crossdev -t i686-pc-linux-gnu --stable --ex-gcc --ex-gdb --portage --pretend). Sans cette option, crossdev installe la dernière version expérimentale des paquets d'outils de compilation ! Autrement, le script ci-dessus n'est plus nécessaire, à moins que des versions spécifiques des outils de paquets et/ou des headers aient été démasquées.

Notes spécifiques à Arch

Remarque
Obtenez le nom de l'architecture en regardant la variable CHOST dans le fichier /etc/make.conf de la cible de la compilation. En cas de massacre du nom de l'architecture passé à l'option crossdev -t, crossdev se fera une joie de deviner et d'installer les outils en utilisant le mauvais nom pour les dossiers dans /usr/ (par exemple: /usr/i686-pc-linux-gnu/, /usr/i686-linux-gnu/, ...). Pour corriger cela, indiquez chaque nom d'architecture ou de dossier à crossdev --clean afin de les désinstaller, ou supprimez manuellement les dossiers du système.

Sous-architectures Intel x86

Si vous effectuez une compilation croisée entre des sous-architectures pour Intel x86 (par exemple i586 et i686), vous devez toujours compiler une chaîne de compilation croisée complète pour le CHOST désiré, ou autrement la compilation échouera. Ceci est dû au fait que i586 et i686 sont réellement des CHOSTs différents, malgré le fait qu'ils sont tous les deux considérés comme des x86. Garder cela à l'esprit lorsque vous compilez la chaîne de compilation croisée. Par exemple, si la machine cible est i586, ceci signifie que vous devez compiler les chaînes de compilation croisées sur vos machines assistantes i686.

SPARC

Utiliser crossdev -t sparc pourrait échouer avec une des erreurs suivantes :

CODE Erreurs affichées lors de l'exécution de 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 cela vous arrive, essayez la commande suivante à la place de la précédente :

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

Configurer distcc pour des compilations croisées correctes

Remarque
The workaround as described in this section is not needed any more since distcc-3.2, as the functionality for replacing the calls to the compiler with the full compiler name has since then been implemented in distcc itself.

Dans la configuration par défaut de distcc, la compilation croisée ne fonctionnera pas correctement. Le problème est que beaucoup d'ebuilds appellent simplement le compilateur gcc au lieu de l'appeler par son nom complet (par exemple, sparc-unknown-linux-gnu-gcc). Quand cette compilation est distribuée sur une machine participante, le compilateur natif est appelé à la place de votre compilateur croisé flambant neuf.

Heureusement, il y a un moyen de contourner ce petit problème. Tout ce qu'il faut, c'est un script enveloppe et quelques liens symboliques sur la machine qui exécutera la commande d'installation emerge. Nous allons utiliser le machine Sparc comme un exemple. Partout où vous rencontrez sparc-unknown-linux-gnu ci-dessous, vous devrez insérer votre propre valeur pour CHOST (x86_64-pc-linux-gnu pour une machine AMD64, par exemple). Quand vous installerez distcc pour la première fois, le répertoire /usr/lib/distcc/bin devrait ressembler à ceci :

Remarque
Les instructions suivantes doivent être exécutées seulement sur la machine qui exécute la commande emerge. N'effectuez pas ces étapes sur les machines assistantes.
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

Voici ce que vous devez faire :

root #rm c++ g++ gcc cc

Ensuite, nous allons créer le nouveau script sur cette machine. Lancez votre éditeur favori et créez un fichier avec le texte suivant, puis sauvegardez-le comme sparc-unknown-linux-gnu-wrapper . Pensez à remplacer CHOST (dans ce cas, sparc-unknown-linux-gnu ) par le CHOST réel de la machine qui exécutera la commande emerge.

CODE Le nouveau script enveloppe
#!/bin/bash
exec /usr/lib/distcc/bin/sparc-unknown-linux-gnu-g${0:$[-2]} "$@"

Ensuite, nous allons rendre le script exécutable et créer les liens symboliques corrects :

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++

Voilà, c'est terminé. /usr/lib/distcc/bin devrait ressemble à ceci :

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
Remarque
With new distcc versions, the following steps are unnecessary—you can emerge distcc on the client with the crossdev USE flag set instead to achieve the same result.

Ensuite nous devons nous assurer que ces enveloppes restent disponibles après la mise à jour du paquet distcc car il écrase les liens symboliques. Nous pouvons le faire grâce au fichier /etc/portage/bashrc qui ressemble à ceci :

FILE /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

Then create one of the following files as applicable. If you are not using clang:

FILE /usr/local/sbin/distcc-fix
#!/bin/bash                     
sleep 20
# We extract $TUPLE from make.conf to avoid editing the script for each architecture.
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}

If you ARE using clang:

FILE /usr/local/sbin/distcc-fix
#!/bin/bash	                
#clang aware, now your >chromium-65 ebuilds will use distcc just like before ;) 
sleep 20
# We extract $TUPLE from make.conf to avoid editing the script for each architecture.
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}

Give it the proper permissions:

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

Félicitations ! Vous disposez maintenant d'une configuration distcc avec compilation croisée fonctionnelle.

Fonctionnement

Lorsque distcc est appelé, il recherche ce qui est appelé (par exemple i686-pc-linux-gnu-gcc , sparc-unknown-linux-gnu-g++ , etc.) Lorsque distcc distribue ensuite la compilation à une machine assistante, il lui passe le nom par lequel il a été appelé. Le démon distcc sur l'autre machine assistante recherche alors un binaire de ce nom. S'il voit simplement gcc, il cherchera gcc, qui est probablement le compilateur natif sur la machine assistante, si ce n'est pas la même architecture que celle de la machine exécutant la commande emerge. Quand le nom complet du compilateur est envoyé, (par exemple, sparc-unknown-linux-gnu-gcc ), il ne peut y avoir de confusion.

Dépannage

Cette section couvre un certain nombre des problèmes habituels dus à l'utilisation de distcc pour la compilation croisée.

COMPILE ERRORS sur l’hôte distccd distant

En cas d'apparition du message COMPILE ERRORS dans le fichier /var/log/distccd.log de l'un des hôtes distant, regardez ci-dessus les notes concernant la spécification du nom correct pour l'architecture (c'est à dire: crossdev -t $TARGET).

Une autre solution consiste à désinstaller et réinstaller les outils de compilation crossdev, en utilisant l'option crossdev --clean, ou en s'assurant que /usr/$TARGET n'existe plus, puis en réinstallant complètement l'outil de compilation croisée.

Il peut aussi être prudent d’éditer le fichier /usr/$TARGET/etc/portage/make.conf de l’hôte distant afin de s'assurer que le contenu de la variable CFLAGS est similaire sur tous les ordinateurs ou hôtes performant les opérations de compilation.

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

Il est possible que le script d'emballage (wrapper) ne parvienne pas à s’exécuter, même avec les bonnes permissions :

CODE Message d'erreur de l'emballage (wrapper)
distcc[6195] (dcc_execvp) ERROR: failed to exec i686-unknown-linux-gnu-gcc: No such file or directory)

Pour résoudre ceci, assurez vous d'avoir créé le script d'emballage (wrapper) en utilisant le nom complet de l'architecture cible:

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

Voir aussi

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