C devel cross
Introduction
Lorsque l'on compile un programme en C on passe par tout une chaîne de logiciels que l'on appel la chaîne de compilation (toolchain). Si l'on prend le cas de la chaîne de compilation GNU (GNU toolchain), elle est composée de:
- binutils : utilitaires permettant la conversion du pseudo-code généré par la compilation en instructions comprises par le processeur cible (assembleur);
- gcc : les compilateurs C et C++ (gcc et g++);
- glibc, bibliothèque pour les appels au noyau et le traitement bas-niveau (stdio.h, stdlib.h, pthread.h, etc...);
- les en-têtes du noyau requis par la bibliothèque glibc (linux-headers dans le cas du noyau Linux) ;
- gdb, déboguer pour chaîne binaire déjà compilée;
La compilation se fait sur et pour la même architecture que la machine de développement. La compilation croisée permet de modifier l'architecture cible !
On peut alors développer sur une architecture 64 bits Linux (ou Windows) et compiler son programme pour une architecture MIPS, PPC, ARM, AVR, etc...
Pré-requis
Récupération de la chaîne de compilation
Tout d'abord il faut cerner l'architecture cible ! Dans cet exemple, nous allons utiliser un OrangePi Zéro:
Cette carte utilise un SoC AllWinner H2+ et d'après la documentation de AllWinner le CPU est un ARM Cortex-A7 (32 bits):
Il faut maintenant déterminer quelle version de la chaîne de compilation récupérer, cela se décide en fonction du système d'exploitation présent sur la machine:
root@orangepizero:~# ll /usr/lib/gcc total 4 drwxr-xr-x 3 root root 4096 Apr 6 2019 arm-linux-gnueabihf root@orangepizero:~# ll /usr/lib/gcc/arm-linux-gnueabihf/ total 4 drwxr-xr-x 5 root root 4096 Feb 7 19:38 8
On apprend que la chaîne de compilation:
- arm-linux-gnu → est libre ;
- eabi → utilise l'interface binaire-programme embarquée (Embedded ABI);
- hf → utilise une unité de calcul en virgule flottant (hardware FPU).
Il faudra donc récupérer la bonne chaîne de compilation pour sur le site arm.com:
Sur ce système la chaîne de compilation est en version 8.3.0, nous pouvons donc choisir de déplier la section 8.3:
Et télécharger la chaîne de compilation appropriée pour l'architecture de développement (Linux 64bits) et l'architecture cible (eabihf):
Installation de la chaîne de compilation
Il faut maintenant installer la chaîne compilation sur le système cible pour pouvoir l'utiliser. Pour ce faire nous allons décompresser l'archive dans un dossier:
# cd /opt # tar -xf /CHEMIN_VERS_LA_CHAINE/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz
Puis créer un lien symbolique dans le dossier /usr/bin qui se trouve dans la variable PATH de l'environnement:
# chmod +x -R /CHEMIN_VERS_LA_CHAINE/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin # ln -fs /CHEMIN_VERS_LA_CHAINE/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ /usr/bin/ # ln -fs /CHEMIN_VERS_LA_CHAINE/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc /usr/bin/
On peut vérifier la version du compilateur:
[root@DESKTOP-19AIBA2 ~]# arm-linux-gnueabihf-gcc -v Using built-in specs. COLLECT_GCC=arm-linux-gnueabihf-gcc COLLECT_LTO_WRAPPER=/mnt/c/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin/../libexec/gcc/arm-linux-gnueabihf/8.3.0/lto-wrapper Target: arm-linux-gnueabihf Configured with: /tmp/dgboter/bbs/rhev-vm8--rhe6x86_64/buildbot/rhe6x86_64--arm-linux-gnueabihf/build/src/gcc/configure --target=arm-linux-gnueabihf --prefix= --with-sysroot=/arm-linux-gnueabihf/libc --with-build-sysroot=/tmp/dgboter/bbs/rhev-vm8--rhe6x86_64/buildbot/rhe6x86_64--arm-linux-gnueabihf/build/build-arm-linux-gnueabihf/install//arm-linux-gnueabihf/libc --with-bugurl=https://bugs.linaro.org/ --enable-gnu-indirect-function --enable-shared --disable-libssp --disable-libmudflap --enable-checking=release --enable-languages=c,c++,fortran --with-gmp=/tmp/dgboter/bbs/rhev-vm8--rhe6x86_64/buildbot/rhe6x86_64--arm-linux-gnueabihf/build/build-arm-linux-gnueabihf/host-tools --with-mpfr=/tmp/dgboter/bbs/rhev-vm8--rhe6x86_64/buildbot/rhe6x86_64--arm-linux-gnueabihf/build/build-arm-linux-gnueabihf/host-tools --with-mpc=/tmp/dgboter/bbs/rhev-vm8--rhe6x86_64/buildbot/rhe6x86_64--arm-linux-gnueabihf/build/build-arm-linux-gnueabihf/host-tools --with-isl=/tmp/dgboter/bbs/rhev-vm8--rhe6x86_64/buildbot/rhe6x86_64--arm-linux-gnueabihf/build/build-arm-linux-gnueabihf/host-tools --with-arch=armv7-a --with-fpu=neon --with-float=hard --with-arch=armv7-a --with-pkgversion='GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36)' Thread model: posix gcc version 8.3.0 (GNU Toolchain for the A-profile Architecture 8.3-2019.03 (arm-rel-8.36))
Projet C++ en compilation croisée sous Eclipse
Il faut démarrer l'assistant de création d'un projet C/C++:
Sélectionner un projet C ou C++ (au choix) |
Choisir le projet Hello Wolrd Cross GCC |
Préciser le préfixe du compilateur croisé (ici arm-linux-gnueabihf-) | ||
Maintenant que le projet est créé, il faut le compiler grâce au marteau
Le résultat de la compilation se trouve dans le répertoire Debug |
Il ne reste plus qu'a transférer le binaire sur l'Orange Pi pour l'exécuter ! | |
Il ne reste plus qu'a transférer le binaire sur la machine cible (Orange Pi Zero):