Compilation croisée ou compilation à distance ?

Tout d’abord il faut définir ces deux termes :

  • la « cross compilation » ou compilation croisée est le fait de compiler un programme sur une architecture qui n’est pas celle de l’architecture cible. Exemple : vous êtes sur un PC avec un processeur de type Intel en 64bits (architecture LittleEndian) et vous souhaitez compiler pour un RaspberryPi ou une BeagleBoneBlack qui utilise une architecture 32 bits de type ARM (architecture BigEndian). Vous disposez ainsi de toute la puissance et du confort d’une station de travail. Le problème est qu’il faut disposer d’un compilateur croisée.
  • le « remote developpement » ou développement à distance est le fait de saisir son code sur une station de travail performante dans un EDI puis de le transférer et de la compiler sur la cible. Cette technique est plus simple à mettre en œuvre que la précédente mais elle est moins performante car vous compilez sur l’architecture cible qui généralement à des ressources en mémoire et puissance processeur relativement faible.

Dans la suite de cette article, vous mettrez en œuvre ces deux solutions.

Développement à distance

Dans un premier temps, nous allons mettre en œuvre la compilation à distance. L’avantage de cette solution est qu’elle peut être mise en œuvre aussi bien sous Microsoft Windows ou sous GNU/Linux. L’IDE choisi pour mettre en œuvre cette solution est Netbeans 7.4 (pour l’instant la version 8 ne fonctionne pas).

Installation de Netbeans 7.4

Il faut se rendre vers le lien suivant : https://netbeans.org/downloads/7.4/index.html puis choisir sa plateforme (Microsoft Windows ou GNU/Linux) et sa langue. Vous prendrez la version C/C++. Dans tous les cas il faut avoir un environnement d’exécution Java installé (JRE : Java Runtime Environnement).

Sous Microsoft Windows : téléchargez le JRE sur http://java.com/fr/ et sous GNU/Linux : http://java.com/fr/download/help/linux_x64_install.xml . Pour GNU/Linux, dans notre cas Debian GNU/Linux Wheezy 7, il se peut qu’une version du JRE libre existe : faire une recherche avec le mot clé « default-jre » puis l’installer.

Testez alors l’installation de NetBeans 7.4 en l’exécutant.

Configuration de Netbeans 7.4 pour la compilation à distance

Les informations suivantes sont issues en grande partie de : https://netbeans.org/kb/docs/cnd/remotedev-tutorial.html.

Comme pré-requis, vous devez avoir votre cible fonctionnelle : système d’exploitation installé (raspbian sur RaspberryPi, Debian sur BeagleBoneBlack), la configuration réseau doit être fonctionnelle et vous devez connaitre l’adresse ip de votre machine cible, un serveur SSH doit être disponible (apt-get install ssh-server si vous n’êtes pas sur) et enfin un compilateur C++ doit être installé, généralement GNU Compiler (apt-get install build-essentials).

Assurez-vous que vous pouvez « pinguer » votre machine cible depuis votre machine de développement. Lancez alors Netbeans. Cliquez sur le menu « Fenêtres » puis « Services » ou CTRl+F5. Vous devez obtenir la capture suivante :

servicesnetbeansFaites un clic droit sur l’item « C/C++ Build Hosts » puis choisissez « Add new host ». Une nouvelle fenêtre s’ouvre. Dans le champ « Hostname », tapez l’adresse IP de votre machine cible (l’adresse ip de votre raspberry ou votre BBB) puis cliquez sur le bouton « Suivant ».

servicesnetbeanssetuphost Dans la nouvelle fenêtre qui s’ouvre, tapez dans le champ « login » le nom de connexion d’un utilisateur existant sur la cible (dans le cas du raspberrypi, cela peut être pi). Notez que vous pouvez aussi vous connecter sous l’identité « root » si la cible l’autorise.

Laissez l’authentification sur « Password ».

Dans la fenêtre qui s’ouvre alors, tapez le mot de passe dans le champ « Password » voire cochez « Remember password ».

Netbeans va alors tenter de se connecter sur la cible distante et configurer une chaine de compilation. Normalement il devrait trouver une chaine de compilation GNU C++.

Vous obtiendrez alors la capture suivante :

servicesnetbeansremotehostCliquez sur le bouton « Terminer », un nouvel hôte est apparu sous « C/C++ Build Hosts ».

