Auf dieser Seite

Ein Embedded-Linux-Gerät konfigurieren

Die Cross-Kompilierung von Qt für ein bestimmtes Gerät erfordert eine Toolchain und ein Sysroot. Die Toolchain sollte eine Version von gcc oder einem anderen Compiler sowie zugehörige Tools enthalten, die für die Cross-Kompilierung erstellt wurden. Das bedeutet, dass diese Werkzeuge auf dem Host-System (typischerweise x64) ausgeführt werden, während sie Binärdateien für die Zielarchitektur (z. B. 32- oder 64-Bit-ARM) erzeugen. Das Sysroot enthält die Header und Bibliotheken für das Zielsystem und ermöglicht so das Kompilieren und Verknüpfen von Bibliotheken und Anwendungen auf dem Host.

Diese Übersichtsseite beschreibt den generischen Ansatz, bei dem keine Distributions-Build-Systeme wie Yocto oder Buildroot verwendet werden. Es ist jederzeit möglich, Qt cross-zu-kompilieren und auf einem Gerät bereitzustellen, solange eine geeignete Toolchain und ein geeignetes Sysroot verfügbar sind.

Warnung: Diese Seite kann nur einen allgemeinen, übergreifenden Überblick bieten. Es gibt eine Vielzahl von Details, die je nach Build-Umgebung, Zielgerät und Toolchain variieren können. Wenden Sie sich im Zweifelsfall an Ihren Systemintegrator. Vorgefertigte Referenz-Images und SDKs finden Sie im Boot to Qt Angebot.

Bei der Ausführung von Qt-basierten Anwendungen ohne ein Fenstersystem wie X11 oder Wayland erfordern einige Geräte herstellerspezifischen Anpassungscode für die Unterstützung von EGL und OpenGL ES. Dieser wird in Form von Backends für das EGLFS-Plattform-Plugin bereitgestellt. Dies ist für nicht beschleunigte Plattformen nicht relevant, wie beispielsweise solche, die das LinuxFB-Plattform-Plugin verwenden, das ausschließlich für softwarebasiertes Rendering vorgesehen ist. Seit Qt 6 nutzen viele eingebettete Systeme DRM, um einen Videomodus festzulegen, Displayanschlüsse zu verwalten und grafische Oberflächen zu steuern. Beispielsweise nutzen ein i.MX8-basiertes Gerät von NXP oder ein Raspberry Pi 4 diesen Ansatz; daher ist das am häufigsten verwendete Backend für EGLFS „eglfs_kms“, das EGL- und OpenGL ES-basiertes Rendering mit drm ermöglicht und dabei gbm für die Verwaltung von Oberflächen und Puffern nutzt. Ältere Geräte, wie beispielsweise das „ NXP “ i.MX6, werden weiterhin den veralteten, GPU-herstellerspezifischen Ansatz zur Verbindung von EGL-Fensteroberflächen mit dem Framebuffer verwenden, wobei dedizierte EGLFS-Backends wie eglfs_viv zum Einsatz kommen.

Hinweis: Beachten Sie , dass Qt nur eine Komponente im Software-Stack eines eingebetteten Geräts ist. Insbesondere bei beschleunigter Grafik erwartet Qt einen funktionsfähigen Grafik-Stack mit einer geeigneten Konfiguration der Userspace- und Kernel-Komponenten, wie beispielsweise des Grafiktreibers. Diese Komponenten liegen außerhalb des Zuständigkeitsbereichs von Qt, und es liegt in der Verantwortung des Systemintegrators, sicherzustellen, dass das Basissystem voll funktionsfähig und optimal eingerichtet ist, einschließlich der Grafikbeschleunigung.

Weitere Informationen zur Grafik- und Eingabekonfiguration für Embedded-Linux-Systeme finden Sie unter „Qt for Embedded Linux“.

Toolchain-Dateien im Vergleich zu Geräte-Makespecs

