Toolchain crosstool-NG pour Raspberry Pi

Publié par cpb
Oct 19 2012

Toolchain crosstool-NG pour Raspberry Pi

En complément de l’article sur la préparation d’une toolchain avec Buildroot pour Raspberry Pi, et comme Thomas Petazzoni (dont je vous recommande le blog) l’a suggéré en commentaire, on peut préférer construire la chaîne de compilation avec crosstool-NG. Celle-ci offre plusieurs avantages : la toolchain sera relogeable (déplaçable où l’on souhaite dans l’arborescence sans imposer d’emplacement absolu) et elle pourra s’appuyer sur la bibliothèque GlibC ou la eGlibC plutôt que la bibliothèque uClibC. J’ai choisi ici de sélectionner la bibliothèque eGlibC, plus adaptée à un environnement embarqué.

La compilation de crosstool-NG est très simple, mais elle se fait en deux étapes; ce qui la rend un peu déroutante au premier abord. Il est nécessaire de disposer de certains packages qui ne sont pas toujours installés par défaut sur les distributions classiques. On regardera bien les messages de sortie de la commande configure et les éventuels messages d’erreur en fin de fichier build.log.

Voici la liste des packages que j’ai dû rajouter sur une distribution Lubuntu 12.04 tout juste installée : make, gcc, gdb, flex, bison, gperf, texinfo, gawk, libtool, automake, ncurses-dev, subversion, g++, libexpat1-dev.

Téléchargement et configuration des sources

[~]$ cd Projets/RaspberryPi/
[RaspberryPi]$ wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.16.0.tar.bz2
--2012-10-15 09:41:22--  http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.16.0.tar.bz2
Résolution de crosstool-ng.org (crosstool-ng.org)... 140.211.15.107
Connexion vers crosstool-ng.org (crosstool-ng.org)|140.211.15.107|:80... connecté.
requête HTTP transmise, en attente de la réponse... 200 OK
Longueur: 1957336 (1,9M) [application/x-bzip]
Sauvegarde en : «crosstool-ng-1.16.0.tar.bz2»

100%[===============================================>] 1 957 336    520K/s   ds 3,7s    

2012-10-15 09:41:26 (520 KB/s) - «crosstool-ng-1.16.0.tar.bz2» sauvegardé [1957336/1957336]

[RaspberryPi]$ tar xjf crosstool-ng-1.16.0.tar.bz2 
[RaspberryPi]$ cd crosstool-ng-1.16.0/
[crosstool-ng-1.16.0]$ ./configure --prefix="$PWD/ctng"
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
checking for a BSD-compatible install... /usr/bin/install -c
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for a sed that does not truncate output... /bin/sed
  [...]
[crosstool-ng-1.16.0]$

Préparation du répertoire de compilation

La première invocation de make va préparer le répertoire de compilation de crosstool-NG. Ici j’ai choisi (en argument de ./configure) de travailler dans le sous-répertoire ctng du répertoire des sources.

[crosstool-ng-1.16.0]$ make
  SED    'ct-ng'
  SED    'scripts/crosstool-NG.sh'
  SED    'scripts/saveSample.sh'
  SED    'scripts/showTuple.sh'
  GEN    'config/configure.in'
  GEN    'paths.mk'
  GEN    'paths.sh'
  DEP    'nconf.gui.dep'
  DEP    'nconf.dep'
  DEP    'lxdialog/yesno.dep'
  DEP    'lxdialog/util.dep'
  DEP    'lxdialog/textbox.dep'
  DEP    'lxdialog/menubox.dep'
  DEP    'lxdialog/inputbox.dep'
  DEP    'lxdialog/checklist.dep'
  DEP    'mconf.dep'
  DEP    'conf.dep'
  BISON  'zconf.tab.c'
  GPERF  'zconf.hash.c'
  LEX    'lex.zconf.c'
  DEP    'zconf.tab.dep'
  CC     'zconf.tab.o'
  CC     'conf.o'
  LD     'conf'
  CC     'lxdialog/checklist.o'
  CC     'lxdialog/inputbox.o'
  CC     'lxdialog/menubox.o'
  CC     'lxdialog/textbox.o'
  CC     'lxdialog/util.o'
  CC     'lxdialog/yesno.o'
  CC     'mconf.o'
  LD     'mconf'
  CC     'nconf.o'
  CC     'nconf.gui.o'
  LD     'nconf'
  SED    'docs/ct-ng.1'
  GZIP   'docs/ct-ng.1.gz'
