Cross-compilation Qt sur Raspberry Pi 3B+

Voici les différentes étapes permettant de configurer Qt 5.15.1 pour cross-compiler depuis un PC Ubuntu [Hôte] vers une Raspberry Pi 3B+ avec Raspbian Lite [Pi]. Nous verrons également comment configurer QtCreator afin de déployer directement les applications sur la Raspberry Pi.

Configurations testés :

  • Qt 5.13.1 / Ubuntu 18.04 LTS / Raspbian Buster Lite 2019.09.26
  • Qt 5.13.1 / Ubuntu 20.04 LTS / Raspbian Buster Lite 2020.02.13
  • Qt 5.13.1 /Ubuntu 20.04 LTS /Raspberry Pi OS Lite (Buster) 2020.08.20
  • Qt 5.15.1 /Ubuntu 20.04 LTS /Raspberry Pi OS Lite (Buster) 2020.08.20

  • [Pi] : Ces étapes sont à réaliser sur la Raspberry Pi
  • [Hôte] : Ces étapes sont à réaliser sur le PC hôte
  1. Préparation de la cible – [Pi]
  2. Préparation de l’hôte – [Hôte]
  3. Configuration du sysroot – [Hôte]
  4. Compilation de QtBase – [Hôte]
  5. Compilation et installation de QtBase – [Hôte]
  6. Compilation et installation de QtDeclarative – [Hôte]
  7. Compilation et installation de QtWebEngine – [Hôte]
  8. Synchronisation avec la Raspberry Pi – [Hôte]
  9. Test – [Hôte]

1.    Préparation de la cible – [Pi]

Après avoir copier l’image Raspbian Buster Lite sur la carte SD de la Raspberry Pi, assurer vous d’avoir activer le service SSH sur la Raspberry Pi.

Pour cette procédure, nous aurons besoin d’installer certaines librairies de développement. Il faut pour cela autoriser la Raspberry Pi à télécharger des paquets sources. Pour cela, il faut éditer le fichier /etc/apt/sources.list et décommenter la ligne deb-src…

sudo nano /etc/apt/sources.list

Nous pouvons ensuite installer les paquets nécessaires.

sudo apt-get update
sudo apt-get build-dep qt4-x11
sudo apt-get build-dep libqt5gui5
sudo apt-get install libudev-dev libinput-dev libts-dev libxcb-xinerama0-dev libxcb-xinerama0 libnss3-dev

Il ne reste plus qu’à ajouter un dossier dans lequel sera déployé Qt.

sudo mkdir /usr/local/qt5pi
sudo chown pi:pi /usr/local/qt5pi

2.    Préparation de l’hôte – [Hôte]

Nous commençons par créer un dossier dans lequel travailler.

mkdir ~/raspi cd ~/raspi

Il faut ensuite télécharger une chaîne de compilation. Mon objectif étant de pouvoir compiler QWebEngine sur la Raspberry Pi, j’utilise une toolchain en version 7.4 (QWebEngine nécessite une version de GCC supérieure à 5).

wget https://releases.linaro.org/components/toolchain/binaries/7.4-2019.02/arm-linux-gnueabihf/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf.tar.xz
tar xvf gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf.tar.xz

Pour compiler QWebEngine sur la Raspberry qui à une architecture 32 bits avec un PC en 64 bits, il est nécessaire d’avoir certaines librairies supplémentaires

sudo apt install g++-multilib qt5-default gperf bison flex libnss3-dev

Pour les besoins de mon projet j’ai également installé les paquets suivants :

sudo apt install libavcodec-dev libavformat-dev libavutil-dev

3. Configuration du sysroot – [Hôte]

Le dossier sysroot est une copie sur le PC hôte des dossiers de la Raspberry Pi nécessaires à la compilation.

mkdir sysroot sysroot/usr sysroot/opt

La commande rsync permet de synchroniser facilement les dossiers de la Raspberry Pi avec notre dossier sysroot (Remplacer raspberry_pi par l’adresse ip de votre Raspberry Pi).

