Duisburger Linux User Group - http://www.dulug.de
Cross Compiler Workshop
Autor: M. Franke

Vorab eine kleine Anmerkung: dies ist keine Anleitung um einen Cross Compiler zu bauen,
vielmehr eine Anleitung für Crosstool und wie man den damit gebauten Cross Compiler
erweitert.
Crosstool ist ein Sammlung von Skripten um eine Cross Compiler Basis Umgebung zu bauen.
Das ist schon mal sehr hilfreich wenn man sich einen Cross Compiler bauen will/muss.
Zu Anfang sollte man sich die benötigten Skripte von http://www.kegel.com/crosstool/
herunterladen und in seinem Homeverzeichnis entpacken:
$ tar xfz crosstool-0.38.tar.gz
Und noch ins neue Verzeichnis wechseln:
$ cd crosstool-0.38
Wenn man sich nun ein wenig umsieht sieht man einige Skripte und die demo-arch.sh Skripte
sind die wichtigsten (arch steht für Architektur). Als Beispiel nehm ich mal das Skript
für den ARM Prozessor da mein Zaurus auch einen hat (demo-arm.sh). Bevor wir nun los-
legen können muss das Skript noch ein wenig angepasst werden, dh. mit einem Editor
bearbeitet werden. In den ersten Zeilen sieht man diese beiden Variablen:
TARBALLS_DIR=$HOME/downloads
RESULT_TOP=/opt/crosstool
In dem ersten Verzeichnisse werden alle Pakete die während des Bauens heruntergeladen
werden gespeichert und in dem zweiten Verzeichnis wird der Cross Compiler gebaut.
Stellt also unbedingt sicher das Ihr auf beide Verzeichnisse Schreibzugriff habt!
Zuletzt könnt Ihr noch die Version auswählen welcher gcc Cross Compiler gebaut werden
soll, das steht in den letzten Zeilen. Lasst Ihr das so wie es ist, wird der gcc-4.1
gebaut. Wenn Ihr lieber den gcc-3.4.1 haben wollt müsst Ihr die entsprechende Zeile
auskommentieren und ein Kommentarzeichen vor die Zeile mit dem gcc-4.1 setzen.
Jetzt könnt Ihr anfangen den Cross Compiler zu bauen in dem Ihr das Skrip startet:
$ sh demo-arm.sh
Das ganze dauert jetzt unter Umständen einige Stunden, je nachdem wie Leistungstark
Euer Rechner ist.
Wenn alles fertig kann man auch schon loslegen und sein erstes Programm cross-kompilieren:
#include <iostream>
int main() {
std::cout << "Hello Cross-Arm-World\n";
}

Speichert die Zeilen irgendwo als hello.cpp ab. Danach ergänzt Eure Path Variable um den
Pfad mit Eurem Cross Compiler:
$ export PATH=$PATH:/opt/crosstool/gcc-3.3.3-glibc-2.3.2/arm-unknown-linux-gnu/bin/
Und setzt die Variable $CC für den C Compiler wie folgt:
$ export CC=/opt/crosstool/gcc-3.3.3-glibc-2.3.2/arm-unknown-linux-gnu/bin/arm-unknown-linux-gnu-gcc
Ihr könnt das Programm nun folgendermassen übersetzen:
$ arm-unknown-linux-gnu-g++ hello.cpp -o hello
Anschliessend solltet Ihr ein ARM-fähiges Binary haben:
$ file hello
hello: ELF 32-bit LSB executable, ARM, version 1 (ARM), dynamically linked (uses shared libs), not stripped

Strippen ist auch drin:
$ arm-unknown-linux-gnu-strip hello
$ file hello
hello: ELF 32-bit LSB executable, ARM, version 1 (ARM), dynamically linked (uses shared libs), stripped

Damit ist der Cross Compiler schon lauffähig. Wenn man allerdings noch ein paar andere
Bibliotheken nutzen möchte, sollte man ein paar Dinge beachten auf die im folgenden mit
der SDL noch zeigen werde.
Zuerst sollte man sich die SDL von http://www.libsdl.org herunterladen und entpacken:
$ tar xfz SDL-1.2.9.tar.gz
Und ins Verzeichnis wechseln:
$ cd SDL-1.2.9/
Und wieder die beiden Cross Compiler Variablen setzen (falls nicht mehr vorhanden):
$ export PATH=$PATH:/opt/crosstool/gcc-3.3.3-glibc-2.3.2/arm-unknown-linux-gnu/bin/
$ export CC=/opt/crosstool/gcc-3.3.3-glibc-2.3.2/arm-unknown-linux-gnu/bin/arm-unknown-linux-gnu-gcc
Zusätzlich muss man noch die Varaible LDFLAGS setzen, ansonsten versucht der Cross
Compiler mit den X86er Bibliotheken eine ARM Applikation zu bauen, was zu ziemlich
hässlichen Fehlern führt:
$ export LDFLAGS=-L/opt/crosstool/gcc-3.3.3-glibc-2.3.2/arm-unknown-linux-gnu/arm-unknown-linux-gnu/lib
Zudem sollte man dem configure Skrip der SDL noch mit ein paar Parametern füttern:
--prefix=/opt/crosstool/gcc-3.3.3-glibc-2.3.2/arm-unknown-linux-gnu/arm-unknown-linux-gnu
Das stellt sicher das die Bibliothek dem Cross Compiler hinzugefügt wird und nicht wie
üblich unter /usr/local/lib installiert wird.
--host=arm-unknown-linux-gnu
--target=arm-unknown-linux-gnu
Die beiden sind immer sinnvoll wenn man einen Cross Compiler einsetzen will
--disable-esd
ESD habe ich an der Stelle mal rausgeschmissen. Wer ESD haben will muss vorher auch ESD
cross-kompilieren!
--disable-video-x11
--disable-x11-vm
--disable-dga
--disable-video-x11-dgamouse
--disable-video-x11-xv
--disable-video-x11-xinerama
Das selbe mit X. Wer X haben will muss vorher auch X cross-kompilieren!
Jetzt kann man das configure Skript ausführen:
$ ./configure --prefix=/opt/crosstool/gcc-3.3.3-glibc-2.3.2/arm-unknown-linux-gnu/arm-unknown-linux-gnu --host=arm-unknown-linux-gnu --target=arm-unknown-linux-gnu --disable-esd --disable-video-x11 --disable-x11-vm --disable-dga --disable-video-x11-dgamouse --disable-video-x11-xv --disable-video-x11-xinerama
Anschliessend noch:
$ make
make install

und die SDL ist nun bereit für den Cross Compiler, was direkt mal getestet werden sollte.
Dazu ergänzen wir unsere hello.cpp wie folgt:
#include <iostream>
#include <SDL/SDL.h>
int main() {
std::cout << "Hello Cross-Arm-World\n";
}

Und übersetzen mit der zusätzlichen -lSDL Option:
$ arm-unknown-linux-gnu-g++ hello.cpp -lSDL -o hello
Danach sollten sich auch Sourcen mit der SDL cross kompilieren lassen.
Viel Spass!