Outils pour utilisateurs

Outils du site


dev:outils:crosstool

Crosstool

Crosstool est un outil libre écrit par Dan Kegel et placé sous licence GPLv2. Il regroupe un ensemble de scripts permettant de construire une chaine de compilation croisée. Plus complexe à prendre en main qu'une chaine fournie sous forme de binaire telle que ELDK, crosstool apporte cependant plus de souplesse en s'adaptant aux cibles les plus spécifiques, en permettant au developpeur de choisir les versions du compilateur, des bibliothèques et du noyau avec lesquels la chaine sera construite. Crosstool ne fournit pas de chaine de compilation croisée contrairement à ELDK, il permet de la construire.

L'outil crosstool n'évolue plus. Pour générer des chaines de compilation croisée supportant des fonctionnalités rescentes voir l'outil Crosstool-NG.

Installation de Crosstool

Croostool est dsiponible sur le site Dan Kegel à l'adresse http://kegel.com/crosstool/crosstool-0.43.tar.gz

yoann@hermes:~$ cd /tmp/
yoann@hermes:/tmp$ wget http://kegel.com/crosstool/crosstool-0.43.tar.gz
yoann@hermes:/tmp$ tar xf crosstool-0.43.tar.gz
yoann@hermes:/tmp$ sudo mv crosstool-0.43 /opt/
yoann@hermes:/tmp$ cd /opt/crosstool-0.43/

Structure de l'outil

Les scripts nécessaires à la génération de la chaine de compilation croisée sont directement présents dans le répertoire de l'application notamment le script all.sh. Parmis les fichiers on trouve:

  • des fichiers exemples demo-xxx.sh permettant de générer des chaines de compilation types.
  • des fichiers *.dat définissant les variables/environnements nécessaires aux scripts.
  • des fichiers *.config pour les configurations de noyaux vers les cibles compatibles (utilisés par le fichiers .dat).

Le répertoire dowload contiendra les paquets téléchargés par crosstool lors de la compilation de la chaine. Le répertoire patches contient les patchs applicables (le contenu de ce répertoire pourra être étendu si besoin).

Configuration

Avant de pouvoir générer la chaine de compilation croisée il va falloir déterminer:

  • L'environnement hôte,
  • la cible,
  • les versions des paquets (gcc, binutils etc),
  • le noyau,
  • les patchs

Générer une chaine de compilation croisée pour ARM

Un script de démonstration permet de générer une chaine de compilation croisée pour ARM: demo-arm.sh. L'affichage du script révèle:

  • Des variables de configuration notamment RESULT_TOP pour définir le répertoire de destination de la chaine et GCC_LANGUAGES pour définir quels languages pourront être compilés via cette chaine.
  • Un esemble d'appels commentés permettant la compilation de la chaine en utilisant des versions compatibles connues de gcc et de libc. Une seule est décommentée permettant de générer par défaut une chaine de compilation croisée avec gcc-4.1.0 et glibc 2.3.2-lts.

Modification du script demo-arm.sh

Ici, on crée une copie du fichier de demo que l'on va légèrement modifier.

yoann@hermes:/opt/crosstool-0.43$ cp demo-arm.sh my-demo-arm.sh
yoann@hermes:/opt/crosstool-0.43$ vi my-demo-arm.sh

Modifier la valeur de la variable RESULT_TOP pour générer la chaine de compilation croisée dans un répertoire du home utilisateur.

RESULT_TOP=$HOME/crosstool/arm-v1

On profite de la souplesse de Crosstool. On commente la dernière ligne générant une chaine avec gcc 4.1.0 et glibc 2.3.2tls et on introduit une ligne générant plutôt une chaine avec gcc 4.2.2 et glic 2.3.2.

#eval `cat arm.dat gcc-4.1.0-glibc-2.3.2-tls.dat` sh all.sh --notest
eval `cat my-arm.dat gcc-4.2.2-glibc-2.3.2.dat` sh all.sh --notest

Le script utilise à présent deux fichiers n'existant pas encore: gcc-4.2.2-glibc-2.3.2.dat et my-arm.dat. Nous allons les créer à partir des fichiers de configuration existants.

Création du fichier gcc-4.2.2-glibc-2.3.2.dat

Le fichier de configuration gcc-4.2.2-glibc-2.3.2.dat n'existe pas encore, on le crée à partir d'un fichier existant:

yoann@hermes:/opt/crosstool-0.43$ cp gcc-4.1.1-glibc-2.3.2.dat gcc-4.2.2-glibc-2.3.2.dat
yoann@hermes:/opt/crosstool-0.43$ vi gcc-4.2.2-glibc-2.3.2.dat

Modifier la valeur des variables GCC_DIR et LINUX_DIR.

BINUTILS_DIR=binutils-2.16.1
GCC_CORE_DIR=gcc-3.3.6
GCC_DIR=gcc-4.2.2
GLIBC_DIR=glibc-2.3.2
LINUX_DIR=linux-2.6.20
LINUX_SANITIZED_HEADER_DIR=linux-libc-headers-2.6.12.0
GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.3.2
GDB_DIR=gdb-6.5

A présent notre fichier de configuration paramètre une chaine de compilation croisée utilisant gcc en version 4.2.2 et le noyau linux en version 2.6.20.

Création du fichier my-arm.dat

Le script générant notre chaine de compilation s'appuie sur le fichier my-arm.dat pour déterminier la configuration du noyau de la cible. Ce fichier n'existe pas encore, Créons le à partir du fichier existant arm.dat:

yoann@hermes:/opt/crosstool-0.43$ cp arm.dat my-arm.dat
yoann@hermes:/opt/crosstool-0.43$ vi my-arm.dat

Ici, on s'aperçoie que le fichier de configuration du noyau utilisé est le fichier arm.config. On peut modifier la varible TARGET afin de l'adapter à sa cible.

KERNELCONFIG=`pwd`/arm.config
TARGET=arm-crosstool-test-linux-gnu
TARGET_CFLAGS="-O"

Lancer la compilation

Lancer la compilation de notre chaine en executant le script my-demo-arm.sh.

yoann@hermes:/opt/crosstool-0.43$ ./my-demo-arm.sh

1iere tentative

La premiere tentative est abordée, le message suivant est affiché:

No such file `gdb-6.5.tar.bz2'.

+ test -f /home/yoann/downloads/gdb-6.5.tar.bz2
+ abort file gdb-6.5.tar.bz2 not found
+ echo file gdb-6.5.tar.bz2 not found
file gdb-6.5.tar.bz2 not found
+ exec false

Le fichier gdb-6.5.tar;bz2 est introuvable. En remontant les logs, on peut voir que le script le cherche en priorité dans le dossier ./old-releases/ du ftp de redhat. J'explore le ftp à l'aide de ncftp.

yoann@hermes:/opt/crosstool-0.43$ ncftp ftp://sources.redhat.com/pub/gdb/old-releases/
...                                          
Current remote directory is /pub/gdb/old-releases.
ncftp /pub/gdb/old-releases > ls gdb-6.5*
gdb-6.5a.tar.bz2    gdb-6.5a.tar.gz
ncftp /pub/gdb/old-releases >

Une archive gdb-6.5a.tar.bz2 existe, on modifie le fichier pour lui donner cette version de GDB.

2<sup>ième</sup> tentative

A l'etape de compilation de la glibc

checking for arm-unknown-linux-gnu-gcc... gcc
checking version of gcc... 4.4.3, bad
checking for gnumake... no
checking for gmake... no
checking for make... make
checking version of make... 3.81, ok
configure: error:
*** These critical programs are missing or too old: gcc
*** Check the INSTALL file for required versions.
yoann@hermes:/opt/crosstool-0.43$

La vérification de la version de gcc échoue. Un patch permet de modifier ce comportement. Il est fournit dans les ressources additionnelles de l'ouvrage Linux embarqué disponible à l'adresse http://www.editions-eyrolles.com/download/9782212124521/ZeBook3_ex.tgz. Télécharger l'archive, extraire le patch et copier le fichier patch dans l'arborescence de crosstool pour qu'il puisse t'être appliqué.

yoann@hermes:/tmp$ wget http://www.editions-eyrolles.com/download/9782212124521/ZeBook3_ex.tgz
yoann@hermes:/tmp$ tar xf ZeBook3_ex.tgz
yoann@hermes:/tmp$ cd ZeBook3/exemples/chap5/configs/
yoann@hermes:/tmp/ZeBook3/exemples/chap5/configs$ cp patches/glibc-2.3.2/glibc-2.3.3-allow-gcc-4.4-configure.patch /opt/crosstool-0.43/patches/glibc-2.3.2/

Le contenu du patch est donné ci-dessous

*** glibc-2.3.2/configure.old   2009-12-24 18:09:29.050226966 +0100
--- glibc-2.3.2/configure       2009-12-24 18:10:01.458225422 +0100
***************
*** 2272,2278 ****
    ac_prog_version=`$CC -v 2>&1 | sed -n 's/^.*version \([egcygnustpi-]*[0-9.]*\).*$/\1/p'`
    case $ac_prog_version in
      '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
!     3.[2-9]*|4.[01]*)
         ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
      *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;
 
--- 2272,2278 ----
    ac_prog_version=`$CC -v 2>&1 | sed -n 's/^.*version \([egcygnustpi-]*[0-9.]*\).*$/\1/p'`
    case $ac_prog_version in
      '') ac_prog_version="v. ?.??, bad"; ac_verc_fail=yes;;
!     3.[2-9]*|4.[01234]*)
         ac_prog_version="$ac_prog_version, ok"; ac_verc_fail=no;;
      *) ac_prog_version="$ac_prog_version, bad"; ac_verc_fail=yes;;

Remarque: Pour que les patch soient appliqués automatiquement par crosstool, ils doivent se trouver sous le répertoire ./patchs de l'outil et leur nom doit contenir la chaine patch ou le suffixe .diff

Sources

Linux embarqué, Pierre Ficheux et Eric Bénard.
http://www.kegel.com/crosstool/

dev/outils/crosstool.txt · Dernière modification : 2021/02/01 21:51 de 127.0.0.1