rsync -avz pi@raspberrypi_ip:/lib sysroot
rsync -avz pi@raspberrypi_ip:/usr/include sysroot/usr
rsync -avz pi@raspberrypi_ip:/usr/lib sysroot/usr
rsync -avz pi@raspberrypi_ip:/opt/vc sysroot/opt

Il ne reste plus qu’à mettre à jour les liens symboliques du dossier sysroot en utilisant le script suivant :

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

4. Compilation de QtBase – [Hôte]

Nous commençons par télécharger QtBase dans sa version 5.15.1

mkdir ~/raspi/qt_source ~/raspi/qt_source/qt_5.15.1
cd ~/raspi/qt_source/qt_5.15.1
git clone https://code.qt.io/qt/qtbase.git -b 5.15.1
cd qtbase/

Avant de lancer la compilation, il faut passer par une étape de configuration. Certains paramètres sont assez clairs, d’autres sont plus flous et proviennent des différentes sources que j’ai utilisé.

./configure -release -opengl es2 -device linux-rasp-pi3-vc4-g++ -device-option CROSS_COMPILE=~/raspi/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf- -opensource -confirm-license -nomake tests -nomake examples -make libs -verbose -no-pch -eglfs -no-xcb -no-use-gold-linker -sysroot ~/raspi/sysroot -prefix /usr/local/qt5pi -extprefix ~/raspi/qt5pi -hostprefix ~/raspi/qt5 -no-gbm -libinput -libudev
  • -release : on ne compile pas la version debug pour gagner du temps
  • -opengl es2 : Active OpenGL
  • -device linux-rasp-pi3-vc4-g++ : cible raspberry pi 3B+ avec pilote vc4
  • -device-option CROSS_COMPILE=~/raspi/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf- : on utilise le compilateur gcc linaro version 7.4 pour pouvoir compiler QWebEngine qui demande une version de gcc supérieure à 5
  • -opensource -confirm-license : on utilise la version libre et on accepte la license
  • -nomake examples -nomake tests : ne compile pas les tests et examples pour gagner du temps
  • -make …  : Ajoute certaines parties à compiler (libs, tools, examples, demos).
  • -verbose : mode verbeux
  • -no-pch : N’utilise pas des headers pré-compilés
  • -eglfs : permet de créer des applis en mode plein écran (embarqué)
  • -no-xcb : desactive l’utilisation du serveur X (-xcb pour pouvoir l’utiliser)
  • -no-use-gold-linker : nécessaire pour version Qt supérieur à 5.6
  • -sysroot ~/raspi/sysroot : dossier sysroot synchronisé avec la Raspberry Pi
  • -prefix /usr/local/qt5pi : dossier où sera installé Qt sur la Raspberry Pi
  • -extprefix ~/raspi/qt5pi : dossier où sera installé Qt et qui sera synchronisé avec la Raspberry Pi.
  • -hostprefix ~/raspi/qt5 : dossier où seront installés les outils pour l’hôte (ex : qmake)
  • -no-gbm : n’utilise pas GBM
  • -libinput : librairie nécessaire pour mon projet
  • -libudev : librairie nécessaire pour mon projet

5. Compilation et installation de QtBase – [Hôte]

Une fois configuré, vous pouvez lancer la compilation avec la commande make. Pour accélérer le temps de compilation il est possible d’utiliser le flag -jn (avec n le nombre de process parallèles autorisés). Lorsque la compilation est terminée, il faut installer QtBase avec la commande make install.

make -j4
sudo make install

6. Compilation et installation de QtDeclarative – [Hôte]

Pour pouvoir utiliser QtWebEngine, il est nécessaire d’avoir préalablement installé QtDeclarative. La commande qmake créée lors de la compilation de QtBase va permettre de générer les Makefiles nécessaire à la compilation du module. La procédure est identique si vous voulez compiler un autre module nécessaire à votre projet (QtScript, QtGamepad…).

On commence par télécharger les sources du module en question :

