Configurar un dispositivo Linux embebido
La compilación cruzada de Qt para un dispositivo dado requiere un toolchain y un sysroot. Se espera que la cadena de herramientas contenga una versión de gcc, u otro compilador, y herramientas asociadas construidas para la compilación cruzada. Esto significa que estas herramientas se ejecutan en el sistema anfitrión (normalmente x64), al tiempo que producen binarios para la arquitectura de destino (por ejemplo, ARM de 32 o 64 bits). El sysroot contiene las cabeceras y bibliotecas para el sistema de destino, lo que permite compilar y enlazar bibliotecas y aplicaciones en el host.
Esta página describe el enfoque genérico, en el que no se utilizan sistemas de construcción de distribuciones, como Yocto o Buildroot. Siempre es posible la compilación cruzada y el despliegue de Qt en un dispositivo, siempre que se disponga de una cadena de herramientas y un sysroot adecuados.
Advertencia: Esta página sólo puede proporcionar una visión genérica de alto nivel. Hay un gran número de detalles que pueden variar dependiendo del entorno de compilación, el dispositivo de destino y la cadena de herramientas. En caso de duda, consulte a su integrador de sistemas. Para imágenes de referencia y SDK preconstruidos, consulte la oferta de Boot to Qt oferta.
Cuando se ejecutan aplicaciones basadas en Qt sin un sistema de ventanas, como X11 o Wayland, algunos dispositivos requieren código de adaptación específico del fabricante para la compatibilidad con EGL y OpenGL ES. Esto se proporciona en forma de backends para el plugin de plataforma EGLFS. Esto no es relevante para plataformas no aceleradas, como las que utilizan el plugin de plataforma LinuxFB, que está pensado sólo para renderizado basado en software. A partir de Qt 6, muchos sistemas embebidos utilizan drm para establecer un modo de vídeo, gestionar conectores de pantalla y superficies gráficas. Por ejemplo, un dispositivo basado en NXP i.MX8 o una Raspberry Pi 4 utilizarán este enfoque, y por lo tanto el backend más utilizado para EGLFS es eglfs_kms, que permite el renderizado basado en EGL y OpenGL ES con drm, utilizando gbm para la gestión de superficies y búferes. Los dispositivos más antiguos, como NXP i.MX6, seguirán utilizando el enfoque heredado, específico del proveedor de GPU, para conectar las superficies de ventana EGL al framebuffer, utilizando backends eglfs dedicados, como eglfs_viv.
Nota: Ten en cuenta que Qt es sólo un componente de la pila de software de un dispositivo embebido. Especialmente cuando hay gráficos acelerados involucrados, Qt espera una pila de gráficos funcional, con una configuración apropiada para los componentes del espacio de usuario y del núcleo, como el controlador de pantalla. Estos componentes están fuera del dominio de Qt, y es responsabilidad del integrador del sistema asegurarse de que el sistema base es completamente funcional y óptimo, incluyendo los gráficos acelerados.
Para más información sobre gráficos y configuración de entrada para sistemas Embedded Linux, consulte Qt para Embedded Linux.
Archivos Toolchain versus Makespecs de Dispositivo
En Qt 5, normalmente se utiliza una especificación de dispositivo en el directorio qtbase/mkspecs/devices. Estas contienen las banderas apropiadas del compilador y del enlazador para un determinado dispositivo, asegurándose también de que las librerías correctas EGL y OpenGL ES son recogidas, en caso de que estén en una ubicación no estándar en el sysroot.
Por ejemplo, podrías haber configurado una compilación de Qt 5 para una Raspberry Pi 2 con un comando configure como el siguiente:
./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
Nota: configure siempre utiliza el generador Ninja y la herramienta de compilación si un ejecutable ninja está disponible. Ninja es multiplataforma, rico en características, performante y recomendado en todas las plataformas. El uso de otros generadores puede funcionar pero no está soportado oficialmente.
Con Qt 6 y CMake, este enfoque ya no es suficiente por sí solo. En su lugar, se debe proporcionar un archivo CMake toolchain antes de que se pueda configurar. Es en este archivo donde tiene lugar la personalización con respecto a las banderas del compilador y del enlazador, y las peculiaridades específicas del toolchain y del sysroot.
En las siguientes secciones presentaremos un archivo de cadena de herramientas que puede ser utilizado en muchos casos, con una personalización mínima. Se basa en el enfoque presentado en esta entrada de blog.
Nota: El archivo toolchain presentado a continuación es un ejemplo, que a menudo necesitará una mayor personalización para un dispositivo determinado. Los usuarios y los integradores de sistemas también son libres de crear sus propios archivos de cadena de herramientas de la forma que consideren oportuna.
Aunque CMake es el único sistema de construcción soportado para construir Qt, las aplicaciones pueden construirse usando qmake en Qt 6.0. Para obtener una configuración de qmake que sea funcional con la compilación cruzada, será necesario especificar algunos de los argumentos heredados a CMake o a configure.
Herramientas de host
La compilación cruzada de Qt requiere una compilación host de Qt disponible. Ver Compilación cruzada de Qt para más detalles.
Configurando Qt
Asumamos que lo siguiente está disponible:
- un toolchain y sysroot bajo
$HOME/rpi-sdk, - un checkout de Qt, como mínimo el módulo qtbase, en
$HOME/qt-cross, - un host build de Qt en
$HOME/qt-host.
Además, hay que decidir lo siguiente antes de configurar:
- ¿Dónde se instalará la compilación de Qt en el sistema local una vez finalizada la compilación? En el ejemplo usaremos
$HOME/qt6-rpi. - ¿Dónde se instalará la compilación de Qt en el dispositivo? En el ejemplo usaremos
/usr/local/qt6.
En el ejemplo vamos a utilizar un SDK de Raspberry Pi 4 (toolchain+sysroot) generado vía Yocto, pero las instrucciones aquí son completamente genéricas, sin dependencia de Yocto. Los pasos son los mismos con cualquier otro toolchain y sysroot, una vez que el archivo toolchain se actualiza con el compilador cruzado correcto y otras rutas.
Después de crear y cambiar a un directorio build:
$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
En la práctica este comando configure es equivalente a la siguiente llamada directa a CMake:
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
Dado el archivo toolchain apropiado, esto es suficiente para generar una compilación Qt que luego permite que las aplicaciones se construyan usando CMake. Para permitir que las aplicaciones se construyan también con qmake, se debe especificar la especificación de dispositivo estilo Qt 5 y las opciones de dispositivo, además de todos los argumentos mostrados anteriormente:
$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" \ ...
Por defecto, cuando se realiza la compilación cruzada, sólo se compilan las librerías y herramientas Qt que se supone que deben ejecutarse en el dispositivo de destino. Las herramientas relacionadas con la compilación como moc y uic no se compilan. La compilación de dichas herramientas puede activarse configurando QT_FORCE_BUILD_TOOLS a ON.
Nota: Si se activa QT_FORCE_BUILD_TOOLS, los binarios de destino de herramientas como qmake se instalarán en la ubicación de almacenamiento. Por lo tanto, si se utiliza qmake para construir aplicaciones, llame al script host-qmake en su lugar.
Una vez completada la configuración sin errores, ejecute cmake --build . --parallel para compilar. Una vez compilado, ejecute cmake --install . para instalar los resultados en $HOME/qt6-rpi. Desde allí la compilación de Qt puede ser desplegada al dispositivo usando rsync, scp, u otro método.
Si se construyen módulos Qt individuales, se puede utilizar el script qt-configure-module desde el directorio bin de la ubicación de montaje ($HOME/qt6-rpi en el ejemplo) para configurar módulos adicionales, tales como qtdeclarative, qtquick3d, y así sucesivamente. A continuación, se pueden compilar con cmake --build . e instalar en la ubicación de montaje ejecutando cmake --install .
Nota: Antes de iniciar la compilación, inspeccione siempre cuidadosamente la salida del paso de configuración: ¿tiene activadas todas las características esperadas? Realizar una compilación e instalarla en el dispositivo es inútil si las funciones esenciales no están activadas en el momento de la configuración.
Por ejemplo, cuando se desean gráficos acelerados a través de OpenGL, preste especial atención a las siguientes características:
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
Con el ejemplo de Raspberry Pi 4, esperamos que EGL, OpenGL ES y EGLFS GBM sean reportados como yes, de lo contrario el plugin de plataforma EGLFS y su backend eglfs_kms no serán funcionales en el dispositivo. Para que el ratón, el teclado y la entrada táctil funcionen, debe estar habilitado evdev o libinput.
Del mismo modo, si se planea utilizar X11 como el (o uno de los) sistemas de ventanas en el dispositivo, asegúrese de que las funciones relacionadas con xcb y X11 están marcadas como yes.
Ejemplo de archivo Toolchain
Asumiremos que hay un sysroot y un toolchain disponibles bajo $HOME/rpi-sdk. TARGET_SYSROOT y CROSS_COMPILER deben ajustarse al toolchain y al sysroot en uso. Este ejemplo sólo es adecuado para un SDK específico generado por Yocto. Lo mismo ocurre con CMAKE_C_COMPILER y CMAKE_CXX_COMPILER.
No nos basamos en ningún script envoltorio que proporcione variables de entorno como PKG_CONFIG_*. En su lugar, la ruta a los archivos .pc se especifica en el archivo de la cadena de herramientas. Es probable que otro sysroot necesite ajustes en PKG_CONFIG_LIBDIR. Por ejemplo, con un sysroot generado a partir de una imagen Raspberry Pi OS (antes Raspbian) se usaría /usr/lib/arm-gnueabihf/pkgconfig en su lugar.
Las banderas del compilador y del enlazador no son las óptimas necesarias en el ejemplo. Ajústelos según sea necesario para el dispositivo de destino.
Para obtener más información sobre los detalles de CMake en el archivo toolchain de ejemplo, consulte esta entrada del blog y la documentación de 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()Creación de aplicaciones para el dispositivo de destino
Una vez que la compilación de Qt está hecha e instalada en la ubicación de montaje, se pueden compilar ejemplos o aplicaciones.
Con CMake, utiliza el script qt-cmake generado en el directorio bin de la ubicación de montaje ($HOME/qt6-rpi en el ejemplo) para configurar, luego ejecuta ninja. Por ejemplo:
$HOME/qt6-rpi/bin/qt-cmake . cmake --build .
El binario de la aplicación resultante puede desplegarse en el dispositivo. Usar el script de ayuda qt-cmake es conveniente, porque el script asegura que el archivo toolchain que fue usado para construir Qt es cargado, así que no hay necesidad de especificarlo repetidamente para cada aplicación.
A diferencia de Qt, la compilación de aplicaciones con qmake sigue siendo compatible con Qt 6.0, siempre que se disponga de una especificación de dispositivo adecuada y se hayan pasado los argumentos heredados apropiados a CMake o configure al configurar Qt. Si todo esto es cierto, la ejecución de qmake y make también generará un binario de aplicación para el dispositivo de destino.
Plugins de plataforma y EGLFS por defecto
Una vez configurado, se elige un plugin de plataforma por defecto. Este se utiliza cuando se lanza una aplicación sin el argumento -platform y sin tener configurada la variable de entorno QT_QPA_PLATFORM.
Del mismo modo, el plugin de plataforma EGLFS tiene múltiples backends. El predeterminado se elige en función de la disponibilidad y de un orden de prioridad predefinido. Si drm y gbm están disponibles, el predeterminado será el backend eglfs_kms. Esto siempre se puede anular en tiempo de ejecución estableciendo la variable de entorno QT_QPA_EGLFS_INTEGRATION.
Para cambiar estos valores predeterminados para la construcción, sin tener que forzar un valor específico en tiempo de ejecución, las siguientes dos variables de caché CMake están disponibles después de CMake se ha ejecutado una vez:
QT_QPA_DEFAULT_PLATFORM(STRING) - El nombre del plugin de plataforma por defecto.QT_QPA_DEFAULT_EGLFS_INTEGRATION(STRING) - El backend EGLFS por defecto.
Estas variables también se pueden configurar dentro del archivo toolchain.
Para más información sobre la configuración de Qt, ver Qt Configure Options.
© 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.