Configurer un appareil Linux embarqué
La compilation croisée de Qt pour un appareil donné nécessite une chaîne d'outils et un sysroot. La chaîne d'outils doit contenir une version de gcc, ou d'un autre compilateur, ainsi que les outils associés conçus pour la compilation croisée. Cela signifie que ces outils s’exécutent sur le système hôte (généralement x64), tout en produisant des binaires pour l’architecture cible (par exemple, ARM 32 ou 64 bits). Le sysroot contient les en-têtes et les bibliothèques pour le système cible, ce qui permet de compiler et de lier des bibliothèques et des applications sur l’hôte.
Cette page de présentation décrit l’approche générique, dans laquelle aucun système de construction de distribution, tel que Yocto ou Buildroot, n’est utilisé. Il est toujours possible de compiler de manière croisée et de déployer Qt sur un appareil, à condition qu’une chaîne d’outils et un sysroot adaptés soient disponibles.
Avertissement : cette page ne fournit qu’une vue d’ensemble générique et de haut niveau. De nombreux détails peuvent varier en fonction de l’environnement de compilation, du périphérique cible et de la chaîne d’outils. En cas de doute, consultez votre intégrateur système. Pour les images de référence précompilées et les SDK, consultez l’ Boot to Qt offre.
Lors de l’exécution d’applications basées sur Qt sans système de fenêtrage, tel que X11 ou Wayland, certains appareils nécessitent un code d’adaptation spécifique au fabricant pour la prise en charge d’EGL et d’OpenGL ES. Celui-ci est fourni sous la forme de backends pour le plugin de plateforme EGLFS. Cela ne concerne pas les plateformes non accélérées, telles que celles qui utilisent le plugin de plateforme LinuxFB, destiné exclusivement au rendu logiciel. À partir de Qt 6, de nombreux systèmes embarqués utilisent drm pour définir un mode vidéo, gérer les connecteurs d’affichage et les surfaces graphiques. Par exemple, un appareil NXP basé sur i.MX8 ou un Raspberry Pi 4 utilisera cette approche ; par conséquent, le backend le plus couramment utilisé pour EGLFS est eglfs_kms, qui permet un rendu basé sur EGL et OpenGL ES avec drm, en utilisant gbm pour la gestion des surfaces et des tampons. Les appareils plus anciens, tels que l’ NXP u l’i.MX6, continueront d’utiliser l’approche héritée, spécifique au fournisseur de GPU, pour connecter les surfaces de fenêtre EGL au framebuffer, à l’aide de backends eglfs dédiés, tels que eglfs_viv.
Remarque : sachez que Qt n’est qu’un composant parmi d’autres de la pile logicielle d’un appareil embarqué. En particulier lorsque l’accélération graphique est impliquée, Qt s’attend à une pile graphique fonctionnelle, avec une configuration appropriée pour les composants de l’espace utilisateur et du noyau, tels que le pilote d’affichage. Ces composants ne relèvent pas du domaine de compétence de Qt, et il incombe à l’intégrateur système de s’assurer que le système de base est pleinement fonctionnel et optimisé, y compris en matière de graphisme accéléré.
Pour plus d’informations sur la configuration graphique et d’entrée des systèmes Linux embarqués, consultez Qt pour Linux embarqué.
Fichiers de la chaîne d’outils et spécifications des périphériques
Dans Qt 5, vous utilisiez généralement une spécification de périphérique située dans le répertoire `qtbase/mkspecs/devices`. Celles-ci contiennent les options de compilation et de liaison appropriées pour un périphérique donné, tout en garantissant que les bibliothèques EGL et OpenGL ES correctes sont sélectionnées, au cas où elles se trouveraient à un emplacement non standard dans le `sysroot`.
Par exemple, vous auriez pu configurer une compilation Qt 5 pour un Raspberry Pi 2 à l’aide d’une commande `configure` similaire à celle-ci :
./configure -release -opengl es2 -device linux-rasp-pi2-g++ -device-option CROSS_COMPILE=$TOOLCHAIN/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf- -sysroot $ROOTFS -prefix /usr/local/qt5Remarque : la commande `configure` utilise toujours le générateur et l’outil de compilation Ninja si un exécutable ` ninja ` est disponible. Ninja est multiplateforme, riche en fonctionnalités, performant et recommandé sur toutes les plateformes. L’utilisation d’autres générateurs peut fonctionner, mais n’est pas officiellement prise en charge.
Avec Qt 6 et CMake, cette approche ne suffit plus à elle seule. Il faut désormais fournir un fichier de chaîne d’outils CMake avant de pouvoir lancer la commande `configure`. C’est dans ce fichier que s’effectuent les personnalisations concernant les options du compilateur et de l’éditeur de liens, ainsi que les particularités spécifiques à la chaîne d’outils et au répertoire `sysroot`.
Dans les sections ci-dessous, nous présenterons un fichier de chaîne d’outils pouvant être utilisé dans de nombreux cas, avec un minimum de personnalisation. Il s’appuie sur l’approche présentée dans cet article de blog.
Remarque : le fichier de chaîne d’outils présenté ci-dessous est un exemple qui nécessitera souvent une personnalisation supplémentaire pour un appareil donné. Les utilisateurs et les intégrateurs système sont également libres de créer leurs propres fichiers de chaîne d’outils comme bon leur semble.
Bien que CMake soit le seul système de construction pris en charge pour la compilation de Qt lui-même, les applications peuvent toujours être compilées à l’aide de ` qmake ` dans Qt 6.0. Afin d’obtenir une configuration ` qmake ` fonctionnelle pour la compilation croisée, il faudra spécifier certains arguments hérités à CMake ou à `configure`.
Outils de l'hôte
La compilation croisée de Qt nécessite la disponibilité d’une version hôte de Qt. Voir Compilation croisée de Qt pour plus de détails.
Configuration de Qt
Supposons que les éléments suivants soient disponibles :
- une chaîne d'outils et un sysroot sous
$HOME/rpi-sdk, - une copie de Qt, comprenant au minimum le module qtbase, sous
$HOME/qt-cross, - une version de Qt compilée sur l'hôte dans
$HOME/qt-host.
De plus, il faut déterminer les éléments suivants avant la configuration :
- Où la version de Qt sera-t-elle installée sur le système local une fois la compilation terminée ? Dans cet exemple, nous utiliserons
$HOME/qt6-rpi. - Où la version de Qt sera-t-elle déployée sur le périphérique ? Dans l’exemple, nous utiliserons
/usr/local/qt6.
Dans cet exemple, nous allons utiliser un SDK Raspberry Pi 4 (chaîne d’outils + sysroot) généré via Yocto, mais les instructions fournies ici sont entièrement génériques et ne dépendent pas de Yocto. Les étapes sont les mêmes avec n’importe quelle autre chaîne d’outils et n’importe quel autre sysroot, une fois que le fichier de la chaîne d’outils a été mis à jour avec le compilateur croisé approprié et les autres chemins d’accès.
Après avoir créé le répertoire build et s’y être déplacé :
$HOME/qt-cross/qtbase/configure -release -opengl es2 -nomake examples -nomake tests \
-qt-host-path $HOME/qt-host \
-extprefix $HOME/qt6-rpi \
-prefix /usr/local/qt6 \
-- -DCMAKE_TOOLCHAIN_FILE=$HOME/qt-cross/toolchain.cmakeEn pratique, cette commande `configure` équivaut à l’appel CMake direct suivant :
cmake -GNinja -DCMAKE_BUILD_TYPE=Release -DINPUT_opengl=es2 -DQT_BUILD_EXAMPLES=OFF -DQT_BUILD_TESTS=OFF \
-DQT_HOST_PATH=$HOME/qt-host \
-DCMAKE_STAGING_PREFIX=$HOME/qt6-rpi \
-DCMAKE_INSTALL_PREFIX=/usr/local/qt6 \
-DCMAKE_TOOLCHAIN_FILE=$HOME/qt-cross/toolchain.cmake \
$HOME/qt-cross/qtbaseAvec le fichier de chaîne d’outils approprié, cela suffit pour générer une version de Qt qui permet ensuite de compiler des applications à l’aide de CMake. Pour permettre également la compilation d’applications avec qmake, il faut spécifier la spécification de périphérique et les options de périphérique au format Qt 5, en plus de tous les arguments indiqués ci-dessus :
$HOME/qt-cross/qtbase/configure ...
...
-device linux-rasp-pi4-v3d-g++ \
-device-option CROSS_COMPILE=$HOME/rpi_sdk/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi- \
-device-option DISTRO_OPTS="hard-float" \
...Par défaut, lors d’une compilation croisée, seules les bibliothèques et les outils Qt censés s’exécuter sur le périphérique cible sont compilés. Les outils liés à la compilation, tels que moc et uic, ne sont pas compilés. La compilation de ces outils peut être activée en définissant QT_FORCE_BUILD_TOOLS sur ON.
Remarque : lorsque QT_FORCE_BUILD_TOOLS est activé, les binaires cibles d’outils tels que qmake seront installés dans l’emplacement de transit. Par conséquent, si qmake est utilisé pour compiler des applications, exécutez plutôt le script host-qmake.
Une fois la configuration terminée sans erreur, exécutez cmake --build . --parallel pour lancer la compilation. Une fois la compilation terminée, exécutez cmake --install . pour installer les résultats dans $HOME/qt6-rpi. À partir de là, la compilation Qt peut être déployée sur l’appareil à l’aide de rsync, scp ou d’une autre méthode.
Si vous compilez des modules Qt individuels, vous pouvez utiliser le script ` qt-configure-module ` situé dans le répertoire ` bin ` de l’emplacement de transit ($HOME/qt6-rpi dans l’exemple) pour configurer des modules supplémentaires, tels que `qtdeclarative`, `qtquick3d`, etc. Ceux-ci peuvent ensuite être compilés à l’aide de ` cmake --build . ` et installés dans l’emplacement de transit en exécutant cmake --install .
Remarque : avant de lancer la compilation, vérifiez toujours attentivement le résultat de l’étape de configuration : toutes les fonctionnalités attendues sont-elles activées ? Il est inutile de compiler et de déployer sur l’appareil si des fonctionnalités essentielles ne sont pas activées lors de la configuration.
Par exemple, si vous souhaitez bénéficier d’un rendu graphique accéléré via OpenGL, portez une attention particulière aux fonctionnalités suivantes :
EGL .................................... yes
OpenGL:
Desktop OpenGL ....................... no
OpenGL ES 2.0 ........................ yes
OpenGL ES 3.0 ........................ yes
...
evdev .................................. yes
libinput ............................... yes
...
EGLFS .................................. yes
EGLFS details:
EGLFS OpenWFD ........................ no
EGLFS i.Mx6 .......................... no
EGLFS i.Mx6 Wayland .................. no
EGLFS RCAR ........................... no
EGLFS EGLDevice ...................... yes
EGLFS GBM ............................ yes
EGLFS VSP2 ........................... no
EGLFS Mali ........................... no
EGLFS Raspberry Pi ................... no
EGLFS X11 ............................ no
LinuxFB ................................ yesDans l’exemple du Raspberry Pi 4, nous nous attendons à ce qu’EGL, OpenGL ES et EGLFS GBM soient tous signalés comme yes; sinon, le plugin de plateforme EGLFS et son backend eglfs_kms ne fonctionneront pas sur l’appareil. Pour disposer d’une souris, d’un clavier et d’une entrée tactile fonctionnels, il faut activer soit evdev, soit libinput.
De même, s’il est prévu d’utiliser X11 comme système de fenêtrage (ou l’un des systèmes de fenêtrage) sur l’appareil, assurez-vous que les fonctionnalités liées à xcb et à X11 sont marquées comme yes.
Exemple de fichier de chaîne d’outils
Nous partons du principe qu’un sysroot et une chaîne d’outils sont disponibles sous $HOME/rpi-sdk. Les fichiers TARGET_SYSROOT et CROSS_COMPILER doivent être adaptés à la chaîne d’outils et au sysroot utilisés. L’exemple présenté ici ne convient qu’à un SDK spécifique généré par Yocto. Il en va de même pour les fichiers CMAKE_C_COMPILER et CMAKE_CXX_COMPILER.
Nous ne nous appuyons sur aucun script de wrapper qui fournirait des variables d’environnement telles que PKG_CONFIG_*. Au lieu de cela, le chemin d’accès aux fichiers .pc est spécifié dans le fichier de chaîne d’outils. Il est probable qu’un autre sysroot nécessite des ajustements dans PKG_CONFIG_LIBDIR. Par exemple, avec un sysroot généré à partir d’une image Raspberry Pi OS (anciennement Raspbian), il faudrait plutôt utiliser /usr/lib/arm-gnueabihf/pkgconfig.
Les options du compilateur et de l’éditeur de liens ne sont pas nécessairement optimales dans cet exemple. Adaptez-les si nécessaire en fonction du périphérique cible.
Pour plus d’informations sur les spécificités de CMake dans le fichier de chaîne d’outils d’exemple, consultez cet article de blog et la documentation CMake.
cmake_minimum_required(VERSION 3.18)
include_guard(GLOBAL)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(TARGET_SYSROOT /home/user/rpi-sdk/sysroots/cortexa7t2hf-neon-vfpv4-poky-linux-gnueabi)
set(CROSS_COMPILER /home/user/rpi-sdk/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi)
set(CMAKE_SYSROOT ${TARGET_SYSROOT})
set(ENV{PKG_CONFIG_PATH} "")
set(ENV{PKG_CONFIG_LIBDIR} ${CMAKE_SYSROOT}/usr/lib/pkgconfig:${CMAKE_SYSROOT}/usr/share/pkgconfig)
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})
set(CMAKE_C_COMPILER ${CROSS_COMPILER}/arm-poky-linux-gnueabi-gcc)
set(CMAKE_CXX_COMPILER ${CROSS_COMPILER}/arm-poky-linux-gnueabi-g++)
set(QT_COMPILER_FLAGS "-march=armv7-a -mfpu=neon -mfloat-abi=hard")
set(QT_COMPILER_FLAGS_RELEASE "-O2 -pipe")
set(QT_LINKER_FLAGS "-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
include(CMakeInitializeConfigs)
function(cmake_initialize_per_config_variable _PREFIX _DOCSTRING)
if (_PREFIX MATCHES "CMAKE_(C|CXX|ASM)_FLAGS")
set(CMAKE_${CMAKE_MATCH_1}_FLAGS_INIT "${QT_COMPILER_FLAGS}")
foreach (config DEBUG RELEASE MINSIZEREL RELWITHDEBINFO)
if (DEFINED QT_COMPILER_FLAGS_${config})
set(CMAKE_${CMAKE_MATCH_1}_FLAGS_${config}_INIT "${QT_COMPILER_FLAGS_${config}}")
endif()
endforeach()
endif()
if (_PREFIX MATCHES "CMAKE_(SHARED|MODULE|EXE)_LINKER_FLAGS")
foreach (config SHARED MODULE EXE)
set(CMAKE_${config}_LINKER_FLAGS_INIT "${QT_LINKER_FLAGS}")
endforeach()
endif()
_cmake_initialize_per_config_variable(${ARGV})
endfunction()Compilation d’applications pour le périphérique cible
Une fois la compilation de Qt terminée et l’installation effectuée dans l’emplacement de préparation, vous pouvez compiler des exemples ou des applications.
Avec CMake, utilisez le script généré ` qt-cmake ` situé dans le répertoire ` bin ` de l’emplacement de transit ($HOME/qt6-rpi dans l’exemple) pour configurer, puis exécutez ` ninja`. Par exemple :
$HOME/qt6-rpi/bin/qt-cmake .
cmake --build .Le binaire de l’application ainsi obtenu peut ensuite être déployé sur l’appareil. L’utilisation du script d’aide qt-cmake est pratique, car il garantit que le fichier de chaîne d’outils utilisé pour la compilation de Qt est chargé ; il n’est donc pas nécessaire de le spécifier à chaque fois pour chaque application.
Contrairement à Qt lui-même, la compilation d’applications avec qmake est toujours prise en charge dans Qt 6.0, à condition qu’une spécification de périphérique adaptée soit disponible et que les arguments hérités appropriés aient été transmis à CMake ou à configure lors de la configuration de Qt. Si toutes ces conditions sont remplies, l’exécution de qmake et de make générera également un binaire d’application pour le périphérique cible.
Paramètres par défaut pour les plugins de plateforme et EGLFS
Une fois la configuration effectuée, un plugin de plateforme par défaut est sélectionné. Celui-ci est utilisé lors du lancement d’une application sans l’argument ` -platform ` et sans que la variable d’environnement ` QT_QPA_PLATFORM ` soit définie.
De même, le plugin de plateforme EGLFS dispose de plusieurs backends. La valeur par défaut est choisie en fonction de la disponibilité et d’un ordre de priorité prédéfini. Si drm et gbm sont disponibles, la valeur par défaut sera le backend eglfs_kms. Il est toujours possible de passer outre cette valeur par défaut lors de l’exécution en définissant la variable d’environnement QT_QPA_EGLFS_INTEGRATION.
Pour modifier ces valeurs par défaut lors de la compilation, sans avoir à imposer une valeur spécifique au moment de l’exécution, les deux variables de cache CMake suivantes sont disponibles une fois que CMake a été exécuté une première fois :
QT_QPA_DEFAULT_PLATFORM(STRING) - Nom du plugin de plateforme par défaut.QT_QPA_DEFAULT_EGLFS_INTEGRATION(STRING) - Le backend EGLFS par défaut.
Ces variables peuvent également être définies dans le fichier de la chaîne d'outils.
Pour plus d’informations sur la configuration de Qt, consultez la section « Options de configuration de Qt ».
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.