In Qt 5 würden Sie normalerweise eine Gerätespezifikation aus dem Verzeichnis ` qtbase/mkspecs/devices ` verwenden. Diese enthalten die entsprechenden Compiler- und Linker-Flags für ein bestimmtes Gerät und stellen zudem sicher, dass die richtigen EGL- und OpenGL ES-Bibliotheken herangezogen werden, falls sich diese an einem nicht standardmäßigen Speicherort im Sysroot befinden.

Beispielsweise könnten Sie einen Qt-5-Build für einen Raspberry Pi 2 mit einem „configure“-Befehl wie dem folgenden konfiguriert haben:

./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/qt5

Hinweis: „configure“ verwendet immer den Ninja-Generator und das Ninja-Build-Tool, sofern eine ausführbare Datei „ ninja “ verfügbar ist. Ninja ist plattformübergreifend, funktionsreich, leistungsstark und wird auf allen Plattformen empfohlen. Die Verwendung anderer Generatoren funktioniert möglicherweise, wird jedoch nicht offiziell unterstützt.

Mit Qt 6 und CMake reicht dieser Ansatz allein nicht mehr aus. Vielmehr muss vor der Konfiguration eine CMake-Toolchain-Datei bereitgestellt werden. In dieser Datei erfolgen Anpassungen hinsichtlich Compiler- und Linker-Flags sowie Toolchain- und sysroot-spezifischer Besonderheiten.

In den folgenden Abschnitten stellen wir eine Toolchain-Datei vor, die in vielen Fällen mit minimalen Anpassungen verwendet werden kann. Sie basiert auf dem in diesem Blogbeitrag vorgestellten Ansatz.

Hinweis: Die unten vorgestellte Toolchain-Datei ist ein Beispiel, das für ein bestimmtes Gerät oft weiter angepasst werden muss. Anwendern und Systemintegratoren steht es zudem frei, eigene Toolchain-Dateien nach eigenem Ermessen zu erstellen.

Während CMake das einzige unterstützte Build-System für die Erstellung von Qt selbst ist, können Anwendungen in Qt 6.0 weiterhin mit „ qmake “ erstellt werden. Um eine „ qmake “-Konfiguration zu erhalten, die für die Cross-Kompilierung funktionsfähig ist, müssen einige der älteren Argumente für CMake oder „configure“ angegeben werden.

Host-Tools

Für die Cross-Kompilierung von Qt muss eine Host-Version von Qt verfügbar sein. Weitere Informationen finden Sie unter „Cross-Kompilierung von Qt “.

Konfiguration von Qt

Nehmen wir an, Folgendes ist verfügbar:

  • eine Toolchain und ein Sysroot unter $HOME/rpi-sdk,
  • ein Checkout von Qt, mindestens das Modul „qtbase“, unter $HOME/qt-cross,
  • eine Host-Version von Qt XML unter $HOME/qt-host.

Darüber hinaus muss vor der Konfiguration Folgendes festgelegt werden:

  • Wo soll der Qt-Build nach Abschluss des Builds auf dem lokalen System installiert werden? In diesem Beispiel verwenden wir $HOME/qt6-rpi.
  • Wo soll der Qt-Build auf dem Gerät bereitgestellt werden? Im Beispiel verwenden wir /usr/local/qt6.

Im Beispiel verwenden wir ein über Yocto generiertes Raspberry Pi 4 SDK (Toolchain + Sysroot), aber die hier beschriebenen Anweisungen sind völlig generisch und nicht von Yocto abhängig. Die Schritte sind bei jeder anderen Toolchain und jedem anderen Sysroot identisch, sobald die Toolchain-Datei mit dem richtigen Cross-Compiler und den entsprechenden Pfaden aktualisiert wurde.

Nachdem Sie ein Verzeichnis „ build “ erstellt und in dieses gewechselt haben:

$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.cmake

In der Praxis entspricht dieser `configure`-Befehl dem folgenden direkten CMake-Aufruf:

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/qtbase