[crosstool-ng-1.16.0]$ make install
  GEN    'config/configure.in'
  GEN    'paths.mk'
  GEN    'paths.sh'
  MKDIR   '/home/cpb/Projets/RaspberryPi/crosstool-ng-1.16.0/ctng/bin/'
  INST    'ct-ng'
  RMDIR   '/home/cpb/Projets/RaspberryPi/crosstool-ng-1.16.0/ctng/lib/ct-ng.1.16.0/'
  MKDIR   '/home/cpb/Projets/RaspberryPi/crosstool-ng-1.16.0/ctng/lib/ct-ng.1.16.0/'
  INSTDIR 'config/'
  INSTDIR 'contrib/'
  INSTDIR 'patches/'
  INSTDIR 'scripts/'
  INST    'steps.mk'
  INST    'paths'
  INSTDIR 'samples/'
  INST    'kconfig/'
  MKDIR   '/home/cpb/Projets/RaspberryPi/crosstool-ng-1.16.0/ctng/share/doc/crosstool-ng/ct-ng.1.16.0/'
  INST    'docs/*.txt'
  MKDIR   '/home/cpb/Projets/RaspberryPi/crosstool-ng-1.16.0/ctng/share/man/man1/'
  INST    'ct-ng.1.gz'

For auto-completion, do not forget to install 'ct-ng.comp' into
your bash completion directory (usually /etc/bash_completion.d)
[crosstool-ng-1.16.0]$

Configuration de la chaîne désirée

Nous pouvons à présent aller dans le sous-répertoire de compilation et y placer un fichier de configuration.

[crosstool-ng-1.16.0]$ cd /ctng/
[ctng]$ PATH="$PATH:$PWD/bin"
[ctng]$ wget https://www.blaess.fr/christophe/files/article-2012-10-19/config-ctng
--2012-10-15 09:57:56--  https://www.blaess.fr/christophe/files/article-2012-10-19/config-ctng
  [...]
100%[=======================================================>] 10 995      --.-K/s   ds 0,09s   

2012-10-15 09:57:59 (120 KB/s) - «config-ctng» sauvegardé [10995/10995]

[ctng]$ mv config-ctng .config
[ctng]$ ct-ng menuconfig
  CONF  config/config.in
[ctng]$

Nous pouvons nous déplacer dans les sous-menus pour observer les options de compilation. J’ai sélectionné un support pour processeur arm1176jzf-s (celui du Raspberry Pi) avec FPU vfp. J’ai choisi un jeu d’instructions arithmétiques hard, mais on peut préférer softfp (je réaliserai ultérieurement des tests pour vérifier les avantages/inconvénients de ces choix).

On peut également noter que je n’ai pas sélectionné la dernière version de la eGlibC mais une antérieure (2.13), car le support pour les RPC a été supprimé des dernières moutures et cela pose problème entre autres pour la compilation de Busybox.

Compilation et installation finale

Lançons ensuite la compilation. Sa durée varie avec le processeur et la connexion réseau entre quelques minutes et une heure environ.

