Debian Qt Toolchain installation: Difference between revisions
No edit summary |
No edit summary |
||
(37 intermediate revisions by the same user not shown) | |||
Line 9: | Line 9: | ||
--> {{#vardefine:QT_VER_SHORT|{{#explode:{{#var:QT_VER}}|.|0}}.{{#explode:{{#var:QT_VER}}|.|1}}}} <!-- | --> {{#vardefine:QT_VER_SHORT|{{#explode:{{#var:QT_VER}}|.|0}}.{{#explode:{{#var:QT_VER}}|.|1}}}} <!-- | ||
--> {{#vardefine:QT_CMAKE_VER| | --> {{#vardefine:QT_CMAKE_VER|3.22.0}} <!-- | ||
--> {{#vardefine:QT_CROSS_COMPILER_VER| | --> {{#vardefine:QT_CROSS_COMPILER_VER|}} <!-- | ||
--> {{#vardefine:QT_TARGET_MKSPEC|devices/linux-imx8-g++}} <!-- | --> {{#vardefine:QT_TARGET_MKSPEC|devices/linux-imx8-g++}} <!-- | ||
--> {{#vardefine:QT_TARGET_CMAKE_TOOLCHAIN_FILE|toolchain.cmake}} <!-- | --> {{#vardefine:QT_TARGET_CMAKE_TOOLCHAIN_FILE|toolchain.cmake}} <!-- | ||
--> {{#vardefine:QT_SRC_DIR|{{#var:BUILD_FOLDER}}/src/qt{{#var:QT_VER_MAJOR}}}} <!-- | --> {{#vardefine:QT_SRC_DIR|{{#var:BUILD_FOLDER}}/src/qt{{#var:QT_VER_MAJOR}}}} <!-- | ||
--> {{#vardefine:QT_ROOTFS_DIR| | --> {{#vardefine:QT_ROOTFS_DIR|usr/local/qt{{#var:QT_VER_MAJOR}}}} <!-- | ||
--> {{#vardefine: | --> {{#vardefine:QT_HOST|qt{{#var:QT_VER_MAJOR}}-x86_64}} <!-- | ||
--> {{#vardefine: | --> {{#vardefine:QT_HOST_DIR|{{#var:BUILD_FOLDER}}/toolchain/{{#var: QT_HOST}}}} <!-- | ||
--> {{#vardefine:QT_TARGET|qt{{#var:QT_VER_MAJOR}}-{{#var:SOC}}-debian-{{#var:DEBIAN_VERSION}}-wayland}} <!-- | |||
--> {{#vardefine:QT_TARGET_DIR|{{#var:BUILD_FOLDER}}/toolchain/{{#var:QT_TARGET}}}} <!-- | |||
--> {{#vardefine:QT_BUILD_HOST_DIR|{{#var:QT_SRC_DIR}}/.x86_64_build}} <!-- | --> {{#vardefine:QT_BUILD_HOST_DIR|{{#var:QT_SRC_DIR}}/.x86_64_build}} <!-- | ||
--> {{#vardefine:QT_BUILD_TARGET_DIR|{{#var:QT_SRC_DIR}}/.{{#var:SOC}}-debian-{{#var:DEBIAN_VERSION}}-wayland_build}} <!-- | --> {{#vardefine:QT_BUILD_TARGET_DIR|{{#var:QT_SRC_DIR}}/.{{#var:SOC}}-debian-{{#var:DEBIAN_VERSION}}-wayland_build}} <!-- | ||
Line 23: | Line 25: | ||
-->{{PageHeader|{{#var:HARDWARE_NAME}} - Debian Qt{{#var:QT_VER}} Toolchain Installation}} {{DocImage|category1=Debian|category2={{#var:HARDWARE_NAME}}}} __toc__ | -->{{PageHeader|{{#var:HARDWARE_NAME}} - Debian Qt{{#var:QT_VER}} Toolchain Installation}} {{DocImage|category1=Debian|category2={{#var:HARDWARE_NAME}}}} __toc__ | ||
= | <includeonly> | ||
<section begin=DEBIAN_QT_TOOLCHAIN_FOLDER_OVERVIEW/> | |||
{| | {| | ||
|- | |- | ||
| {{#var: QT_SRC_DIR}} | | {{#var: QT_SRC_DIR}} | ||
Line 45: | Line 40: | ||
|   | |   | ||
| Build folder for Qt{{#var:QT_VER_MAJOR}} target compilation | | Build folder for Qt{{#var:QT_VER_MAJOR}} target compilation | ||
|- | |||
| {{#var: BUILD_FOLDER}}/toolchain/sysroot | |||
|   | |||
| Debian sysroot, created using the {{varlink|Debian_Toolchain_installation#Create_a_sysroot|{{#var:RELEASE_NAME}}|Create a Debian sysroot}} guide | |||
|- | |- | ||
| {{#var: QT_HOST_DIR}} | | {{#var: QT_HOST_DIR}} | ||
Line 54: | Line 53: | ||
| Installation folder for the Qt{{#var:QT_VER_MAJOR}} target variant | | Installation folder for the Qt{{#var:QT_VER_MAJOR}} target variant | ||
|} | |} | ||
<section end=DEBIAN_QT_TOOLCHAIN_FOLDER_OVERVIEW/> | |||
</includeonly> | |||
= Introduction = | |||
Qt is a powerful cross-platform application framework that enables developers to create high-performance applications for various operating systems, including embedded Linux. It provides a comprehensive library of pre-defined components and tools for creating graphical user interfaces, network applications, and more. This guide provides a walkthrough on how to cross-compile Qt{{#var:QT_VERS}} for Variscite i.MX8-based SOMs, allow you to compile applications on a host machine and deploy them to the SOM running Debian {{#var:DEBIAN_NAME}}. | |||
The generated Qt toolchain consists of the following: | |||
* {{#var:QT_HOST}}: Qt installation (headers, libraries, plugins, etc.) for the host architecture | |||
* {{#var:QT_TARGET}}: Qt installation (headers, libraries, plugins, etc.) for the target architecture | |||
The Qt toolchain with the Cross Compiler and the target sysroot enables Qt application programming from CLI or using the {{varlink|Yocto_Qt_Creator|{{#var:RELEASE_NAME}}|Qtcreator IDE}}. | |||
You can find a list of useful Qt documentation references in the section: {{varlink|Yocto_QT_Hello_World#Yocto_Qt_Creator_Guide|{{#var:RELEASE_NAME}}|Qt Creator guide}} | |||
{{Note|'''Info''': | |||
As we're going to deal with several folders, here is a short summary to keep track: | |||
{{#lst:Debian_Qt_Toolchain_installation|DEBIAN_QT_TOOLCHAIN_FOLDER_OVERVIEW}} | |||
|info}} | |||
= Setup Host Computer environment = | = Setup Host Computer environment = | ||
Ubuntu 20.04 | We will create the Qt toolchain in the Debian build environment using a Ubuntu 20.04 machine. Therefore, please follow the steps: | ||
# {{varlink| Debian_Build_Release_Stage#Setup Development Environment |{{#var:RELEASE_NAME}}|Setup Development Environment}} | |||
# {{varlink| Debian_Build_Release_Stage#Download Debian build script |{{#var:RELEASE_NAME}}|Download Debian build script}} | |||
# {{varlink| Debian_Build_Release_Stage#Deploy sources |{{#var:RELEASE_NAME}}|Fetch/Deploy sources}} | |||
Now, we need to install the packages needed for the Qt toolchain generation, please run the following to install those: | |||
<!-- TODO: Some of the packages are already installed by setting up the build environment --> | |||
$ sudo apt-get update | $ sudo apt-get update | ||
$ sudo apt-get install -y make build-essential libclang-dev ninja-build gcc git bison python3 gperf pkg-config libfontconfig1-dev \ | $ sudo apt-get install -y make build-essential libclang-dev ninja-build gcc git bison python3 gperf pkg-config libfontconfig1-dev \ | ||
Line 68: | Line 87: | ||
libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-shape0-dev \ | libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-shape0-dev \ | ||
libxcb-randr0-dev libxcb-render-util0-dev libxcb-util-dev libxcb-xinerama0-dev libxcb-xkb-dev libxkbcommon-dev \ | libxcb-randr0-dev libxcb-render-util0-dev libxcb-util-dev libxcb-xinerama0-dev libxcb-xkb-dev libxkbcommon-dev \ | ||
libxkbcommon-x11-dev libatspi2.0-dev libgl1-mesa-dev libglu1-mesa-dev freeglut3-dev | libxkbcommon-x11-dev libatspi2.0-dev libgl1-mesa-dev libglu1-mesa-dev freeglut3-dev \ | ||
libwayland-dev libwayland-bin libwayland-egl1-mesa libwayland-client0 libwayland-server0 libwayland-cursor0 libgles2-mesa-dev | |||
Next, we will install the GNU C/C++ Cross Compiler: | |||
$ sudo apt install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu | |||
{{Note|'''Note''': In the {{varlink|Debian_Toolchain_installation|{{#var:RELEASE_NAME}}|Debian toolchain installation}} guide, we're referring to the Cross Compiler which is shipped with the Debian script. For the Qt{{#var:QT_VER_MAJOR}} toolchain generation and Qt{{#var:QT_VER_MAJOR}} application programming, we need a newer one.|info}} | |||
Finally, we will need to update cmake manually to a newer version: | |||
$ cd ~ | $ cd ~ | ||
$ sudo apt-get remove -y cmake | $ sudo apt-get remove -y cmake | ||
$ wget https://github.com/Kitware/CMake/releases/download/v{{#var: | $ wget https://github.com/Kitware/CMake/releases/download/v{{#var:QT_CMAKE_VER}}/cmake-{{#var:QT_CMAKE_VER}}.tar.gz | ||
$ tar -zvxf cmake-{{#var:QT_CMAKE_VER}}.tar.gz | $ tar -zvxf cmake-{{#var:QT_CMAKE_VER}}.tar.gz | ||
$ cd cmake-{{#var:QT_CMAKE_VER}} | $ cd cmake-{{#var:QT_CMAKE_VER}} | ||
Line 95: | Line 115: | ||
$ cd {{#var:BUILD_FOLDER}}/src | $ cd {{#var:BUILD_FOLDER}}/src | ||
$ wget https://download.qt.io/archive/qt/{{#var: | $ wget https://download.qt.io/archive/qt/{{#var:QT_VER_SHORT}}/{{#var:QT_VER}}/single/qt-everywhere-src-{{#var:QT_VER}}.tar.xz | ||
And untar the archive: | And untar the archive: | ||
$ tar -xf qt-everywhere-src-{{#var:QT_VER}}.tar.xz qt{{#var:QT_VER_MAJOR}} | $ tar -xf qt-everywhere-src-{{#var:QT_VER}}.tar.xz | ||
$ mv qt-everywhere-src-{{#var:QT_VER}} qt{{#var:QT_VER_MAJOR}} | |||
$ cd .. | $ cd .. | ||
The Qt{{#var:QT_VER_MAJOR}} framework sources are now located at ''{{#var:QT_SRC_DIR}}''. | The Qt{{#var:QT_VER_MAJOR}} framework sources are now located at ''{{#var:QT_SRC_DIR}}''. | ||
= | = Configure, compile and install Qt{{#var:QT_VER_MAJOR}} for the host = | ||
Create the build and installation folder: | Create the build and installation folder: | ||
$ mkdir -p {{#var:QT_BUILD_HOST_DIR}} | |||
$ mkdir -p {{#var:QT_HOST_DIR}} | $ mkdir -p {{#var:QT_HOST_DIR}} | ||
Build and install the Qt framework for the host: | Build and install the Qt framework for the host: | ||
$ cd {{#var:QT_BUILD_HOST_DIR}} | $ cd {{#var:QT_BUILD_HOST_DIR}} | ||
$ cmake .. | $ cmake ../ -Wno-dev -GNinja -DCMAKE_BUILD_TYPE=Release -DQT_BUILD_EXAMPLES=OFF -DQT_BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX={{#replace:{{#var:QT_HOST_DIR}}|~|$HOME}} -DBUILD_qtwayland=ON | ||
$ cmake --build . --parallel | $ cmake --build . --parallel $(nproc) | ||
$ cmake --install . | $ cmake --install . | ||
= Cross-Compile Qt{{#var:QT_VER_MAJOR}} for the target = | = Cross-Compile Qt{{#var:QT_VER_MAJOR}} for the target = | ||
== Create | == Create a Qt cross-compilation sysroot == | ||
In order to perform cross-compilation of the Qt framework for the target system on the host, we would require a Debian sysroot containing all the necessary libraries. The essential libraries for the Debian rootfs (which will later be extracted as sysroot) will be added by utilizing the G_USER_PACKAGES variable in the build script. | |||
Please refer to the {{varlink|Adding_Debian_packages|{{#var:RELEASE_NAME}}|Adding packages to the Debian image}} guide for more information where to find the G_USER_PACKAGES variable, and add: | |||
<syntaxhighlight lang=bash> | |||
readonly G_USER_PACKAGES="\ | |||
libboost-all-dev libudev-dev libinput-dev libts-dev libmtdev-dev libjpeg-dev libfontconfig1-dev libssl-dev libdbus-1-dev libglib2.0-dev \ | |||
libxkbcommon-dev libegl1-mesa-dev libgbm-dev libgles2-mesa-dev mesa-common-dev libasound2-dev libpulse-dev gstreamer1.0-omx libgstreamer1.0-dev \ | |||
libgstreamer-plugins-base1.0-dev gstreamer1.0-alsa libvpx-dev libsrtp2-dev libsnappy-dev libnss3-dev "^libxcb.*" flex bison libxslt-dev \ | |||
ruby gperf libbz2-dev libcups2-dev libatkmm-1.6-dev libxi6 libxcomposite1 libfreetype6-dev libicu-dev libsqlite3-dev libxslt1-dev \ | |||
\ | |||
libavcodec-dev libavformat-dev libswscale-dev libx11-dev freetds-dev libsqlite3-dev libpq-dev libiodbc2-dev firebird-dev libgst-dev \ | |||
libxext-dev libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev 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 libatspi2.0-dev libxcursor-dev libxcomposite-dev libxdamage-dev \ | |||
libxss-dev libxtst-dev libpci-dev libcap-dev libxrandr-dev libdirectfb-dev libaudio-dev libxkbcommon-x11-dev \ | |||
\ | |||
libwayland-dev libwayland-egl1-mesa libwayland-client0 libwayland-server0 libwayland-cursor0 libgles2-mesa-dev \ | |||
" | |||
</syntaxhighlight> | |||
Next, execute the build script to build the complete Debian system: | |||
$ cd {{#var:BUILD_FOLDER}} | |||
$ sudo {{#var:BUILD_SCRIPT}} -c all | |||
Once Debian has been built, please refer to the {{varlink|Debian_Toolchain_installation#Create_a_sysroot|{{#var:RELEASE_NAME}}|Create a Debian sysroot}} guide to learn how to create the sysroot.<br> | |||
The sysroot should be located at ''{{#var:BUILD_FOLDER}}/toolchain/sysroot'' and can be used to | The sysroot should then be located at ''{{#var:BUILD_FOLDER}}/toolchain/sysroot'' and can be used to compile the Qt{{#var:QT_VERS_MAJOR}} framework in the next step. | ||
== | == Configure, compile and install Qt == | ||
Create the build and installation folder: | Create the build and installation folder: | ||
$ mkdir -p {{#var:QT_BUILD_TARGET_DIR}} | |||
$ mkdir -p {{#var:QT_TARGET_DIR}} | $ mkdir -p {{#var:QT_TARGET_DIR}} | ||
Create a file, named '''{{#var:QT_TARGET_CMAKE_TOOLCHAIN_FILE}}''', and locate it at ''{{#var:QT_BUILD_TARGET_DIR}}'', with the following content: | Create a file, named '''{{#var:QT_TARGET_CMAKE_TOOLCHAIN_FILE}}''', and locate it at ''{{#var:QT_BUILD_TARGET_DIR}}'', with the following content: | ||
Line 170: | Line 195: | ||
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc-9) | set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc-9) | ||
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++-9) | set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++-9) | ||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${TARGET_SYSROOT}/usr/include") | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${TARGET_SYSROOT}/usr/include") | ||
Line 238: | Line 261: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
And replace the token <code><<<TARGET_SYSROOT_PATH>>></code> with <code> | And replace the token <code><<<TARGET_SYSROOT_PATH>>></code> with <code>/home/USER/{{#var:BUILD_FOLDER_NAME}}/toolchain/sysroot</code>, where USER is your user name, in the toolchain.make file, to declare the sysroot path. | ||
Next, we can cross-compile the Qt{{#var:QT_VERS_MAJOR}} framework for the target: | Next, we can cross-compile the Qt{{#var:QT_VERS_MAJOR}} framework for the target: | ||
Line 244: | Line 267: | ||
$ cmake ../ -GNinja -Wno-dev -DCMAKE_BUILD_TYPE=Release \ | $ cmake ../ -GNinja -Wno-dev -DCMAKE_BUILD_TYPE=Release \ | ||
-DQT_HOST_PATH={{#replace:{{#var:QT_HOST_DIR}}|~|$HOME}} \ | -DQT_HOST_PATH={{#replace:{{#var:QT_HOST_DIR}}|~|$HOME}} \ | ||
-DCMAKE_INSTALL_PREFIX={{#var:QT_ROOTFS_DIR}} \ | -DCMAKE_INSTALL_PREFIX=/{{#var:QT_ROOTFS_DIR}} \ | ||
-DCMAKE_TOOLCHAIN_FILE={{#replace:{{#var:QT_BUILD_TARGET_DIR}}/{{#var:QT_TARGET_CMAKE_TOOLCHAIN_FILE}}|~|$HOME}} \ | -DCMAKE_TOOLCHAIN_FILE={{#replace:{{#var:QT_BUILD_TARGET_DIR}}/{{#var:QT_TARGET_CMAKE_TOOLCHAIN_FILE}}|~|$HOME}} \ | ||
-DCMAKE_STAGING_PREFIX={{#replace:{{#var:QT_TARGET_DIR}}|~|$HOME}} \ | -DCMAKE_STAGING_PREFIX={{#replace:{{#var:QT_TARGET_DIR}}|~|$HOME}} \ | ||
Line 250: | Line 273: | ||
-DQT_BUILD_EXAMPLES=OFF -DQT_BUILD_TESTS=OFF \ | -DQT_BUILD_EXAMPLES=OFF -DQT_BUILD_TESTS=OFF \ | ||
-DBUILD_qtwayland=ON \ | -DBUILD_qtwayland=ON \ | ||
-DINPUT_opengl=es2 \ | |||
-DQT_FEATURE_xcb=ON -DFEATURE_xcb_xlib=ON -DQT_FEATURE_xlib=ON \ | -DQT_FEATURE_xcb=ON -DFEATURE_xcb_xlib=ON -DQT_FEATURE_xlib=ON \ | ||
-DBUILD_qt3d | -DBUILD_qt3d=OFF | ||
$ cmake --build . --parallel $(nproc) | $ cmake --build . --parallel $(nproc) | ||
And finally, install it locally | And finally, install it locally (cmake will install it here: ''{{#var:QT_TARGET_DIR}}'', the dot in the command refers to the cmake root): | ||
$ cmake --install . | $ cmake --install . | ||
= Install Qt{{#var:QT_VER_MAJOR}} on the target = | |||
In order for the Qt applications to find the Qt{{#var:QT_VER_MAJOR}} runtime libraries, plugins, and so on, it is necessary to install Qt{{#var:QT_VER_MAJOR}} on the target. The installation path must be: ''/{{#var: QT_ROOTFS_DIR}}'', and the following environment variables should be declared: | |||
{| | |||
|- | |||
| LD_LIBRARY_PATH | |||
|   | |||
| /usr/local/qt6/lib (The LD_LIBRARY_PATH already exists, append the value to it) | |||
|- | |||
| QT_QPA_PLATFORM_PLUGIN_PATH | |||
|   | |||
| /usr/local/qt6/plugins | |||
|- | |||
| QT_QPA_PLATFORM | |||
|   | |||
| wayland | |||
|} | |||
A Qt application invoke (for a test) could look, for example, like this:<br> | |||
Export the environment variables: | |||
# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/{{#var: QT_ROOTFS_DIR}}/lib | |||
# export QT_QPA_PLATFORM_PLUGIN_PATH=/{{#var: QT_ROOTFS_DIR}}/plugins | |||
# export QT_QPA_PLATFORM=wayland | |||
And run the Qt application: | |||
# XDG_RUNTIME_DIR=/run/user/0 DISPLAY=:0 <qt6-application> | |||
Numerous methods exist for creating a static environment setup, with plenty of explanatory examples available on the internet. | |||
== Install Qt at compile-time == | |||
You can add an install routine to the Debian build script to install Qt{{#var:QT_VER_MAJOR}} at compile-time. Please refer to {{varlink|Adding_Debian_packages#Adding_application_to_rootfs|{{#var:RELEASE_NAME}}|Adding an application to the Debian image}} to learn how to do it. | |||
Or alternatively (for a test), you can copy it locally to the rootfs: | |||
$ cd {{#var:BUILD_FOLDER}} | |||
$ sudo mkdir -p rootfs/{{#var:QT_ROOTFS_DIR}} | |||
$ sudo cp {{#var:BUILD_FOLDER}}/toolchain/{{#var:QT_TARGET}}/. rootfs/{{#var:QT_ROOTFS_DIR}} | |||
And re-create the rootfs archive: | |||
$ {{#var:BUILD_SCRIPT}} -c rtar | |||
{{varlink|Debian_Build_Release_Stage#Create_a_bootable_SD_card|{{#var:RELEASE_NAME}}|Creating an SD card}}, the Qt{{#var:QT_VER_MAJOR}} installation should then be in place. | |||
== Install Qt at runtime == | |||
One can use SCP to install Qt to the target at runtime, for example: | |||
$ cd {{#var:BUILD_FOLDER}}/toolchain/{{#var:QT_TARGET}} | |||
$ scp -r * root@<target-ip-address>:/{{#var:QT_ROOTFS_DIR}} |
Latest revision as of 00:14, 29 May 2023
This page is using the default release mx8mp-debian-bullseye-5.10.52_2.1.0-v1.1.
To view this page for a specific Variscite SoM and software release, please follow these steps:
- Visit variwiki.com
- Select your SoM
- Select the software release
Introduction
Qt is a powerful cross-platform application framework that enables developers to create high-performance applications for various operating systems, including embedded Linux. It provides a comprehensive library of pre-defined components and tools for creating graphical user interfaces, network applications, and more. This guide provides a walkthrough on how to cross-compile Qt for Variscite i.MX8-based SOMs, allow you to compile applications on a host machine and deploy them to the SOM running Debian Bullseye.
The generated Qt toolchain consists of the following:
- qt6-x86_64: Qt installation (headers, libraries, plugins, etc.) for the host architecture
- qt6-mx8mp-debian-11-wayland: Qt installation (headers, libraries, plugins, etc.) for the target architecture
The Qt toolchain with the Cross Compiler and the target sysroot enables Qt application programming from CLI or using the Qtcreator IDE.
You can find a list of useful Qt documentation references in the section: Qt Creator guide
As we're going to deal with several folders, here is a short summary to keep track:
~/debian_imx8mp-var-dart/src/qt6 | Folder for the Qt6 framework sources | |
~/debian_imx8mp-var-dart/src/qt6/.x86_64_build | Build folder for Qt6 host compilation | |
~/debian_imx8mp-var-dart/src/qt6/.mx8mp-debian-11-wayland_build | Build folder for Qt6 target compilation | |
~/debian_imx8mp-var-dart/toolchain/sysroot | Debian sysroot, created using the Create a Debian sysroot guide | |
~/debian_imx8mp-var-dart/toolchain/qt6-x86_64 | Installation folder for the Qt6 host variant | |
~/debian_imx8mp-var-dart/toolchain/qt6-mx8mp-debian-11-wayland | Installation folder for the Qt6 target variant |
Setup Host Computer environment
We will create the Qt toolchain in the Debian build environment using a Ubuntu 20.04 machine. Therefore, please follow the steps:
Now, we need to install the packages needed for the Qt toolchain generation, please run the following to install those:
$ sudo apt-get update $ sudo apt-get install -y make build-essential libclang-dev ninja-build gcc git bison python3 gperf pkg-config libfontconfig1-dev \ libfreetype6-dev libx11-dev libx11-xcb-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libxcb-glx0-dev \ libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-shape0-dev \ libxcb-randr0-dev libxcb-render-util0-dev libxcb-util-dev libxcb-xinerama0-dev libxcb-xkb-dev libxkbcommon-dev \ libxkbcommon-x11-dev libatspi2.0-dev libgl1-mesa-dev libglu1-mesa-dev freeglut3-dev \ libwayland-dev libwayland-bin libwayland-egl1-mesa libwayland-client0 libwayland-server0 libwayland-cursor0 libgles2-mesa-dev
Next, we will install the GNU C/C++ Cross Compiler:
$ sudo apt install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
Finally, we will need to update cmake manually to a newer version:
$ cd ~ $ sudo apt-get remove -y cmake $ wget https://github.com/Kitware/CMake/releases/download/v3.22.0/cmake-3.22.0.tar.gz $ tar -zvxf cmake-3.22.0.tar.gz $ cd cmake-3.22.0 $ ./bootstrap $ make -j$(nproc) $ sudo make install
Once the installation is done, it is reasonable to double-check the version:
$ cmake --version cmake version 3.22.0
Obtain Qt6 framework sources
Download the Qt6 sources from the official Qt download archive:
$ cd ~/debian_imx8mp-var-dart/src $ wget https://download.qt.io/archive/qt/6.4/6.4.0/single/qt-everywhere-src-6.4.0.tar.xz
And untar the archive:
$ tar -xf qt-everywhere-src-6.4.0.tar.xz $ mv qt-everywhere-src-6.4.0 qt6 $ cd ..
The Qt6 framework sources are now located at ~/debian_imx8mp-var-dart/src/qt6.
Configure, compile and install Qt6 for the host
Create the build and installation folder:
$ mkdir -p ~/debian_imx8mp-var-dart/src/qt6/.x86_64_build $ mkdir -p ~/debian_imx8mp-var-dart/toolchain/qt6-x86_64
Build and install the Qt framework for the host:
$ cd ~/debian_imx8mp-var-dart/src/qt6/.x86_64_build $ cmake ../ -Wno-dev -GNinja -DCMAKE_BUILD_TYPE=Release -DQT_BUILD_EXAMPLES=OFF -DQT_BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=$HOME/debian_imx8mp-var-dart/toolchain/qt6-x86_64 -DBUILD_qtwayland=ON $ cmake --build . --parallel $(nproc) $ cmake --install .
Cross-Compile Qt6 for the target
Create a Qt cross-compilation sysroot
In order to perform cross-compilation of the Qt framework for the target system on the host, we would require a Debian sysroot containing all the necessary libraries. The essential libraries for the Debian rootfs (which will later be extracted as sysroot) will be added by utilizing the G_USER_PACKAGES variable in the build script. Please refer to the Adding packages to the Debian image guide for more information where to find the G_USER_PACKAGES variable, and add:
readonly G_USER_PACKAGES="\
libboost-all-dev libudev-dev libinput-dev libts-dev libmtdev-dev libjpeg-dev libfontconfig1-dev libssl-dev libdbus-1-dev libglib2.0-dev \
libxkbcommon-dev libegl1-mesa-dev libgbm-dev libgles2-mesa-dev mesa-common-dev libasound2-dev libpulse-dev gstreamer1.0-omx libgstreamer1.0-dev \
libgstreamer-plugins-base1.0-dev gstreamer1.0-alsa libvpx-dev libsrtp2-dev libsnappy-dev libnss3-dev "^libxcb.*" flex bison libxslt-dev \
ruby gperf libbz2-dev libcups2-dev libatkmm-1.6-dev libxi6 libxcomposite1 libfreetype6-dev libicu-dev libsqlite3-dev libxslt1-dev \
\
libavcodec-dev libavformat-dev libswscale-dev libx11-dev freetds-dev libsqlite3-dev libpq-dev libiodbc2-dev firebird-dev libgst-dev \
libxext-dev libxcb1 libxcb1-dev libx11-xcb1 libx11-xcb-dev 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 libatspi2.0-dev libxcursor-dev libxcomposite-dev libxdamage-dev \
libxss-dev libxtst-dev libpci-dev libcap-dev libxrandr-dev libdirectfb-dev libaudio-dev libxkbcommon-x11-dev \
\
libwayland-dev libwayland-egl1-mesa libwayland-client0 libwayland-server0 libwayland-cursor0 libgles2-mesa-dev \
"
Next, execute the build script to build the complete Debian system:
$ cd ~/debian_imx8mp-var-dart $ sudo MACHINE=imx8mp-var-dart ./var_make_debian.sh -c all
Once Debian has been built, please refer to the Create a Debian sysroot guide to learn how to create the sysroot.
The sysroot should then be located at ~/debian_imx8mp-var-dart/toolchain/sysroot and can be used to compile the Qt framework in the next step.
Configure, compile and install Qt
Create the build and installation folder:
$ mkdir -p ~/debian_imx8mp-var-dart/src/qt6/.mx8mp-debian-11-wayland_build $ mkdir -p ~/debian_imx8mp-var-dart/toolchain/qt6-mx8mp-debian-11-wayland
Create a file, named toolchain.cmake, and locate it at ~/debian_imx8mp-var-dart/src/qt6/.mx8mp-debian-11-wayland_build, with the following content:
cmake_minimum_required(VERSION 3.18)
include_guard(GLOBAL)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(TARGET_SYSROOT <<<TARGET_SYSROOT_PATH>>>)
set(CMAKE_SYSROOT ${TARGET_SYSROOT})
set(ENV{PKG_CONFIG_PATH} $PKG_CONFIG_PATH:/usr/lib/aarch64-linux-gnu/pkgconfig)
set(ENV{PKG_CONFIG_LIBDIR} /usr/lib/pkgconfig:/usr/share/pkgconfig/:${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/pkgconfig:${TARGET_SYSROOT}/usr/lib/pkgconfig)
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})
# if you use other version of gcc and g++ than gcc/g++ 9, you must change the following variables
set(CMAKE_C_COMPILER /usr/bin/aarch64-linux-gnu-gcc-9)
set(CMAKE_CXX_COMPILER /usr/bin/aarch64-linux-gnu-g++-9)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I${TARGET_SYSROOT}/usr/include")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")
set(QT_COMPILER_FLAGS "-march=armv8-a")
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)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
set(CMAKE_BUILD_RPATH ${TARGET_SYSROOT})
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()
set(XCB_PATH_VARIABLE ${TARGET_SYSROOT})
set(GL_INC_DIR ${TARGET_SYSROOT}/usr/include)
set(GL_LIB_DIR ${TARGET_SYSROOT}:${TARGET_SYSROOT}/usr/lib/aarch64-linux-gnu/:${TARGET_SYSROOT}/usr:${TARGET_SYSROOT}/usr/lib)
set(EGL_INCLUDE_DIR ${GL_INC_DIR})
set(EGL_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libEGL.so)
set(OPENGL_INCLUDE_DIR ${GL_INC_DIR})
set(OPENGL_opengl_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libOpenGL.so)
set(GLESv2_INCLUDE_DIR ${GL_INC_DIR})
set(GLIB_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libGLESv2.so)
set(GLESv2_INCLUDE_DIR ${GL_INC_DIR})
set(GLESv2_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libGLESv2.so)
set(gbm_INCLUDE_DIR ${GL_INC_DIR})
set(gbm_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libgbm.so)
set(Libdrm_INCLUDE_DIR ${GL_INC_DIR})
set(Libdrm_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libdrm.so)
set(XCB_XCB_INCLUDE_DIR ${GL_INC_DIR})
set(XCB_XCB_LIBRARY ${XCB_PATH_VARIABLE}/usr/lib/aarch64-linux-gnu/libxcb.so)
And replace the token <<<TARGET_SYSROOT_PATH>>>
with /home/USER/debian_imx8mp-var-dart/toolchain/sysroot
, where USER is your user name, in the toolchain.make file, to declare the sysroot path.
Next, we can cross-compile the Qt framework for the target:
$ cd ~/debian_imx8mp-var-dart/src/qt6/.mx8mp-debian-11-wayland_build $ cmake ../ -GNinja -Wno-dev -DCMAKE_BUILD_TYPE=Release \ -DQT_HOST_PATH=$HOME/debian_imx8mp-var-dart/toolchain/qt6-x86_64 \ -DCMAKE_INSTALL_PREFIX=/usr/local/qt6 \ -DCMAKE_TOOLCHAIN_FILE=$HOME/debian_imx8mp-var-dart/src/qt6/.mx8mp-debian-11-wayland_build/toolchain.cmake \ -DCMAKE_STAGING_PREFIX=$HOME/debian_imx8mp-var-dart/toolchain/qt6-mx8mp-debian-11-wayland \ -DQT_QMAKE_TARGET_MKSPEC=devices/linux-imx8-g++ \ -DQT_BUILD_EXAMPLES=OFF -DQT_BUILD_TESTS=OFF \ -DBUILD_qtwayland=ON \ -DINPUT_opengl=es2 \ -DQT_FEATURE_xcb=ON -DFEATURE_xcb_xlib=ON -DQT_FEATURE_xlib=ON \ -DBUILD_qt3d=OFF $ cmake --build . --parallel $(nproc)
And finally, install it locally (cmake will install it here: ~/debian_imx8mp-var-dart/toolchain/qt6-mx8mp-debian-11-wayland, the dot in the command refers to the cmake root):
$ cmake --install .
Install Qt6 on the target
In order for the Qt applications to find the Qt6 runtime libraries, plugins, and so on, it is necessary to install Qt6 on the target. The installation path must be: /usr/local/qt6, and the following environment variables should be declared:
LD_LIBRARY_PATH | /usr/local/qt6/lib (The LD_LIBRARY_PATH already exists, append the value to it) | |
QT_QPA_PLATFORM_PLUGIN_PATH | /usr/local/qt6/plugins | |
QT_QPA_PLATFORM | wayland |
A Qt application invoke (for a test) could look, for example, like this:
Export the environment variables:
# export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/qt6/lib # export QT_QPA_PLATFORM_PLUGIN_PATH=/usr/local/qt6/plugins # export QT_QPA_PLATFORM=wayland
And run the Qt application:
# XDG_RUNTIME_DIR=/run/user/0 DISPLAY=:0 <qt6-application>
Numerous methods exist for creating a static environment setup, with plenty of explanatory examples available on the internet.
Install Qt at compile-time
You can add an install routine to the Debian build script to install Qt6 at compile-time. Please refer to Adding an application to the Debian image to learn how to do it.
Or alternatively (for a test), you can copy it locally to the rootfs:
$ cd ~/debian_imx8mp-var-dart $ sudo mkdir -p rootfs/usr/local/qt6 $ sudo cp ~/debian_imx8mp-var-dart/toolchain/qt6-mx8mp-debian-11-wayland/. rootfs/usr/local/qt6
And re-create the rootfs archive:
$ MACHINE=imx8mp-var-dart ./var_make_debian.sh -c rtar
Creating an SD card, the Qt6 installation should then be in place.
Install Qt at runtime
One can use SCP to install Qt to the target at runtime, for example:
$ cd ~/debian_imx8mp-var-dart/toolchain/qt6-mx8mp-debian-11-wayland $ scp -r * root@<target-ip-address>:/usr/local/qt6