Skip to content

Reference Image: Verdin iMX8M Plus, Yocto 4.0, Qt 6.5

Burkhard Stubert edited this page Apr 16, 2023 · 6 revisions

Context

Building the Image

$ git clone git@github.com:bstubert/embedded-linux-distros.git

$ mkdir work-yocto-4.0
$ cd work-yocto-4.0
$ export KAS_BUILD_DIR=$PWD/build-verdin-imx8mp-qt6
$ kas-container build ../embedded-linux-distros/yocto-4.0/toradex/verdin-imx8mp-6.1.0.yml

Make sure that you use a different build directory - e.g., build-verdin-imx8mp-qt6 - for the build with meta-qt6 than you used for the build with meta-qt5. Otherwise, libQt5WaylandClient or some other Qt5 library may end up in the Qt6 rootfs and makes it impossible to run Qt6 applications. You only need a new and empty build directory. You can reuse the sstate and download directories from the meta-qt5 build.

Preparations

The Qt6 version of cuteradio can be found in the main branch of the cuteradio-apps repo. The Qt5 version is now in the qt5 branch.

We change the repo entry for meta-qt5 to one for meta-qt6:

meta-qt6:
    url: "https://code.qt.io/yocto/meta-qt6.git"
    refspec: "v6.5.0"
    path: "layers/meta-qt6"

Note that the versioning scheme changed for meta-qt6. The versions are not Yocto versions any more but Qt versions. We can use Qt 6.2 or newer with any Yocto 3.1 or newer. See my post Compatibility between Yocto and Qt 6 Versions.

Replacing meta-qt5 with meta-qt6: The Naive Approach

With meta-qt5 replaced by meta-qt6, I ran the build. I could wield out several parse errors, but got stuck with a build error in Qt6Gui, which is part of qtbase. The build error reveals a fundamental configuration problem. It seems to build X11 stuff, but can't find it. I don't want X11 in the image. So, I changed my approach and looked around how far others got with meta-qt6.

Parsing Errors

The build fails with an error in cuteradio_1.0.bb:

ERROR: ParseError at /build/../work/layers/meta-embeddeduse/recipes-apps/radio/cuteradio_1.0.bb:9: Could not inherit file classes/cmake_qt5.bbclass

We replace inherit cmake_qt5 by inherit qt6-cmake.

The next build failure is from smart-hmi-platform-image.bb:

ERROR: ParseError at /build/../work/layers/meta-embeddeduse/recipes-images/images/smart-hmi-platform-image.bb:6: Could not inherit file classes/populate_sdk_qt5.bbclass

We replace inherit populate_sdk_qt5 by inherit populate_sdk_qt6.

Next failure:

ERROR: Nothing RPROVIDES 'qtgraphicaleffects' (but /build/../work/layers/meta-embeddeduse/recipes-images/images/packagegroup-qt-lgpl.bb RDEPENDS on or otherwise requires it)

The module qtgraphicaleffects has been removed in Qt 6. So, we remove it from the package list in packagegroup-qt-lgpl.bb.

Next failure:

ERROR: Nothing RPROVIDES 'qtquickcontrols2' (but /build/../work/layers/meta-embeddeduse/recipes-images/images/packagegroup-qt-lgpl.bb RDEPENDS on or otherwise requires it)

qtquickcontrols2 does not exist as a repo of its own. It is now part of the qtdeclarative repo. We remove it from packagegroup-qt-lgpl.bb.

Next failure:

ERROR: Nothing RPROVIDES 'qtsystems' (but /build/../work/layers/meta-embeddeduse/recipes-images/images/packagegroup-qt-lgpl.bb RDEPENDS on or otherwise requires it)

qtsystems isn't part of Qt 6 any more. We remove it from packagegroup-qt-lgpl.bb.

Next failure:

ERROR: Nothing PROVIDES 'ffmpeg' (but /build/../work/layers/meta-qt6/recipes-qt/qt6/qtmultimedia_git.bb DEPENDS on or otherwise requires it)
ffmpeg was skipped: because it has a restricted license 'commercial'. Which is not listed in LICENSE_FLAGS_ACCEPTED

We add

LICENSE_FLAGS_ACCEPTED = "commercial_ffmpeg"

to local.conf via the kas configuration file (section local_conf_header). Note that Qt 6.5 is the first version that uses ffmpeg as the default backend of qtmultimedia (instead of gstreamer).

At this point, Yocto starts building the Qt 6.5 libraries.

Build Errors

Building libQt6Gui.so.6.5.0 fails with several undefined references to glX* symbols originating from src/gui/opengl/platform/unix/qglxconvenience.cpp.

It seems that the build tries to build for X11 with OpenGL. I don't want X11, as the image uses Wayland. This is a fundamental configuration problem. So, I checked out how far others got with meta-qt6.

Replacing meta-qt5 with meta-qt6: With Help from Friends

Fixing the Qt6 build errors

I found this Q&A on the Toradex community pages. benjamin.tx describes how to adapt the image and package-group recipes. Let's follow his suggestions.

I ignore the changes to meta-qt6/classes/populate_sdk_qt6.bbclass and the addition of meta-qt6/recipes-qt/packagegroups/packagegroup-qt6-qtcreator-debug.bb for the time being. They enable remote debugging on the target device in QtCreator.