[ctng]$ ct-ng build
[INFO ]  Performing some trivial sanity checks
[INFO ]  Build started 20121015.100328
[INFO ]  Building environment variables
[INFO ]  =================================================================
[INFO ]  Retrieving needed toolchain components' tarballs
[INFO ]  Retrieving needed toolchain components' tarballs: done in 299.57s (at 05:02)
[INFO ]  =================================================================
[INFO ]  Extracting and patching toolchain components
[INFO ]  Extracting and patching toolchain components: done in 74.86s (at 06:17)
[INFO ]  =================================================================
[INFO ]  Installing GMP for host
[INFO ]  Installing GMP for host: done in 37.69s (at 06:54)
[INFO ]  =================================================================
[INFO ]  Installing MPFR for host
[INFO ]  Installing MPFR for host: done in 15.40s (at 07:10)
[INFO ]  =================================================================
[INFO ]  Installing PPL for host
[INFO ]  Installing PPL for host: done in 142.78s (at 09:32)
[INFO ]  =================================================================
[INFO ]  Installing CLooG/PPL for host
[INFO ]  Installing CLooG/PPL for host: done in 6.86s (at 09:39)
[INFO ]  =================================================================
[INFO ]  Installing MPC for host
[INFO ]  Installing MPC for host: done in 7.83s (at 09:47)
[INFO ]  =================================================================
[INFO ]  Installing binutils for host
[INFO ]  Installing binutils for host: done in 44.18s (at 10:31)
[INFO ]  =================================================================
[INFO ]  Installing pass-1 core C compiler
[INFO ]  Installing pass-1 core C compiler: done in 122.82s (at 12:34)
[INFO ]  =================================================================
[INFO ]  Installing kernel headers
[INFO ]  Installing kernel headers: done in 6.91s (at 12:41)
[INFO ]  =================================================================
[INFO ]  Installing C library headers & start files
[INFO ]  Installing C library headers & start files: done in 28.50s (at 13:10)
[INFO ]  =================================================================
[INFO ]  Installing pass-2 core C compiler
[INFO ]  Installing pass-2 core C compiler: done in 139.85s (at 15:30)
[INFO ]  =================================================================
[INFO ]  Installing C library
[INFO ]  Installing C library: done in 487.29s (at 23:37)
[INFO ]  =================================================================
[INFO ]  Installing final compiler
[INFO ]  Installing final compiler: done in 223.49s (at 27:20)
[INFO ]  =================================================================
[INFO ]  Installing libelf for the target
[INFO ]  Installing libelf for the target: done in 6.93s (at 27:27)
[INFO ]  =================================================================
[INFO ]  Installing dmalloc
[INFO ]  Installing dmalloc: done in 10.70s (at 27:38)
[INFO ]  =================================================================
[INFO ]  Installing D.U.M.A.
[INFO ]  Installing D.U.M.A.: done in 1.88s (at 27:40)
[INFO ]  =================================================================
[INFO ]  Installing cross-gdb
[INFO ]  Installing cross-gdb: done in 104.86s (at 29:25)
[INFO ]  =================================================================
[INFO ]  Installing gdbserver
[INFO ]  Installing gdbserver: done in 7.60s (at 29:32)
[INFO ]  =================================================================
[INFO ]  Installing ltrace
[INFO ]  Installing ltrace: done in 5.46s (at 29:38)
[INFO ]  =================================================================
[INFO ]  Cleaning-up the toolchain's directory
[INFO ]    Stripping all toolchain executables
[INFO ]  Cleaning-up the toolchain's directory: done in 2.90s (at 29:41)
[INFO ]  Build completed at 20121015.103309
[INFO ]  (elapsed: 29:40.44)
[INFO ]  Finishing installation (may take a few seconds)...
[29:41] / [ctng]$

La toolchain est installée, nous pouvons supprimer le répertoire de construction et celui des sources.

[ctng]$ cd ../..
[RaspberryPi]$ rm -rf crosstool-ng-1.16.0

Essai de la toolchain

Premier petit test, le lancement du compilateur à vide.

