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]#
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. 🙂
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
avecct-ng
en s’appuyant sur unelibC
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.
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.
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
Il faudrait voir les lignes déclenchant l’erreur dans le fichier
build.log
qui a été créé pendant la compilation.Merci pour votre reponse.
C’est ça ?
[ALL ] /usr/bin/ld: cannot find -lstdc++
[ALL ] collect2: ld returned 1 exit status
Pour l’info les paquets « libexpat1-dev. » et « ncurses-dev » je n’ai pas pu installer « does not exist » !! j’utilise F15
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 🙂
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 🙂