Ce document n'est pas un n-iéme document sur comment construire un
cross compilateur. Il y a déjà des documents sur ce sujet, allez voir
la section Références. Son but est d'expliquer quelles sont les étapes
requises and comment cela doit fonctionner dans un monde idéal. Nous
ne parlerons pas de patchs ici (ou juste pour référence). Bien sûr,
LES INTRUCTIONS FOURNIES ICI NE FONCTIONNENT PAS.
- Installation des en-têtes du noyau Linux®
Les en-têtes du noyau Linux® sont nécessaires pour compiler la
glibc. Cependant, nous avons besoin des mêmes en-têtes que celles qui
seraient sur le système hôte. Par exemple, le lien symbolique
asm
doit pointer vers le répertoire approprié. Une autre
façon de régler cette situation et qui est nécessaire sur un système
multi-arch est d'avoir des en-têtes du noyau Linux® multi-arch.
Comme nous utilisons déjà des en-têtes du noyau Linux® multi-arch,
cette étape est une simple copie de répertoire.
mkdir -p $SYSROOT/usr/include &&
cp -a /usr/include/asm* /usr/include/linux $SYSROOT/usr/include
- Installation de binutils
binutils fournis deux outils importants : l'assembleur GNU et
l'éditeur de liens GNU qui sont tout les deux utilisés comme
backend du compilateur C GNU. Nous avons ici besoin de cross
binutils, i.e. un assembleur GNU et un éditeur de liens GNU qui seront
exécutés sur le système de compilation et qui produiront des binaires
corrects pour le système hôte.
L'option --with-sysroot
est assez importante. Elle sera
codée en dur dans l'exécutable résultant, i.e. $HOST-ld. Cette option
est utilisée au moment de l'exécution pour localiser les bibliothéques
lorsque le chemin de recherche des bibliothéques inclus un chemin
commençant par le signe =. C'est le cas pour les chemins de recherche
des bibliothéques par défaut, qui est :
=/usr/local/lib:=/lib:=/usr/lib
. Ceci peut sembler assez
complexe de prime abord, mais cela permet aux bibliothéques d'être
trouvées par l'éditeur de liens comme si nous compilions sur le
système hôte lui-même.
tar jxf binutils-2.15.tar.bz2 &&
mkdir binutils-build &&
cd binutils-build &&
../binutils-2.15/configure --prefix=$PREFIX \
--target=$HOST \
--with-sysroot=$SYSROOT &&
make all &&
make install
- Installation des en-têtes glibc
Nous avons besoin des en-têtes glibc pour construire gcc. Nous avons
utilisé l'add-on linuxthreads au lieu de nptl car ce dernier ne
fonctionnait pas dans cette étape. Nous spécifions à la fois le
système de compilation et le système hôte sur la ligne de commande
configure pour forcer la cross compilation. La valeur de BUILD
peut-être déterminé en exécutant le script config.guess
dans les sources de binutils.
tar jxf glibc-2.3.4.tar.bz2 &&
(cd glibc-2.3.4 &&
tar jxf glibc-linuxthreads-2.3.4.tar.bz2) &&
mkdir glibc-build &&
cd glibc-build &&
../glibc-2.3.4/configure --prefix=/usr \
--build=$BUILD --host=$HOST \
--with-headers=$SYSROOT/usr/include \
--without-cvs --disable-profile --disable-debug --without-gd \
--enable-add-ons=linuxthreads --with-tls --without-__thread \
--enable-kernel=2.4 &&
make install-headers install_root=$SYSROOT
- Installation d'un premier gcc
Dans cet étape, nous pouvons compiler un premier cross compilateur. Il
ne sera pas capable de produire des bibliothéques dynamiques car les
bibliothéques dynamiques ont besoin des bibliothéques dynamiques de
glibc.
Comme pour binutils, l'option --with-sysroot
est assez
importante aussi. Cette option sera utilisé au moment de l'exécution
pour gérer le chemin par défaut de recherche des en-têtes comme si
nous compilions sur le système hôte. Le chemin par défaut de recherche
des en-têtes est :
/usr/local/include:/usr/include
. Quelques répertoires
internes à gcc peuvent également s'y ajouter
($PREFIX/lib/gcc/$HOST/3.4.3/include
ici).
tar jxf gcc-core-3.4.3.tar.bz2 &&
mkdir gcc-build &&
cd gcc-build &&
../gcc-3.4.3/configure --prefix=$PREFIX \
--target=$HOST \
--with-sysroot=$SYSROOT --with-headers=$SYSROOT/usr/include \
--disable-threads --disable-shared --enable-language=c &&
make &&
make install
- Installation de glibc
Nous avons maintenant un premier cross compilateur/assembleur/éditeur
de liens. Nous allons l'utiliser pour construire une glibc hôte. Nous
avons besoin d'ajouter le répertoire correct à PATH afin que le script
configure trouve notre cross compilateur.
export PATH=$PREFIX/bin:$PATH &&
tar jxf glibc-2.3.4.tar.bz2 &&
(cd glibc-2.3.4 &&
tar jxf glibc-linuxthreads-2.3.4.tar.bz2) &&
../glibc-2.3.4/configure \
--prefix=/usr \
--build=$BUILD --host=$HOST \
--with-headers=$SYSROOT/usr/include \
--without-cvs --disable-profile --disable-debug --without-gd \
--enable-add-ons=linuxthreads --with-tls --without-__thread \
--enable-kernel=2.4 &&
make &&
make install install_root=$SYSROOT &&
- Installation de gcc
Maintenant que nous avons une glibc hôte, nous pouvons reconstruire
notre cross compilateur pour inclure le support du C++ (ceci requiert
la construction d'une bibliothéque dynamique et ne pouvait pas être
fait à une étape précédente).
tar jxf gcc-core-3.4.3.tar.bz2 &&
tar jxf gcc-g++-3.4.3.tar.bz2 &&
mkdir gcc-build &&
cd gcc-build &&
../gcc-3.4.3/configure --prefix=$PREFIX \
--target=$HOST \
--with-sysroot=$SYSROOT --with-headers=$SYSROOT/usr/include \
--enable-threads=posix --enable-languages=c,c++ &&
make &&
make install
- Un exemple simple: compilons Hello World!
Nous allons utilisé le programme C suivant pour tester si notre cross
compilateur fonctionne. C'est un programme trés simple.
int main()
{ printf("Hello World!\n"); return 0; }
Nous le compilons par:
$HOST-gcc -o main main.c
Nous pouvons maintenant le fichier main sur le système hôte et
l'exécuter!
- Un exemple plus complexe: compilons tar
Nous allons maintenant utiliser la syntaxe correcte de configure pour
activer la cross compilation. DESTDIR est l'argument correct à
utiliser pour make install
avec tout les logiciels
utilisant automake
, ce qui est le cas de tar.
tar zxvf tar-1.15.1.tar.gz &&
cd tar-1.15.1 &&
./configure --prefix=/usr --host=$HOST &&
make &&
make install DESTDIR=$SYSROOT
D'autres logiciels peuvent utiliser la même convention, même s'ils
n'utilisent pas automake
. Si aucune convention n'a été
utilisé, nous pouvons utiliser make install
prefix=$SYSROOT/usr
à la place, mais ceci ne fonctionnera pas
pour les chemins qui ont été passés sur la ligne de commande de
configure. Voici un exemple plus complexe que nous utiliserons dans ce
cas :
./configure --prefix=/usr \
--sysconfdir=/etc \
--localstatedir=/var \
--mandir="\${prefix}/share/man" \
--infodir="\${prefix}/share/info" &&
make &&
make install prefix="${SYSROOT}/usr" \
sysconfdir="${SYSROOT}/etc" \
localstatedir="${SYSROOT}/var"