Création d’un projet C++ utilisant le nouvel hôte de compilation à distance

Cliquez sur « Fichier » puis « Nouveau projet ». Dans la fenêtre qui vient d’apparaitre, choisissez « C/C++ Application » puis le bouton « Suivant ». Vous obtiendrez alors la capture suivante :

netbeansnouveauprojetDonnez un nom à votre projet (Project Name). La plupart du temps le projets Netbeans est stocké dans un répertoire NetBeansProjects (Project Location)…laissez-le ici. Le plus important dans notre cas est le choix de la machine de compilation (Build Host). Vérifiez que c’est bien la machine que vous venez de créer à l’étape précédente. Cliquez alors sur le bouton « Terminer ».

netbeansprojectDans l’arbre des projets, dépliez l’item « Source Files » puis double-cliquez sur le fichier « main.cpp ». Celui-ci apparaitra alors dans la zone d’édition.Modifiez-le pour obtenir le code suivant :

Lancez la compilation de ce code par le menu « Exécuter » puis « Construire projet ». Netbeans va alors se connecter sur la machine distante, transférer les fichiers puis les compiler. S’il n’y a pas d’erreurs de compilation vous obtiendrez la capture suivante :

netbeanscompilationConnexion à l’hôte distant et exécution du programme

Vous venez de compiler votre projet. Pour exécuter votre programme vous pouvez passer par « Exécuter » puis « Exécuter projet » ou appuyez sur la touche F6. Le programme s’exécutera sur la machine cible et les entrées/sorties console seront redirigés dans la fenêtre de sortie en bas de l’EDI.

Vous pouvez aussi vous connecter à distance par SSH par exemple à l’aide de putty sous Microsoft Windows. Il vous faudra alors rentrer dans le répertoire caché « .netbeans ». Déplacez-vous alors jusqu’au répertoire « dist » de votre projet. Vous pouvez alors lancer votre exécutable en tapant « ./nom_du_programme ».

Compilation croisée

Pour cette partie il y aura un prérequis important : utiliser une distribution qui propose une chaine de cross-compilation récente. Le choix de la distribution GNU/Linux sera donc soit Ubuntu (XUbuntu 14) soit pour ma part Debian GNU/Linux Jessie (la future version stable de Debian).

Installation de GNU/Linux Jessie

Vous pouvez installer Debian Jessie dans une machine virtuelle. L’image ISO utilisée sera http://cdimage.debian.org/cdimage/weekly-builds/amd64/iso-cd/debian-testing-amd64-netinst.iso . L’interface graphique n’est pas nécessaire mais peut faciliter le développement avec l’utilisation d’un EDI comme NetBeans. Dans ce cas je vous conseille une interface légère comme celle fournie par le bureau xfce. Il faudra rajouter dans les dépots Debian les sources « contrib » et « non-free » : éditez le fichier /etc/apt/sources.list puis faire un apt-get update et apt-get upgrade. Installez ensuite Netbeans 7.4 (open-jdk-7 est installé par défaut si vous avez installé l’environnement graphique).

Installation de la chaine de compilation croisée

Il existe plusieurs chaines de compilation croisée (armel, armhf, arm64, etc…). Deux chaines nous intéressent :

  • armel : cette chaine de compilation supporte les architectures qui n’ont pas d’unité de calcul en virgule flottante matériel. Nous utiliserons cette chaine pour le RaspberryPi (même si celui-ci par l’intermédiaire d’une chaine de compilation spécialement compilé pour lui à un module de calcul),
  • armhf : cette chaine de compilation supporte les architectures avec virgule flottante (hf = hard float). Cette chaine sera utilisée pour la BeagleBoneBlack.

Debian présente l’installation des chaines de compilation croisée sur cette page. Ce qui suit est donc issu de cette page. Dans ce qui suit, il faut être root ou utiliser la commande ‘sudo’.

Il faut tout d’abord installer le logiciel curl:

Modifiez ensuite le fichier des dépots Debian:

et ajoutez la ligne suivante :

Il faut rajouter la signature des dépôts emdebian (debian pour les cibles embarquées) :

Sauvez le fichier. Puis tapez les commandes suivantes qui installerons le cross compilateur pour une architecture armhf (carte BeagleBoneBlack par exemple):