cd ~/raspi/qt_source/qt_5.15.1
git clone https://code.qt.io/qt/qtdeclarative.git -b 5.15.1
cd qtdeclarative

Qmake génére automatiquement tous les makefiles nécessaires:

~/raspi/qt5/bin/qmake

Il ne reste plus qu’à compiler et installer le module.

make -j4
sudo make install

6.1 Autres modules

En fonction des projets, il est nécessaires de compiler d’autres modules de Qt. Par exemple dans mon cas j’ai également compilé les modules QtQuickControls et QtQuickControls2. Pour ce faire, il suffit de répéter les étapes précédentes en modifiant uniquement le nom du modules dans les commandes.

7. Compilation et installation de QtWebEngine – [Hôte]

Le module QtWebEngine est un petit peu différent à récupérer car il est géré comme sous-module.

cd ~/raspi/qt_source/qt_5.15.1
git clone https://code.qt.io/qt/qtwebengine.git
cd qtwebengine/
git submodule init
git checkout 5.15.1
git submodule update

On génère ensuite les makefiles avec le qmake de QtBase. L’option -webengine-proprietary-codecs est nécessaires pour mon projet pour afficher certains formats vidéos dans Qtwebengine. Pour la version Qt 5.13.1, j’ai du ajouter l’option –no-feature-webengine-arm-thumb.

~/raspi/qt5/bin/qmake -- -webengine-proprietary-codecs

On lance ensuite la compilation.

make -j4

Pendant la compilation il est possible d’avoir une erreur du type :

g++: internal compiler error: Killed (program cc1plus) Please submit a full bug report, with preprocessed source if appropriate.

Le plus souvent il s’agit d’un problème de mémoire. QtWebEngine est lourd à compiler et demande beaucoup de ressources. Pour valider qu’il s’agit bien d’un manque de mémoire, il est possible de saisir la commande dmesg et voir apparaître un message du type :

Out of memory: Kill process 1568 (cc1plus)

Plusieurs options sont alors possible :

  • relancer make autant de fois que nécessaire mais çà peut être trèèès long.
  • Réduire le nombre de tâches en parallèles en diminuant ou supprimant le flag -j
  • Si vous travailler sur une machine virtuelle (ce qui est mon cas) augmenter les ressources allouées à la VM.
  • Augmenter la taille du fichier de swap.

Pour ma part, il a fallu appliquer les 4 à la fois (je suis passé à 6Go de RAM et un fichier de swap de 9Go). Il m’a fallu en tout plus de 6h pour compiler le module.

A nouveau une fois le module compiler, on l’installe avec :

sudo make install

8. Synchronisation avec la Raspberry Pi [Hôte]

Une fois que tout est compilé, la commande rsync permet de synchroniser les dossiers afin de déployer Qt sur la Raspberry Pi.

cd ~/raspi
rsync -avz qt5pi pi@raspberrypi_ip:/usr/local

9. Compiler un exemple [Hôte]

Pour tester si le module QtWebEngine a bien été compilé, nous allons faire un test avec l’exemple simpleBrowser disponible dans les sources de QtWebEngine.

cd ~/raspi/qt_source/qt_5.15.1/qtwebengine/examples/webenginewidgets/simplebrowser
~/raspi/qt5/bin/qmake
make - j4

Une fois compilé, nous pouvons déployer le programme sur la raspberry.

scp simpleBrowser pi@raspberrypi_ip:~

10. Tester le programme [Pi]

Avant d’éxécuter notre programme test, il faut indiquer à la raspberry l’emplacement des librairies que nous venons de compiler :

export LD_LIBRARY_PATH=/usr/local/qt5pi/lib
sudo ldconfig

Pour tester notre programme il suffit d’exécuter les commandes suivantes :

cd ~
./simpleBrowser

Sources :

Retour en haut

Votre commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l’aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google

Vous commentez à l’aide de votre compte Google. Déconnexion /  Changer )

Image Twitter

Vous commentez à l’aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l’aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s