Bei Vorliegen der entsprechenden Toolchain-Datei reicht dies aus, um einen Qt-Build zu generieren, der dann die Erstellung von Anwendungen mit CMake ermöglicht. Damit Anwendungen auch mit ` qmake ` erstellt werden können, müssen zusätzlich zu allen oben gezeigten Argumenten die Gerätespezifikation und die Geräteoptionen im Qt-5-Stil angegeben werden:

$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" \
  ...

Standardmäßig werden beim Cross-Compiling nur die Qt-Bibliotheken und -Tools erstellt, die auf dem Zielgerät ausgeführt werden sollen. Build-bezogene Tools wie moc und uic werden nicht erstellt. Das Erstellen solcher Tools kann aktiviert werden, indem „ QT_FORCE_BUILD_TOOLS “ auf „ ON “ gesetzt wird.

Hinweis: Wenn „ QT_FORCE_BUILD_TOOLS “ aktiviert ist, werden Ziel-Binärdateien von Tools wie „ qmake “ im Staging-Verzeichnis installiert. Wenn Sie daher „ qmake “ zum Erstellen von Anwendungen verwenden, rufen Sie stattdessen das Skript „ host-qmake “ auf.

Sobald die Konfiguration fehlerfrei abgeschlossen ist, führen Sie „ cmake --build . --parallel “ aus, um den Build zu erstellen. Nach Abschluss des Builds führen Sie „ cmake --install . “ aus, um die Ergebnisse unter „ $HOME/qt6-rpi “ zu installieren. Von dort aus kann der Qt-Build mithilfe von rsync, scp oder einer anderen Methode auf das Gerät bereitgestellt werden.

Wenn einzelne Qt-Module erstellt werden, kann man das Skript „ qt-configure-module “ aus dem Verzeichnis „ bin “ des Staging-Speicherorts (im Beispiel$HOME/qt6-rpi ) verwenden, um zusätzliche Module wie qtdeclarative, qtquick3d usw. zu konfigurieren. Diese können dann mit „ cmake --build . “ erstellt und durch Ausführen von cmake --install .

Hinweis: Überprüfen Sievor Beginn des Builds stets sorgfältig die Ausgabe des Konfigurationsschritts: Sind alle erwarteten Funktionen aktiviert? Ein Build zu erstellen und auf dem Gerät bereitzustellen ist sinnlos, wenn wesentliche Funktionen bei der Konfiguration nicht aktiviert wurden.

Wenn beispielsweise eine Grafikbeschleunigung über OpenGL gewünscht ist, achten Sie besonders auf die folgenden Funktionen:

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 ................................ yes

Im Beispiel des Raspberry Pi 4 erwarten wir, dass EGL, OpenGL ES und „ EGLFS GBM “ alle als „ yes “ gemeldet werden; andernfalls sind das EGLFS-Plattform-Plugin und sein „eglfs_kms“-Backend auf dem Gerät nicht funktionsfähig. Um Maus-, Tastatur- und Touch-Eingaben nutzen zu können, muss entweder „ evdev “ oder „ libinput “ aktiviert sein.

Ebenso gilt: Wenn X11 als (eines der) Fenstersysteme auf dem Gerät verwendet werden soll, muss sichergestellt werden, dass die xcb- und X11-bezogenen Funktionen als „ yes “ gekennzeichnet sind.

Eine Beispiel-Toolchain-Datei

Wir gehen davon aus, dass unter $HOME/rpi-sdk ein Sysroot und eine Toolchain verfügbar sind. TARGET_SYSROOT und CROSS_COMPILER müssen an die verwendete Toolchain und den Sysroot angepasst werden. Das hier gezeigte Beispiel eignet sich nur für ein bestimmtes, von Yocto generiertes SDK. Gleiches gilt für CMAKE_C_COMPILER und CMAKE_CXX_COMPILER.