Il se peut que la dernière commande ne fonctionne pas. Dans ce cas tapez la commande suivante :

Dans le cas d’une carte RaspberryPi, vous pouvez installer le cross-compilateur pour architecture armel :

Si la dernière ligne ne fonctionne pas, tapez la commande suivante :

Testez ensuite que les compilateurs sont correctement installés. Pour le compilateur à destination de la plateforme armel :

Pour le compilateur à destination de la plateforme armhf :

Intégration des chaines de cross compilation dans NetBeans

Lancez Netbeans. Cliquez sur le menu « Outils » puis « Options » et enfin cliquez sur l’onglet C/C++. Vous obtenez la capture suivante :

netbeanscrossoptionscCliquez sur le bouton « Add… » pour ajouter une nouvelle chaine de compilation. Complétez les différents champs comme dans la capture ci-dessous :

netbeanscrossaddnewtoolCliquez sur le bouton « OK » puis compléter les différents champs comme dans la capture ci-dessous :

netbeanscrossoptionsc2Lorsque vous cliquerez sur le bouton « OK » vous aurez alors une nouvelle chaine de compilation disponible. Créez un nouveau projet C++, au moment de choisir le nom du projet, vérifiez que la chaine de compilation correspond à celle que vous venez de créer :

netbeanscrossoptionsc3Ici il s’agit du champ « Tool Collection » et l’on a bien notre chaine de compilation « GNU_Armhf (GNU) ».

Modifiez le fichier « main.cpp » de la même manière que précédemment (affichez le message « Hello ARMhf ») puis lancez la compilation par le menu « Exécuter » puis « Construire projet ». Vous obtiendrez alors dans la fenêtre de sortie, le résultat de compilation suivant :

netbeanscrosscompilationarmhfPour vérifier que l’on a bien un exécutable pour plateforme ARM, on peut utiliser la commande ‘file’ et l’on obtient :

netbeanscrossfilearmhfIl reste alors à transférer l’exécutable vers la plateforme cible par la commande ‘scp’. Par exemple, si vous avez votre beagleboneblack sur votre réseau en 192.168.1.51 avec un utilisateur qui s’appelle ‘bbb’, vous pouvez transférer l’exécutable généré avec la commande suivante :

Connectez-vous par ssh sur votre plateforme linux embarqué puis exécutez votre programme :

A titre d’exercice, vous pouvez créer une chaine de compilation par armel.

2 réflexions au sujet de « Compilation croisée ou compilation à distance ? »

  1. oriano

    Bonjour,

    Merci pour le tutoriel.
    J’ai bien réussi à faire ma compilation croisée. C’est cool.
    J’ai cependant une question, pour de ce qui est des librairies annexes comme wiringPi ou Mysqlconnector++
    Comment les intégrer à la compilation ?

    J’ai pas mal cherché sur internet et j’ai trouvé quelques explications mais jamais avec Netbeans, j’ai donc essayé de les adapter sans résultat convainquant.

    Voilà le tuto que j’ai en partit suivi pour intégrer la lib : https://wiki.electroniciens.cnrs.fr/index.php/Installation_d'une_cha%C3%AEne_de_compilation_crois%C3%A9e_%28GCC%29_sous_Eclipse

    Cordialement,

  2. gilles

    Bonjour Oriano,

    la technique de transferer les bibliotheque du site donné en lien est complètement pourri … a chaque fois il faut recompiler la bibli que l’on a besoin la transférer etc :/

    Ma solution :

    Monter direct une image iso d’un système complet raspbian sur le linux qui sert a coder, quand on a besoin d’une nouvelle bibli : on démonte l’iso et on la charge dans QEmu (émulateur de raspberry), on compile ce que l’on veut, on fait des apt-get etc etc comme si on était sur un vrai raspberry, une fois finis on arrete QEmu, on remonte l’iso et voila !! toute les libs sont présentes et disponible /point_demontage/route_systeme_raspbian_de_la_lib

    Attention cependant a « couper » l’iso raspbian proprement pour ne garder que la partis linux, exemple montage : sudo mount -o loop,offset=62914560 2015-05-05-raspbian-wheezy.img /mnt/rasp-sys

    ici on coupe a 62914560 pour virer la partie FAT

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *