Mise en oeuvre de Qt5 sur Raspberry Pi

Qt est un ensemble de bibliotèques orientées objet développées en C++ et regroupées en modules. Ceux-ci offrent notamment des composants d’interface graphique (widgets), d’accès aux données, de connexions réseaux, de gestion des fils d’exécution, d’analyse XML, … Qt Creator est l’environnement de développement intégré permettant la réalisation d’applications Qt.

→ Ici, on utilisera la dernière version stable de Qt Qt disponible : 5.11.2.

Lien : Ressources Qt

Le Raspberry Pi est un nano-ordinateur monocarte à processeur ARM. Ce système embarqué peut fonctionner avec les systèmes d’exploitation GNU/Linux, Windows 10 IoT Core et Android Pi.

Lien : cours-raspberrypi.pdf

→ Ici, on utilisera la dernière Raspbian Stretch disponible : 2018-11-13-raspbian-stretch sur Raspberry Pi 3.

Lien : wiki.qt.io/RaspberryPi

Présentation

L’installation de Qt sur Raspberry Pi peut être réalisée de différentes manières :

  • à partir des paquets présents dans les dépôts officiels : la version fournie est figée (Qt 5.7.1 fin 2018) mais elle est “prête à l’emploi”.
  • à partir des sources de Qt : http://download.qt.io/official_releases/qt/ ou https://code.qt.io/

Le développement d’applications Qt sur Raspberry Pi peut être réalisé de différentes manières :

  • directement sur Raspberry Pi en mode CLI (qmake puis make) ou GUI avec Qt Creator
  • sur un PC de développement en utilisant une chaîne de compilation croisée (cross compilation) généralement avec Qt Creator configuré pour cela

L’installation sur Raspberry Pi devra réaliser les étapes suivantes :

  • télécharger les sources de Qt avec git clone ou wget
  • configurer le mécanisme de fabrication avec ./configure (les options définiront votre personnalisation de Qt)
  • fabriquer avec make
  • installer avec make install

Pour disposer d’une chaîne de compilation croisée sur PC, il faudra reproduire ces étapes sur sa machine en y intégrant :

  • l’installation de la chaîne de compilation croisée pour Raspberry Pi sur le PC (arm-linux-gnueabihf)
  • l’accès aux fichiers de développement sur Raspberry Pi (sysroot)
  • le déploiement de Qt sur Raspberry Pi (dans /usr/local/qt5pi par exemple)
  • la configuration de Qt Creator sur le PC

Qt5 sur Raspberry Pi

Installation à partir des paquets du dépôt

Actuellement la version disponible est Qt 5.7.1 :

$ apt-cache show qt5-default
Package: qt5-default
Source: qtbase-opensource-src
Version: 5.7.1+dfsg-3+rpi1
Architecture: armhf
...

Les paquets disponibles pour qtbase5 sont :

$ apt-cache search qtbase5
qtbase5-dev - Qt 5 base development files
qtbase5-dev-tools - Qt 5 base development programs
qtbase5-doc - Qt 5 base documentation
qtbase5-doc-html - Qt 5 base HTML documentation
qtbase5-examples - Qt 5 base examples
qtbase5-private-dev - Qt 5 base private development files

Les paquets disponibles pour Qt 5 sont :

$ apt-cache search qt5- | grep -E "^qt5-"
qt5-default - Qt 5 development defaults package
qt5-doc - Qt 5 API Documentation
qt5-doc-html - Qt 5 API documentation (HTML format)
qt5-gtk-platformtheme - Qt 5 GTK+ 3 platform theme
qt5-image-formats-plugins - Qt 5 Image Formats module
qt5-qmake - Qt 5 qmake Makefile generator tool
qt5-qmltooling-plugins - Qt 5 qmltooling plugins
qt5-style-plugins - Qt 5 extra widget styles

La plupart des modules de Qt sont fournis par des bibliothèques :

$ apt-cache search qt | grep -E "^libqt5"
...
libqt5multimedia5 - Qt 5 Multimedia module
...
libqt5network5 - Qt 5 network module
...
libqt5qml5 - Qt 5 QML module
libqt5serialport5 - Qt 5 serial port support
libqt5sql5 - Qt 5 SQL module
libqt5sql5-mysql - Qt 5 MySQL database driver
libqt5sql5-sqlite - Qt 5 SQLite 3 database driver
...
libqt5widgets5 - Qt 5 widgets module
...

Pour obtenir une version de base, on pourra sélectionner simplement le paquet qt5-default qui entraînera l’installation automatiquement des paquets qt5-qmake, qtbase5-dev et qtbase5-dev-tools.

$ sudo apt-get install qt5-default

Vous pouvez aussi installer qtcreator ce qui déclenchera l’installation entre autres des paquets suivants :

libqt5designer5 libqt5designercomponents5 libqt5help5 libqt5qml5 libqt5quick5 libqt5quicktest5 libqt5quickwidgets5 libqt5script5 libqt5test5 libqt5webkit5 libqt5xmlpatterns5 qt5-doc qt5-qmltooling-plugins qtbase5-dev-tools qtbase5-doc qtchooser qtconnectivity5-doc qtdeclarative5-dev-tools qtdeclarative5-doc qtgraphicaleffects5-doc qtlocation5-doc qtmultimedia5-doc qtquickcontrols2-5-doc qtquickcontrols5-doc qtscript5-doc qtsensors5-doc qtserialport5-doc qtsvg5-doc qttools5-dev-tools qttools5-doc qtwayland5-doc qtwebchannel5-doc qtwebengine5-doc qtwebkit5-doc qtwebkit5-examples-doc qtwebsockets5-doc qtx11extras5-doc qtxmlpatterns5-dev-tools qtxmlpatterns5-doc
$ sudo apt-get install qtcreator

Remarque : Qt4 version 4.8.7 est toujours disponible dans les dépôts.

Préparation sur Raspberry Pi

Tout d’abord, il faut mettre son système à jour :

$ sudo rpi-update
$ sudo reboot
$ sudo apt-get update
$ sudo apt-get upgrade

Pour commencer, il faut une chaîne de compilation C++ :

$ sudo apt-get install build-essential

Un certain nombre de paquets sont recommandés pour Qt5 :

$ sudo apt-get install libfontconfig1-dev libdbus-1-dev libfreetype6-dev libicu-dev libudev-dev libinput-dev libxkbcommon-dev libssl-dev libpng-dev libjpeg-dev libglib2.0-dev libraspberrypi-dev

Ensuite, il vous faut définir vos besoins, par exemple :

Fonctionnalité Paquet(s)
Bluetooth sudo apt-get install bluez libbluetooth-dev
Multimédia sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly gstreamer1.0-plugins-bad libgstreamer-plugins-bad1.0-dev gstreamer1.0-pulseaudio gstreamer1.0-tools gstreamer1.0-alsa
Audio sudo apt-get install libasound2-dev pulseaudio libpulse-dev
Base de données sudo apt-get install libpq-dev libmariadbclient-dev libmariadbclient-dev-compat libsqlite3-dev
Impression sudo apt-get install libcups2-dev
X11 sudo apt-get install libx11-dev libxcb1-dev libxkbcommon-x11-dev libx11-xcb-dev libxext-dev
Accessibilité sudo apt-get install libatspi-dev
WebKit sudo apt-get install libicu-dev libsqlite3-dev libxslt1-dev libssl-dev

En résumé, il est possible d’installer les paquets suivants :

sudo apt-get install -y build-essential libfontconfig1-dev libdbus-1-dev libfreetype6-dev libicu-dev libudev-dev libinput-dev libxkbcommon-dev libssl-dev libpng-dev libjpeg-dev libglib2.0-dev libraspberrypi-dev
sudo apt-get install -y bluez libbluetooth-dev
sudo apt-get install -y libavcodec-dev libavformat-dev libswscale-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly gstreamer1.0-plugins-bad libgstreamer-plugins-bad1.0-dev gstreamer1.0-pulseaudio gstreamer1.0-tools gstreamer1.0-alsa
sudo apt-get install -y libasound2-dev pulseaudio libpulse-dev
sudo apt-get install -y libsqlite3-dev libpq-dev libmariadbclient-dev libmariadbclient-dev-compat
sudo apt-get install -y libcups2-dev
sudo apt-get install -y libx11-dev libxcb1-dev libxkbcommon-x11-dev libx11-xcb-dev libxext-dev
sudo apt-get install -y libatspi-dev
sudo apt-get install -y libwayland-dev

Et aussi :

sudo apt-get install -y libxslt1-dev libavcodec-dev libavformat-dev libswscale-dev libpulse-dev freetds-dev libiodbc2-dev firebird-dev libjpeg9-dev libgst-dev libxext-dev libxcb1 libx11-xcb1 libxcb-keysyms1 libxcb-keysyms1-dev libxcb-image0 libxcb-image0-dev libxcb-shm0 libxcb-shm0-dev libxcb-icccm4 libxcb-icccm4-dev libxcb-sync1 libxcb-sync-dev libxcb-render-util0 libxcb-render-util0-dev libxcb-xfixes0-dev libxrender-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-glx0-dev libxi-dev libdrm-dev libxcb-xinerama0 libxcb-xinerama0-dev vim

Installation à partir des sources de Qt

Si vous voulez disposer d’une version particulière de Qt, vous devez envisager de compiler Qt par vos soins en le téléchargeant. Vous devez aussi disposer des outils pour le faire.

Il y a deux possibilités :

  • en téléchargeant les sources avec wget sur download.qt.io.
  • en clonant le dépôt git avec git clone à partir de code.qt.io

C’est une méthode destinée à personnaliser son environnement Qt et vous aurez probablement besoin d’installer des paquets en conséquence. Il n’y a donc pas de procédure générique.

Création d’un répertoire de travail :

$ cd ~
$ mkdir raspi
$ cd raspi

Télécharger les sources de Qt :

$ wget http://download.qt.io/official_releases/qt/5.11/5.11.2/single/qt-everywhere-src-5.11.2.tar.xz
$ tar xf qt-everywhere-src-5.11.2.tar.xz

Remarque : on aurait pu aussi utiliser le dépôt git de Qt

$ git clone https://code.qt.io/qt/qt5.git
$ cd qt5
$ git checkout 5.11
$ git submodule update --init
$ cd ..

Création du répertoire de build :

$ mkdir build
$ cd build

À ce stade, vous devez avoir un répertoire raspi contenant :

build/
qt-everywhere-src-5.11.2/

Configuration de la fabrication :

Le processus de configuration est assuré par le script configure. Il dispose de nombreuses options :

$ ../qt-everywhere-src-5.11.2/configure -h

Lien : doc.qt.io

Les options de base sont :

-no-compile-examples : ne compile pas les exemples fournis (gain de temps)
-nomake examples : ne compile pas les exemples fournis (gain de temps)
-nomake tests : pas besoin de la suite de tests (gain de temps)
-opengl es2 : précise le support d'OpenGL, ici es2 pour Raspberry Pi
-device linux-rasp-pi3-g++ : pour Raspberry Pi 3 (cf. voir le répertoire qtbase/mkspecs/devices)        
-device-option CROSS_COMPILE=/usr/bin/ : précise le préfixe de chacune des commandes de compilation.
-prefix /opt/Qt5.11 : le répertoire d'installation
-confirm-license -opensource        
-release : indique de construire avec des paramètres optimisés
Device Plateforme
linux-rasp-pi-g++ ARMv6, tous les modèles Raspberry Pi
linux-rasp-pi2-g++ ARMv7, pour Raspberry Pi 2 & 3
linux-rasp-pi3-g++ ARMv8, pour Raspberry Pi 3

L’option -skip permet d’éviter de fabriquer certains modules de Qt.

C’est parti :

$ PKG_CONFIG_LIBDIR=/usr/lib/arm-linux-gnueabihf/pkgconfig:/usr/share/pkgconfig 
$ PKG_CONFIG_SYSROOT_DIR=/

$ ../qt-everywhere-src-5.11.2/configure -v -opengl es2 -eglfs -no-gtk -device linux-rasp-pi3-g++ -device-option CROSS_COMPILE=/usr/bin/ -opensource -confirm-license -release -reduce-exports -force-pkg-config -no-kms -nomake examples -no-compile-examples -no-pch -skip qtwayland -skip qtwebengine -no-feature-geoservices_mapboxgl -qt-pcre -ssl -evdev -system-freetype -fontconfig -glib -prefix /opt/Qt5.11

Le script configure affiche un rapport final. Il vous faut vérifier l’état des dépendances avant de continuer.

Vous pouvez recommencer le processus de configuration avec l’option -recheck-all ou simplement -recheck pour les dépendances qui ont échouées.

Fabrication :

Le processus va s’avérer assez long sur Raspberry Pi, il faut alors ajouter l’option -j44 est le nombre de coeurs à allouer (pour une RPI 3).

$ make -j4

Installation :

$ sudo make install

Vérification :

$ ls -l /opt/Qt5.11/bin/
$ /opt/Qt5.11/bin/qmake -v

Il est possible d’ajouter le chemin /opt/Qt5.11/bin/ dans son PATH :

$ export PATH=$PATH:/opt/Qt5.11/bin

Pour finir, il vous faut mettre cette ligne dans votre .bashrc puis le recharger :

$ . ~/.bashrc

La chaîne de compilation Qt5 est prête à l’emploi.

Test :

Importer un exemple Qt puis fabriquer l’exécutable :

$ qmake
$ make

Voir : tests ci-dessous.

Installation de la chaîne de compilation croisée

Une chaîne de compilation (toolchain) désigne l’ensemble des paquets utilisés dans le processus de compilation d’un programme, pour un processeur donné. Le compilateur n’est qu’un élément de cette chaîne, laquelle varie selon l’architecture matérielle cible. Une chaîne de compilation croisée est une chaîne compilée pour fonctionner sur l’architecture de processeurs de la machine hôte, mais qui va compiler des logiciels pour une architecture cible différente. La compilation croisée fait donc référence aux chaînes de compilation capables de traduire un code source en code objet dont l’architecture processeur diffère de celle où la compilation est effectuée. Ces chaînes sont principalement utilisées en informatique industrielle et dans les systèmes embarqués.

  • Sur Raspberry Pi :

L’installation de Qt se fera à la fin dans /usr/local/qt5pi :

$ sudo mkdir /usr/local/qt5pi
$ sudo chown pi:pi /usr/local/qt5pi
  • Sur le PC (ici sous Ubuntu 18.04 LTS) :

Création d’un répertoire de travail :

$ cd ~
$ mkdir raspi
$ cd raspi

Télécharger les sources de Qt :

$ wget http://download.qt.io/official_releases/qt/5.11/5.11.2/single/qt-everywhere-src-5.11.2.tar.xz
$ tar xf qt-everywhere-src-5.11.2.tar.xz

Télécharger la chaîne de compilation croisée pour Raspberry Pi :

$ git clone https://github.com/raspberrypi/tools

Création du sysroot :

$ mkdir sysroot sysroot/usr sysroot/opt
$ rsync -avz pi@W.X.Y.Z:/lib sysroot
$ rsync -avz pi@W.X.Y.Z:/usr/include sysroot/usr
$ rsync -avz pi@W.X.Y.Z:/usr/lib sysroot/usr
$ rsync -avz pi@W.X.Y.Z:/opt/vc sysroot/opt

Mise à jour des liens symboliques du sysroot :

$ wget https://raw.githubusercontent.com/riscv/riscv-poky/priv-1.10/scripts/sysroot-relativelinks.py
$ chmod +x sysroot-relativelinks.py
$ ./sysroot-relativelinks.py sysroot

Création du répertoire de build :

$ mkdir build
$ cd build

À ce stade, vous devez avoir un répertoire raspi contenant :

build/
qt-everywhere-src-5.11.2/
sysroot/
tools/

sysroot-relativelinks.py
qt-everywhere-src-5.11.2.tar.xz

Configuration de la fabrication :

Le processus de configuration est assuré par le script configure. Il dispose de nombreuses options :

$ ../qt-everywhere-src-5.11.2/configure -h

Lien : doc.qt.io

Les options de base sont :

-no-compile-examples : ne compile pas les exemples fournis (gain de temps)
-nomake examples : ne compile pas les exemples fournis (gain de temps)
-nomake tests : pas besoin de la suite de tests (gain de temps)
-opengl es2 : précise le support d'OpenGL, ici es2 pour Raspberry Pi
-device linux-rasp-pi3-g++ : pour Raspberry Pi 3 (cf. voir le répertoire qtbase/mkspecs/devices)        
-device-option CROSS_COMPILE=~/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf- : précise le préfixe de chacune des commandes de compilation croisées.
-sysroot ~/raspi/sysroot : le chemin d'accès à la racine système sysroot
-prefix /usr/local/qt5pi : le chemin de déploiement sur Raspberry Pi (utilisé lors de la configuration des chemins absolus pour les fichiers binaires liés)
-extprefix /usr/local/rpi3/qt5pi : le répertoire d'installation sur le PC où vont se retrouver les fichiers fabriqués (ce n'est pas le chemin sur la cible)
-hostprefix /usr/local/rpi3/qt5 : le répertoire d'installation des outils de fabrication pour le PC
-confirm-license -opensource        
-release : indique de construire avec des paramètres optimisés (sans debug)
Device Plateforme
linux-rasp-pi-g++ ARMv6, tous les modèles Raspberry Pi
linux-rasp-pi2-g++ ARMv7, pour Raspberry Pi 2 & 3
linux-rasp-pi3-g++ ARMv8, pour Raspberry Pi 3

L’option -skip permet d’éviter de fabriquer certains modules de Qt.

Remarque : ici le sysroot et la chaîne de compilation croisée sont situés dans le répertoire personnel de l’utilisateur. Il est évidemment possible de les stocker dans /usr/local/rpi3. Il suffit alors de changer les chemins dans la commande configure.

../qt-everywhere-src-5.11.2/configure -v -opengl es2 -eglfs -device linux-rasp-pi3-g++ -device-option CROSS_COMPILE=~/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf- -sysroot ~/raspi/sysroot -opensource -confirm-license -release -nomake tests -nomake examples -no-compile-examples -skip qtwayland -skip qtwebengine -skip qtlocation -skip qtscript -prefix /usr/local/qt5pi -extprefix /usr/local/rpi3/qt5pi -hostprefix /usr/local/rpi3/qt5 -no-use-gold-linker

Le script configure affiche un rapport final. Il vous faut vérifier l’état des dépendances avant de continuer.

...

Qt is now configured for building. Just run 'make'.
Once everything is built, you must run 'make install'.
Qt will be installed into '/usr/local/rpi3/qt5pi'.

Prior to reconfiguration, make sure you remove any leftovers from
the previous build.

Vous pouvez recommencer le processus de configuration avec l’option -recheck-all ou simplement -recheck pour les dépendances qui ont échouées.

Fabrication :

Le processus pouvant s’avérer un peu long, vous pouvez ajouter l’option -jnn est le nombre de coeurs à allouer.

$ make -j4

Installation :

$ sudo make install

Vous devez obtenir les répertoires suivants :

$ ls /usr/local/rpi3/
qt5  qt5pi

$ ls /usr/local/rpi3/qt5/
bin  mkspecs

$ ls /usr/local/rpi3/qt5pi/
bin  doc  include  lib  plugins  qml  qtvirtualkeyboard  translations

Déploiement sur Rapsberry Pi :

cd /usr/local/rpi3/
sudo rsync -avz qt5pi pi@W.X.Y.Z:/usr/local

Compilation d’un module ou plugin supplémentaire :

$ cd ~/raspi/build/
$ git clone git://code.qt.io/qt/qtmqtt.git
$ cd qtmqtt
$ /usr/local/rpi3/qt5/bin/qmake
$ make
$ sudo make install

Il vous faudra alors déployer les ajouts :

cd /usr/local/rpi3/
sudo rsync -avz qt5pi pi@W.X.Y.Z:/usr/local
  • Sur Raspberry Pi :

Finalisation :

$ echo /usr/local/qt5pi/lib | sudo tee /etc/ld.so.conf.d/qt5pi.conf
$ sudo ldconfig

$ sudo mv /usr/lib/arm-linux-gnueabihf/libEGL.so.1.0.0 /usr/lib/arm-linux-gnueabihf/libEGL.so.1.0.0_backup
$ sudo mv /usr/lib/arm-linux-gnueabihf/libGLESv2.so.2.0.0 /usr/lib/arm-linux-gnueabihf/libGLESv2.so.2.0.0_backup
$ sudo ln -s /opt/vc/lib/libEGL.so /usr/lib/arm-linux-gnueabihf/libEGL.so.1.0.0
$ sudo ln -s /opt/vc/lib/libGLESv2.so /usr/lib/arm-linux-gnueabihf/libGLESv2.so.2.0.0
$ sudo ln -s /opt/vc/lib/libbrcmEGL.so /opt/vc/lib/libEGL.so
$ sudo ln -s /opt/vc/lib/libbrcmGLESv2.so.2 /opt/vc/lib/libGLESv2.so
$ sudo ln -s /opt/vc/lib/libEGL.so /opt/vc/lib/libEGL.so.1
$ sudo ln -s /opt/vc/lib/libGLESv2.so /opt/vc/lib/libGLESv2.so.2
  • Sur le PC :

Dans Qt Creator :

Qt Creator permet de créer, déployer, exécuter et déboguer des applications Qt directement sur la Raspberry Pi en un seul clic.

Menu Options → Appareils mobiles → Périphériques : Ajouter Périphérique Linux générique

Menu Options → Compiler & Executer puis Compilateurs : Ajouter GCC C++

Chemin : ~/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++ ou /usr/local/rpi3/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-g++

Menu Options → Compiler & Executer puis Debuggers : Ajouter

Chemin : ~/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-gdb ou /usr/local/rpi3/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gdb

Menu Options → Compiler & Executer puis Qt Versions : Ajouter

Emplacement de qmake : /usr/local/rpi3/qt5/bin/qmake

Menu Options → Compiler & Executer puis Kits : Ajouter

Sysroot : ~/raspi/sysroot ou /usr/local/rpi3/raspi/sysroot