[RaspberryPi]$ ~/x-tools/arm-rpi-linux-gnueabi/bin/arm-rpi-linux-gcc -v
Utilisation des specs internes.
COLLECT_GCC=/home/cpb/x-tools/arm-rpi-linux-gnueabi/bin/arm-rpi-gcc
COLLECT_LTO_WRAPPER=/home/cpb/x-tools/arm-rpi-linux-gnueabi/libexec/gcc/arm-rpi-linux-gnueabi/4.6.3/lto-wrapper
Target: arm-rpi-linux-gnueabi
Configuré avec: /home/cpb/Projets/RaspberryPi/crosstool-ng-1.16.0/ctng/.build/src/gcc-4.6.3/configure --build=i686-build_pc-linux-gnu --host=i686-build_pc-linux-gnu --target=arm-rpi-linux-gnueabi --prefix=/home/cpb/x-tools/arm-rpi-linux-gnueabi --with-sysroot=/home/cpb/x-tools/arm-rpi-linux-gnueabi/arm-rpi-linux-gnueabi/sysroot --enable-languages=c,c++ --with-cpu=arm1176jzf-s --with-fpu=vfp --with-float=hard --with-pkgversion='crosstool-NG 1.16.0 - cpb 2012-10-15' --enable-__cxa_atexit --disable-libmudflap --disable-libgomp --disable-libssp --disable-libquadmath --disable-libquadmath-support --with-gmp=/home/cpb/Projets/RaspberryPi/crosstool-ng-1.16.0/ctng/.build/arm-rpi-linux-gnueabi/buildtools --with-mpfr=/home/cpb/Projets/RaspberryPi/crosstool-ng-1.16.0/ctng/.build/arm-rpi-linux-gnueabi/buildtools --with-mpc=/home/cpb/Projets/RaspberryPi/crosstool-ng-1.16.0/ctng/.build/arm-rpi-linux-gnueabi/buildtools --with-ppl=/home/cpb/Projets/RaspberryPi/crosstool-ng-1.16.0/ctng/.build/arm-rpi-linux-gnueabi/buildtools --with-cloog=/home/cpb/Projets/RaspberryPi/crosstool-ng-1.16.0/ctng/.build/arm-rpi-linux-gnueabi/buildtools --with-libelf=/home/cpb/Projets/RaspberryPi/crosstool-ng-1.16.0/ctng/.build/arm-rpi-linux-gnueabi/buildtools --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm -L/home/cpb/Projets/RaspberryPi/crosstool-ng-1.16.0/ctng/.build/arm-rpi-linux-gnueabi/buildtools/lib -lpwl' --enable-threads=posix --enable-target-optspace --disable-multilib --with-local-prefix=/home/cpb/x-tools/arm-rpi-linux-gnueabi/arm-rpi-linux-gnueabi/sysroot --enable-c99 --enable-long-long --enable-tls
Modèle de thread: posix
gcc version 4.6.3 (crosstool-NG 1.16.0 - cpb 2012-10-15) 
[RaspberryPi]$

À présent compilons un fichier hello-world en version statique afin que l’exécutable ne dépende pas des bibliothèques partagées.

[RaspberryPi]$ ~/x-tools/arm-rpi-linux-gnueabi/bin/arm-rpi-gcc -o hello hello.c -static
[RaspberryPi]$ file hello
hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 3.5.0, not stripped
[RaspberryPi]$

Parfait. Testons-le sur le Raspberry en l’envoyant par le réseau.

[RaspberryPi]$ scp hello root@192.168.5.28:/tmp 
root@192.168.5.28's password: 
hello                                100%  573KB 572.9KB/s   00:00    
[RaspberryPi]$ ssh root@192.168.5.28 /tmp/hello
root@192.168.5.28's password: 
Hello from the crosstool-NG new compiler
[RaspberryPi]$

Pour valider le fonctionnement avec les bibliothèques partagées, il faut installer ces dernières sur le Raspberry Pi. Comme je préfère éviter les confusions entre les bibliothèques issues de la eGlibC compilée avec crosstool-NG et celles provenant de la uClibC compilée par Buildroot, j’ai préféré reconstruire rapidement un système de fichiers avec Busybox et Dropbear.
Voici un exemple après redémarrage du Raspberry Pi sur le nouveau système.

[RaspberryPi]$ ssh root@192.168.5.28
root@192.168.5.28's password: 
root@R-Pi [/root]# uname -a
Linux R-Pi 3.1.9-glmf #22 PREEMPT Fri Aug 17 16:59:34 CEST 2012 armv6l GNU/Linux
root@R-Pi [/root]# /lib/libc.so.6 
GNU C Library (crosstool-NG 1.16.0 - cpb 2012-10-15) stable release version 2.13, by Roland McGrath et al.
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.6.3.
Compiled on a Linux 3.0.39 system on 2012-10-19.
Available extensions:
	crypt add-on version 2.1 by Michael Glad and others
	Native POSIX Threads Library by Ulrich Drepper et al
	Support for some architectures added on, not maintained in glibc core.
	BIND-8.2.3-T5B
libc ABIs: UNIQUE
For bug reporting instructions, please see:
<http://www.eglibc.org/issues/>.
root@R-Pi [/root]# /tmp/hello-shared 
Hello from the crosstool-NG new compiler
root@R-Pi [/root]#

9 Réponses

  1. Patrick Deflandre dit :

    Quelques questions :

    – Pouvez vous me confirmer que lors de la compilation à l’aide de ct-ng d’une chaîne destinée à des projets tournant sous Raspberry Pi avec Raspbian, il est nécessaire de choisir la même version de eglibc que celle distribuée dans la distribution Raspbian, à savoir eglibc 2.13 à ce jour ?

    – Comment tenir compte des variantes Raspbian ? Aujourd’hui, la version est exactement eglibc 2.13-38+rpi2

    – Faut-il recompiler la chaine lors d’un changement version de eglibc par Raspbian ?

    Merci pour toutes les informations que vous publiez. 🙂

    • cpb dit :

      Bonjour,

      En principe la compilation d’une application ne nécessite que la compatibilité avec la version majeure de la bibliothèque. C’est à dire le numéro 2. Le changement de version mineure (13) de la bibliothèque ne devrait pas avoir d’influence sur les applications. En principe…

      Je pense qu’il est possible de recompiler gcc avec ct-ng en s’appuyant sur une libC existante (mais il faut que je vérifie). Si c’est bien le cas, je l’indiquerai ici.

      Une autre possibilité est d’utiliser une compilation native depuis la distribution Raspbian. Mais il ne faut pas être pressé, la compilation sur micro SD est toujours laborieuse.

      • Patrick Deflandre dit :

        Bonjour, et merci pour votre réponse.

        Pour la compilation native, ça ne me convient guère, les ressources du Pi n’étant vraiment pas adapté à des compilations un peu conséquente.

        Pour la libC existante, l’info m’intéresse si vous la trouvez, mais pour le moment, je vais faire avec une version 2.13 standard. Je verrais si cela me pose un problème.

  2. Wess dit :

    Bonjour,

    Est ce que vous pouvez m’aider avec cet erreur s’il vous plait ?

    [INFO ] Installing pass-1 core C compiler
    [ERROR] make[2]: *** [lto-wrapper] Error 1
    [ERROR] make[1]: *** [all-gcc] Error 2
    [ERROR]
    [ERROR] >>
    [ERROR] >> Build failed in step ‘Installing pass-1 core C compiler’
    [ERROR] >> called in step ‘(top-level)’
    [ERROR] >>
    [ERROR] >> Error happened in: CT_DoExecLog[scripts/functions@172]
    [ERROR] >> called from: do_cc_core_backend[scripts/build/cc/gcc.sh@426]
    [ERROR] >> called from: do_cc_core_pass_1[scripts/build/cc/gcc.sh@88]
    [ERROR] >> called from: main[scripts/crosstool-NG.sh@598]
    [ERROR] >>
    [ERROR] >> For more info on this error, look at the file: ‘build.log’
    [ERROR] >> There is a list of known issues, some with workarounds, in:
    [ERROR] >> ‘share/doc/crosstool-ng/ct-ng.1.16.0/B – Known issues.txt’
    [ERROR]
    [ERROR] (elapsed: 18:24.04)
    [18:25] / make: *** [build] Erreur 2

  3. Wess dit :

    Merci pour votre reponse.
    C’est ça ?
    [ALL ] /usr/bin/ld: cannot find -lstdc++
    [ALL ] collect2: ld returned 1 exit status

  4. Wess dit :

    Pour l’info les paquets « libexpat1-dev. » et « ncurses-dev » je n’ai pas pu installer « does not exist » !! j’utilise F15

  5. Wess dit :

    J’arrive a resoudre le probleme j’ai installé les library suivantes
    libstdc++.i686 : GNU Standard C++ Library
    libstdc++-devel.i686 : Header files and libraries for C++ development
    libstdc++-docs.i686 : Documentation for the GNU standard C++ library
    libstdc++-static.i686 : Static libraries for the GNU standard C++ library
    merci en tous les cas 🙂

  6. trucky dit :

    Salut,

    Je suis en train de suivre ton tuto.
    J’aimerai savoir si ta config https://www.blaess.fr/christophe/files/article-2012-10-19/config-ctng est compatible avec celle que tu donne dans ton article d’opensilicium sur l’optimisation du temps de boot : https://www.blaess.fr/christophe/category/raspberry-pi/

    mon but est de démarrer le plus rapidement sous x. Je ne pense pas aller plus loin que ce que tu as fait mais au moins reproduire ce que tu as fait 🙂

URL de trackback pour cette page