My equivalent to packagegroup-tdx-qt6.bb is packagegroup-qt-lgpl.bb. The latter is a stripped-down version of the former and it is the same.

The list IMAGE_INSTALL of tdx-reference-multimedia-qt6-image.bb does not contain weston-xwayland and xterm. They could very well responsible for X11-related build errors. I remove them in smart-hmi-platform-image.bb, too.

Finally, benjamin.tx removes the distro features directfb and x11 in local.conf. Again, this can eliminate X11-related build errors. I do the same in the section local_conf_header of the kas configuration file verdin-imx8mp-6.1.0.yml.

DISTRO_FEATURES:remove = " directfb x11"

It's time for another build attempt. Building Qt works fine. The build fails in my own cuteradio recipe.

Fixing the cuteradio build errors

Building the cuteradio recipe fails in the configure step.

| -- Could NOT find Qt6QmlTools (missing: Qt6QmlTools_DIR)
| CMake Warning at CMakeLists.txt:19 (find_package):
|   Found package configuration file:
| 
|     /build/tmp/work/cortexa53-tdx-linux/cuteradio/1.0+gitAUTOINC+25c1511566-r0/recipe-sysroot/usr/lib/cmake/Qt6Qml/Qt6QmlConfig.cmake
| 
|   but it set Qt6Qml_FOUND to FALSE so package "Qt6Qml" is considered to be
|   NOT FOUND.  Reason given by package:
| 
|   Qt6Qml could not be found because dependency Qt6QmlTools could not be
|   found.

The error is caused by the line

find_package(Qt6Qml)

The Qt bug 109547 describes exactly this error and gives two workarounds. The first workaround makes the cuteradio depend on qtdeclarative-native:

DEPENDS += "qtbase qtdeclarative qtdeclarative-native qtmultimedia"

It works. The second workaround is cleaner but takes a bit more time. It suggests to set

QT_ALLOW_MISSING_TOOLS_PACKAGES=ON 

when configuring Qt. I'll wait until this fix finds its way into meta-qt6.

The build succeeds and weston starts fine after power-up, but the cuteradio doesn't start. Starting cuteradio manually on the device fails:

root@verdin-imx8mp:~# WAYLAND_DISPLAY=/run/wayland-0 QT_QPA_PLATFORM=wayland-egl /usr/bin/cuteradio 
Detected locale "C" with character encoding "ANSI_X3.4-1968", which is not UTF-8.
Qt depends on a UTF-8 locale, but has failed to switch to one.
If this causes problems, reconfigure your locale. See the locale(1) manual
for more information.
qt.core.plugin.loader: In /usr/lib/plugins/platforms/libqwayland-egl.so:
  Plugin uses incompatible Qt library (5.15.0) [release]
qt.core.plugin.loader: In /usr/lib/plugins/platforms/libqwayland-generic.so:
  Plugin uses incompatible Qt library (5.15.0) [release]
qt.qpa.plugin: Could not find the Qt platform plugin "wayland-egl" in ""
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: vnc, offscreen, minimal, minimalegl, vkkhrdisplay, eglfs.

Aborted

Checking with ldd shows that libqwayland-egl.so and libqwayland-generic.so, indeed, depend on Qt5 libraries:

root@verdin-imx8mp:~# ldd /usr/lib/plugins/platforms/libqwayland-egl.so
    linux-vdso.so.1 (0x0000ffff95eb6000)
    libQt5WaylandClient.so.5 => /usr/lib/libQt5WaylandClient.so.5 (0x0000ffff95d10000)
    libQt5Gui.so.5 => not found
    libQt5Core.so.5 => not found

Why does libQt5WaylandClient end up in the image with a Qt 6 build?!

root@verdin-imx8mp:~# ls /usr/lib/libQt5*
/usr/lib/libQt5WaylandClient.so.5     /usr/lib/libQt5WaylandClient.so.5.15.7  /usr/lib/libQt5WaylandCompositor.so.5.15
/usr/lib/libQt5WaylandClient.so.5.15  /usr/lib/libQt5WaylandCompositor.so.5   /usr/lib/libQt5WaylandCompositor.so.5.15.7

The directory /usr/lib/ does not contain the Qt6 version libQt6WaylandClients.so.

builder@a8b936094d9f:/build$ oe-pkgdata-util find-path /usr/lib/libQt5WaylandClient.so.5.15.7 ERROR: Unable to find any package producing path /usr/lib/libQt5WaylandClient.so.5.15.7

The library libQt5WaylandClient.so.5.15.7 only occurs in the rootfs.

build-verdin-imx8mp/tmp/work$ find * -name "libQt5WaylandClient.so.5.15.7"
verdin_imx8mp-tdx-linux/smart-hmi-platform-image/1.0-r0/rootfs/usr/lib/libQt5WaylandClient.so.5.15.7

So, it looks a lot like a leftover from the meta-qt5 build. I built the image with a clean build directory - reusing the sstate and downloads directories. The Qt5 library is gone. cuteradio starts. It is not playing the radio station. But that's expected, because QtMultimedia uses ffmpeg instead of gstreamer for the first time. QtMultimedia has hardly ever worked out of the box for me.

So, meta-qt6 builds fine and runs with some multimedia problems.