Wir verlassen uns nicht auf Wrapper-Skripte, die Umgebungsvariablen wie PKG_CONFIG_* bereitstellen würden. Stattdessen wird der Pfad zu den .pc-Dateien in der Toolchain-Datei angegeben. Es ist wahrscheinlich, dass bei einem anderen Sysroot Anpassungen in PKG_CONFIG_LIBDIR erforderlich sind. Bei einem Sysroot, der beispielsweise aus einem Raspberry-Pi-OS-Image (ehemals Raspbian) generiert wurde, würde man stattdessen /usr/lib/arm-gnueabihf/pkgconfig verwenden.

Die Compiler- und Linker-Flags sind im Beispiel möglicherweise nicht optimal. Passen Sie diese je nach Zielgerät entsprechend an.

Weitere Informationen zu den CMake-Spezifikationen in der Beispiel-Toolchain-Datei finden Sie in diesem Blogbeitrag und in der CMake-Dokumentation.

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()

Erstellen von Anwendungen für das Zielgerät

Sobald der Qt-Build abgeschlossen und im Staging-Verzeichnis installiert ist, können Beispiele oder Anwendungen erstellt werden.

Verwenden Sie bei CMake das generierte Skript „ qt-cmake “ im Verzeichnis „ bin “ des Staging-Verzeichnisses (im Beispiel „$HOME/qt6-rpi “), um die Konfiguration vorzunehmen, und führen Sie anschließend „ ninja “ aus. Beispiel:

$HOME/qt6-rpi/bin/qt-cmake .
cmake --build .

Die resultierende Anwendungsdatei kann anschließend auf dem Gerät bereitgestellt werden. Die Verwendung des Hilfsscripts „ qt-cmake “ ist praktisch, da das Script sicherstellt, dass die für den Bau von Qt verwendete Toolchain-Datei geladen wird, sodass diese nicht für jede Anwendung erneut angegeben werden muss.

Anders als bei Qt selbst wird das Erstellen von Anwendungen mit qmake in Qt 6.0 weiterhin unterstützt, sofern eine geeignete Gerätespezifikation verfügbar ist und bei der Konfiguration von Qt die entsprechenden Legacy-Argumente an CMake oder „configure“ übergeben wurden. Sind alle diese Voraussetzungen erfüllt, generieren die Befehle „ qmake “ und „ make “ ebenfalls eine Anwendungsbinärdatei für das Zielgerät.

Standardeinstellungen für Plattform-Plugins und EGLFS

Nach der Konfiguration wird ein Standard-Plattform-Plugin ausgewählt. Dieses wird verwendet, wenn eine Anwendung ohne das Argument „ -platform “ und ohne die Umgebungsvariable „ QT_QPA_PLATFORM “ gestartet wird.

Ebenso verfügt das EGLFS-Plattform-Plugin über mehrere Backends. Die Standardauswahl erfolgt basierend auf der Verfügbarkeit und einer vordefinierten Prioritätsreihenfolge. Sind drm und gbm verfügbar, ist das eglfs_kms-Backend der Standard. Dies kann jederzeit zur Laufzeit durch Setzen der Umgebungsvariable „ QT_QPA_EGLFS_INTEGRATION “ überschrieben werden.

Um diese Standardwerte für den Build zu ändern, ohne zur Laufzeit einen bestimmten Wert erzwingen zu müssen, stehen nach einmaliger Ausführung von CMake die folgenden zwei CMake-Cache-Variablen zur Verfügung:

  • QT_QPA_DEFAULT_PLATFORM (STRING) – Der Name des Standard-Plattform-Plugins.
  • QT_QPA_DEFAULT_EGLFS_INTEGRATION (STRING) – Das Standard-EGLFS-Backend.

Diese Variablen können auch in der Toolchain-Datei festgelegt werden.

Weitere Informationen zur Konfiguration von Qt finden Sie unter „Qt-Konfigurationsoptionen“.

© 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.