This is Gentoo's testing wiki. It is a non-operational environment and its textual content is outdated.
Please visit our production wiki at https://wiki.gentoo.org
Distcc/Cross-Compiling
Diese Anleitung zeigt wie distcc für das Übersetzen von Programmen für eine andere Rechnerarchitektur, als die vorhandene, konfiguriert werden msuss.
Cross-Compiling mit distcc
Einleitung
distcc ist ein Tool mit dem die Aufgaben eines Compilierprozesses auf mehrere im Netzwerk verteilte Rechner, aufgeteilt werden können. Wenn alle beteiligten Rechner die gleiche GCC-Version und Prozessorarchitektur verwenden, ist für distcc keine spezielle Konfiguration notwendig.
Diese Anleitung enthält die Instruktionen wie distcc zu konfigurieren ist um Übersetzungen für andere Rechnerarchitekturen durchführen zu können.
Installieren der benötigten Werkzeuge
Zuerst muss crossdev auf allen beteiligten Rechnern installiert werden. crossdev ist ein Tool mit dem die Werkzeuge die für andere Rechnerarchitekturen benötigt werden, einfach erstellt werden können. Es wird folgendermaßen aufgerufen: crossdev -t sparc erstellt alle Werkzeuge für die Sparc-Architektur. Die beinhaltet binutils, gcc, glibc und linux-Headers.
Es ist notwendig die passenden Werkzeuge auf allen teilnehmenden Rechner zu installieren. Weitere Hilfe wird durch crossdev --help angezeigt.
Hier ist ein Skript das die genauen Versionen für binutils, gcc, kernel, glibc und verwendete Architektur anzeigt (dieses sollte auf der Ziel-Platform aufgerufen werden).
#! /bin/bash A="binutils" ; B=`eselect $A show` ; BINUTILS_VER=`echo $B | cut -d- -f5-` A=`/usr/bin/gcc-config -c` ; B=`echo $A | cut -d- -f5` ; GCC_VER=`equery l sys-devel/gcc | grep $B | cut -d- -f3-` KERNEL_VER=`uname -r | sed s/-gentoo//` A="sys-libs/glibc" ; B=`equery l $A` ; LIBC_VER=`echo $B | cut -d- -f3-` echo "crossdev --b =$BINUTILS_VER --g =$GCC_VER --k =$KERNEL_VER --l =$LIBC_VER -t `uname -m`"
Als nächstes muss distcc auf allen Rechnern installiert werden, die am Übersetzungsprozess beteiligt werden sollen. Dies schließt die Zielplattform und die Rechnern die für das Crosscompiling vorgesehen sind ein. Die Gentoo Distcc Dokumentation enthält weitere Informationen für die Konfiguration und Benutzung von distcc.
Aktuelle Versionen von crossdev haben ein
S (--stable)
Flag. Wenn dieses Flag gesetzt ist, werden nur als stabil gekennzeichnete Versionen der Compiler Werkzeuge benutzt. (z.B. crossdev -t i686-pc-linux-gnu --stable --ex-gcc --ex-gdb --portage --pretend). Ohne diese Option, installiert crossdev die letzte experimentelle Version der Compiler! Das Skript oben wird nicht benötigt, es sei den es wurden spezifische Versionen für Portage unmaskiert.Hinweise für spezifische Architekturen
Den Namen der verwendeten Prozessorarchitektur enthält die CHOST Variable in /etc/make.conf. Crossdev wird für jede Architektur unterhalb /usr die erforderlichen Tools installieren (z.B. /usr/i686-pc-linux-gnu/, /usr/i686-linux-gnu/, ...). Es wird empfohlen jede nicht mehr benötigte Architektur mit dem Befehl crossdev --clean vom System zu entfernen, bzw. die betreffenden Verzeichnisse manuell zu löschen.
Intel x86 Architekturen
Wird das Crosscompiling für verschiedene Intel-x86-Prozessoren (z.B. i586 und i686) durchgeführt, müssen die Tools für jeden gewünschten CHOST installiert werden, ansonsten schlägt die Übersetzung fehl. Die Prozessoren i586 und i686 sind aktuell verschiedene CHOST, obwohl es sich bei beiden um x86-Prozessoren handelt. Diese Unterscheidung darf nicht vergessen werden, wenn die Cross-Compiling Werkzeuge installiert werden. Wenn zum Beispiel für einen i586 Rechner Programme übersetzt werden sollen und über distcc i686 Rechner beteiligt werden, müssen auf diese die Werkzeuge für i586 installiert sein.
SPARC
Der Aufruf von crossdev -t sparc kann mit einer der folgenden Fehlermeldungen fehlschlagen.
linker with -z relro support required support for the tls_model attribute is required this configuration requires -mlong-double-128 support
Wenn dies zutrifft, kann der folgende Befehl verwendet werden:
user $
crossdev --lenv "CC=sparc-unknown-linux-gnu-gcc" -t sparc-unknown-linux-gnu
Fehlerfreies Crosscompiling mit distcc
Mit dem voreingestellten distcc-Setup wird das Crosscompiling nicht funktionieren. Ursache des Problems ist, dass viele Pakete als Compiler nur gcc auf rufen, anstelle des vollen Pfades (z.B. sparc-unknown-linux-gnu-gcc). Wird dieses Paket nur zum Übersetzen auf einen Remotehost übertragen, wird auf diesem der system-eigene Compiler verwendet, anstelle des Cross-Compiler.
Für dieses kleine Problem gibt es zum Glück einen Workaround. Alles was es benötigt, ist ein Wrapper-Skript und ein paar Symlinks auf dem Rechner, auf dem emerge laufen soll. In folgenden Beispiel wird ein Sparc-Rechner benutzt, also muss immer dort wo sparc-unknown-linux-gnu
an die eigene CHOST, z.B. x86_64-pc-linux-gnu
für eine AMD64 CPU. Nach dem Installieren von distcc, sieht ein Listing /usr/lib/distcc/bin in etwa folgendermaßen aus:
Die folgenden Anweisungen sind nur auf dem Rechner durchzuführen, von dem die Übersetzung ausgeht, nicht auf den helfenden Rechnern.
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
Was ist zu tun?
root #
rm c++ g++ gcc cc
Nun muss auf dem Ausgangsrechner ein Skript erstellt werden, mit dem Text aus der folgenden Box. Es muss Dieses ist unter sparc-unknown-linux-gnu-wrapper zu speichern. Es muss sparc-unknown-linux-gnu
an die CHOST Variable angepasst werden auf der das emerge-Skript aufgerufen wird.
#!/bin/bash exec /usr/lib/distcc/bin/sparc-unknown-linux-gnu-g${0:$[-2]} "$@"
Der nächste Schritt besteht darin, das Skript ausführbar zu machen und die benötigen Verlinkungen auf dieses Skript anzulegen.
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++
Nun sollte das Listing von /usr/lib/distcc/bin folgendes Bild ergeben:
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
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.Bei einem Upgrade des Distcc-Paketes werden nun diese Verknüpfungen überschrieben. Damit diese nach einem Upgrade wieder hergestellt werden, wird folgende Verfahrensweise benutzt. Wird das Distcc-Paket oder der GNU-C-Compiler neu übersetzt, wird nach dem Übersetzen und Installieren ein Skript ausgeführt. Die Anweisung bekommt Portage dazu durch folgendes Skript in /etc/portage/bashrc:
case ${CATEGORY}/${PN} in '"`UNIQ--pre-00000007-QINU`"' if [ "${EBUILD_PHASE}" == "postinst" ]; then /usr/local/sbin/distcc-fix & fi ;; esac
Dann muss das Skript erstellt werden, mit dem die symbolischen Links wieder hergestellt werden:
#!/bin/bash sleep 20 # die Varibale TUPLE muss an den lokalen Rechner angepasst werden TUPLE="sparc-unknown-linux-gnu" cd /usr/lib/distcc/bin rm cc c++ gcc g++ ${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++
Anpassen der Zugriffsrechte:
root #
chmod 755 /usr/local/sbin/distcc-fix
Glückwunsch zum (hoffentlich) fehlerfrei funktionierendem Distcc Cross-Comiling Setup.
Funktionsweise
Immer wenn nun distcc aufgerufen wird, prüft es über welche Verknüpfung es aufgerufen wurde, (z.B. i686-pc-linux-gnu-gcc
, sparc-unknown-linux-gnu-g++
, etc.). Wenn nun Distcc einen Quelltext auf einen anderen Rechner zur Übersetzung sendet, wird der vollständige Name des Compilers, der auf dem unterstützenden Rechners zu verwenden ist, genannt. Würde nur der Defaultname gcc mitgegeben, würde auf dem Unterstützungsrechner der dortige gcc augeführt, der mit dem lokal verwendeten nicht übereinstimmen muss.
Fehlerbehebung
Dieser Abschnitt hilft bei einigen häufigen Problemen die bei der Benutzung von distcc und Crosscompiling auftreten können.
Übersetzungsfehler auf dem Remote Rechner
Erscheint die Meldung COMPILE ERRORS
in der Datei /var/log/distccd.log auf dem Remoterechner, ist die korrekte Rechnerarchitektur wie im obigen Abschnitt anzugeben (z.B. crossdev -t $TARGET).
Eine andere Lösungsmöglichkeit besteht darin, die crossdev Compiler-Tools zu deinstallieren und neu zu installieren, unter Benutzung der crossdev --clean Option. Wenn /usr/$TARGET leer ist, kann man auch den CrossCompiler komplett neu installieren.
It might also be wise to edit the remote host's /usr/$TARGET/etc/portage/make.conf, and ensure the contents of the CFLAGS variable are similar on all computers or hosts performing compiler operations. Also make sure the USE flags for the cross compiler are sufficient: if you built GCC with USE=graphite
on the client, you need a line like cross-i686-pc-linux-gnu/gcc graphite
in /etc/portage/package.use too.
Failed to exec $TARGET-unknown-linux-gnu-gcc: No such file or directory
Auch bei richtig gesetzten Zugriffsrechten, können die Wrapper-Skripte mit einem Fehler abbrechen:
distcc[6195] (dcc_execvp) ERROR: failed to exec i686-unknown-linux-gnu-gcc: No such file or directory
Um diesen Fehler zu beheben, ist zu kontrollieren, dass das Wrapper-Skript mit dem kompletten Name der Architektur erstellt wurde.
user $
ls -alh /usr/lib/distcc/bin/c++
/usr/lib/distcc/bin/c++ ->./i686-pc-linux-gnu-wrapper
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.