This is how I cross-compiled Qt 5.15 including QtWebEngine for a Raspberry Pi 3 utilizing the default Broadcom graphics libraries supplied by RaspiOS. The whole graphics driver situation is quite complicated, and I will try to explain it below, but first, my step-by-step guide:


Preparing Qt Build

On Raspberry Pi

  1. Update the Pi. No need to rpi-update!
  2. Install dependencies
  3. Create directory for Qt
sudo apt update
sudo apt full-upgrade

sudo apt install libfontconfig1-dev libdbus-1-dev libnss3-dev libxkbcommon-dev libjpeg-dev libasound2-dev libudev-dev libgles2-mesa-dev

sudo mkdir /usr/local/qt5pi
sudo chown -R pi:pi /usr/local/qt5pi

The dependencies are:

fontconfigsupplies fonts for Qt
dbusinter-process communication
nssSSL and such
xkbcommonkeyboard handling
jpegwell, jpeg
asoundALSA. Only needed if you want sound.
udevmouse / keyboard hotplugging support.
gles2-mesaMesa version of the graphics drivers, including headers. I’ll get into this later.

On Host Machine

  1. Install dependencies
sudo apt-get install g++-multilib python pkg-config gperf bison flex libnss3-dev
  1. Install cross compilation toolchain
sudo mkdir /opt/raspiToolchains
sudo chown 1000:1000 /opt/raspiToolchains
cd /opt/raspiToolchains
wget https://releases.linaro.org/components/toolchain/binaries/7.5-2019.12/arm-linux-gnueabihf/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz
tar xf gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz
rm gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf.tar.xz

https://github.com/raspberrypi/tools is extremely outdated and uses gcc 4.8, so use one provided by linaro. Feel free to always pick the newest one, it should work just fine as C++ is rather strict on backwards compatibility.

  1. Create a build directory
sudo mkdir /opt/qt5pi
sudo chown 1000:1000 /opt/qt5pi
cd /opt/qt5pi
  1. Download symlink tool
wget https://raw.githubusercontent.com/riscv/riscv-poky/master/scripts/sysroot-relativelinks.py
chmod +x sysroot-relativelinks.py

This is just a handy tool by someone on Github that we will need later to turn absolute symbolic links into relative ones.

  1. Get the Qt source code
git clone https://github.com/qt/qt5.git
cd qt5
git checkout 5.15
./init-repository --module-subset=essential,qtwebengine

I prefer using the git repo over the qt-everywhere download because it is more modular and easier to update. When checking out a branch I prefer 5.15 over let’s say 5.15.0, because 5.15 will receive more/newer updates, and i.e. contain security patches for chromium earlier.

init-repository is a convenience tool provided by Qt to fetch the source code of the specified modules. The “super-repo” by itself is tiny, and everything else is kept as git submodules. Here we specify all essential modules and QtWebEngine to be downloaded. You can read up on all available modules here and find out more about the tool with init-repository --help or here.


Qt Build (or Update)

Run these steps next or every time you want to update your Qt.

On Host Machine

  1. Get the (updated) sysroot from your Pi and make symlinks relative
cd /opt/qt5pi/
rsync -avzR pi@192.168.1.101:/lib :/usr/include :/usr/lib :/usr/share/pkgconfig/ :/opt/vc  sysroot
./sysroot-relativelinks.py sysroot

This will copy the specified directories from your Pi over the network into a directory called sysroot. These contain libraries, headers and pkg-config files we will need later.

  1. Update Qt source code (unless you just got it)
cd /opt/qt5pi/qt5

(a) I want to stay in the same branch (5.15) and pull more recent changes:
	git pull
	git submodule update --recursive
(b) I want to switch to a new branch:
	git fetch
	git checkout 5.15
	git submodule update --recursive
(c) Normally some specific commit of QtWebEngine is selected in the super repository. 
If I want one newer than this, I have to checkout a branch of qtwebengine:
	git fetch
	cd qtwebengine
	git checkout 5.15
	git submodule update
(d) If I already did checkout a branch for which there are newer commits:
	cd qtwebengine
	git pull
	git submodule update
  1. Configure Qt Essentials
cd /opt/qt5pi/qt5/qtbase/mkspecs/devices
cp -r linux-rasp-pi3-g++/ linux-rasp-pi3-brcm-g++/
nano linux-rasp-pi3-brcm-g++/qmake.conf

You will need to customize qmake.conf. This file defines some settings for compilation and is a modification of the one provided by Qt. It should look like this:

# qmake configuration for the Raspberry Pi 3 using the Broadcom graphics stack
# MODIFIED to use the library names that are shipped since 2016
#
# Also setting the linker flags according to the pkg-config files that are shipped with the libraries.
# Remove egl.pc and glesv2.pc from /usr/lib/arm-linux-gnueabihf/pkgconfig/ for these to take effect.
# The reason for using static values instead of supplying the correct pkg-config files is that configure ignores -pthread from there
#
# Including headers from /opt/vc first, but also from mesa version of EGL and GLES, since the /opt/vc headers are from 2009 and don't work with qtwebengine.
# This way you can make mesa headers available by manually removing directories EGL, GLES and GLES2 from /opt/vc/include before building.

include(../common/linux_device_pre.conf)

# Let the linker know about /opt/vc/lib. Required for EGL config.test (at least) because brcmGLESv2 also needs brcmEGL.
QMAKE_RPATHLINKDIR_POST += $$[QT_SYSROOT]/opt/vc/lib

VC_LIBRARY_PATH         = $$[QT_SYSROOT]/opt/vc/lib
VC_INCLUDE_PATH         = $$[QT_SYSROOT]/opt/vc/include
MESA_INCLUDE_PATH	= $$[QT_SYSROOT]/usr/include

QMAKE_LIBDIR_OPENGL_ES2 = $${VC_LIBRARY_PATH}
QMAKE_LIBDIR_EGL        = $$QMAKE_LIBDIR_OPENGL_ES2
QMAKE_LIBDIR_OPENVG     = $$QMAKE_LIBDIR_OPENGL_ES2
QMAKE_LIBDIR_BCM_HOST   = $$VC_LIBRARY_PATH

QMAKE_INCDIR_EGL        = \
                        $${VC_INCLUDE_PATH} \
                        $${MESA_INCLUDE_PATH} \
                        $${VC_INCLUDE_PATH}/interface/vcos/pthreads \
                        $${VC_INCLUDE_PATH}/interface/vmcs_host/linux
QMAKE_INCDIR_OPENGL_ES2 = $${QMAKE_INCDIR_EGL}
QMAKE_INCDIR_BCM_HOST   = $$VC_INCLUDE_PATH

# recreating pkg-config --libs glesv2
QMAKE_LIBS_OPENGL_ES2   = -L$${VC_LIBRARY_PATH} -lbrcmGLESv2 -lbcm_host -lvcos -lvchiq_arm -pthread
# recreating pkg-config --libs egl
QMAKE_LIBS_EGL          = -L$${VC_LIBRARY_PATH} -lbrcmEGL -lbrcmGLESv2 -lbcm_host -lvchostif -lbcm_host -lvcos -lvchiq_arm -pthread
#recreating pkg-config --libs bcm_host
QMAKE_LIBS_BCM_HOST     = -L$${VC_LIBRARY_PATH} -lbcm_host -lvcos -lvchiq_arm -pthread

QMAKE_CFLAGS            = -march=armv8-a -mtune=cortex-a53 -mfpu=crypto-neon-fp-armv8
QMAKE_CXXFLAGS          = $$QMAKE_CFLAGS

DISTRO_OPTS            += hard-float
DISTRO_OPTS            += deb-multi-arch

EGLFS_DEVICE_INTEGRATION= eglfs_brcm

include(../common/linux_arm_device_post.conf)

load(qt_config)

Qt uses pkg-config to determine whether some library is installed (on the Pi) and where. Actually, there usually are multiple methods, the last of which is using the static definitions from qmake.conf we just set. So we need to remove the .pc files so configure falls back on our definitions instead of using the (mesa) defaults.

cd /opt/qt5pi/sysroot/usr/lib/arm-linux-gnueabihf/pkgconfig/
mv egl.pc egl.pc.mesa
mv glesv2.pc glesv2.pc.mesa

cd /opt/qt5pi
mkdir build
cd build

Now we are ready to configure Qt for build, that is everything but QtWebEngine for now (detailed explanation on the right):

../qt5/configure \
-opengl es2 -device linux-rasp-pi3-brcm-g++ \
-device-option CROSS_COMPILE=/opt/raspiToolchains/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf- \
-sysroot /opt/qt5pi/sysroot \
-prefix /usr/local/qt5pi \
-extprefix /opt/qt5pi/targetBinaries \
-hostprefix /opt/qt5pi/hostBinaries \
-opensource -confirm-license \
-release -v \
-nomake examples \
-no-use-gold-linker \
-recheck-all \
-skip qtwebengine \
2>&1 | tee ../configure$(date +"%Y-%m-%d_%H-%M").log
>run the configure tool
>using our qmake.conf

>with this compiler/toolchain
(adjust the path to yours)

>look for the sysroot here
>this will later be the path on the Pi
>put binaries destined for the Pi here
>put binaries only used by the host machine here
>use the opensource Qt variant
>release build, verbose logs
>only build libraries
>gold linker won't work
>if we re-run this later, redo all test cases
>don't build QtWebEngine – for now
>write everything to logfile

Check the output. My config summary looked like this.

  1. Build Qt Essentials

Now we are ready to build. The make step will take ~0.5h.

make -j4 2>&1 | tee ../make$(date +"%Y-%m-%d_%H-%M").log
make install 2>&1 | tee ../install$(date +"%Y-%m-%d_%H-%M").log
  1. Configure QtWebEngine

To successfully build QtWebEngine, the Broadcom libraries shipped with the Pi are too old – they are missing GLES3 support, for example. So we need to make sure the Mesa headers are found instead. (This is rather hacky, I’ll explain below.)
Also the build needs to happen in a separate directory.

cd /opt/qt5pi/sysroot/opt/vc/include
mv EGL EGL_brcm
mv GLES GLES_brcm
mv GLES2 GLES2_brcm

mkdir /opt/qt5pi/buildWebengine
cd /opt/qt5pi/buildWebengine
../hostBinaries/bin/qmake ../qt5/qtwebengine/ -- \
-webengine-pepper-plugins -webengine-proprietary-codecs -v \
2>&1 | tee ../configWebengine$(date +"%Y-%m-%d_%H-%M").log

Pepper Plugins is needed to load Widevine later, and the codecs are needed to play media. You don’t have to build those.
Check the output again. Mine looked like this.

  1. Build QtWebEngine

Now we are ready to build QtWebEngine. The make step will take ~4h.

make -j4 2>&1 | tee ../makeWebengine$(date +"%Y-%m-%d_%H-%M").log
make install 2>&1 | tee ../installWebengine$(date +"%Y-%m-%d_%H-%M").log
  1. Upload to Pi
rsync -avz /opt/qt5pi/targetBinaries/ pi@192.168.1.101:/usr/local/qt5pi/

Trailing slashes are important!


If you got this far, congratulations! You should have a fully functioning Qt library installed on your Raspberry Pi. I’ll quickly go into how to set up Qt Creator to comfortably cross-compile and deploy an application over the network.

Setting up Qt Creator

Go to the Projects tab and select Manage Kits….
Select the Qt Versions header and add a new version by selecting the qmake you just compiled (/opt/qt5pi/hostBinaries/bin/qmake).

Go to the Compiler header and add a new “GCC” for C and C++.
For C++, the compiler path is /opt/raspiToolchains/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++, and I named it G++ RasPi Cross 7.5.0 (Linaro).
For C, the compiler path is /opt/raspiToolchains/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc, and I named it GCC RasPi Cross 7.5.0 (Linaro).

In the Devices tab, set up your Pi as a new “Generic Linux Device”. You will be asked for your Pi’s IP and a username.

Back in the Kits tab, go to the Kits header and set up a new kit. I’ll call it RasPi Cross 5.15. Select the compilers (C and C++) and the Qt version you just set up. The Device Type is Generic Linux Device and then select the device you just created.

Now activate the kit you just created. Finally, make sure your projects .pro file contains the following lines:

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /home/pi/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

Now you should be able to build your project. When you hit run, Qt Creator will upload the compiled project to your Pi, run it and pipe the console output back to you. Amazing!


The Graphics Library Situation

The Raspberry Pi 3 ships with a proprietary graphics driver from the chip vendor Broadcom enabled by default. For what we are concerned, it consists of libraries for EGL (Embedded Graphics Library) and GLES (OpenGL for Embedded Systems) and can be found at /opt/vc/lib/ as libbrcmEGL.so and libbrcmGLESv2.so.

Alternatively, there exists another version, an open-source implementation by Mesa. This is what we installed earlier with libgles2-mesa-dev. These are located at /usr/lib/arm-linux-gnueabihf/ as libEGL.so and libGLESv2.so.

As you can see, they are named a little differently. This goes back to this decision from 2016, if you are courious. Many people seem to be unhappy with the decision to use non-standard names, but this is just the way it is.
Unless you run rpi-update at some point. Updating the firmware actually brings back the library with the standard names in the same folder. They appear to be identical. I literally have no idea why this decision was made, but in a way this means we have to deal with three different versions of the library.

These libraries also come with header files used to build software that uses them. Conveniently, these contain the date of their revision:

Broadcom (/opt/vc/include/EGL/eglext.h)

/* Header file version number */
/* Current version at http://www.khronos.org/registry/egl/ */
/* $Revision: 7244 $ on $Date: 2009-01-20 17:06:59 -0800 (Tue, 20 Jan 2009) $ */

Mesa (/usr/include/EGL/eglext.h)

/*
** This header is generated from the Khronos EGL XML API Registry.
** The current version of the Registry, generator scripts
** used to make the header, and the header can be found at
**   http://www.khronos.org/registry/egl
**
** Khronos $Git commit SHA1: cb927ca98d $ on $Git commit date: 2019-08-08 01:05:38 -0700 $
*/

The VC headers are from 2009 and are missing, among other things, EGLSetBlobFuncANDROID, just to name an example. Also GLESv2 is missing the entire folder GLES3/. So basically, this collection of headers is useless for building something like chromium which will inevitably call some of the newer definitions.

Luckily, I found out you can just swap in the newer headers from Mesa whilst still building with and linking against the Broadcom drivers, and this is what’s happening in instruction step 13. This might of course be subject to change, but at the time of writing it works! Of course, if chromium were to actually use any of the new functions advertised in these headers, it would run into issues. I have not spotted any major problems with this so far, however. Chromium is spamming some error messages sometimes which might be related to this, but they don’t seem to affect anything.

So, using the steps I layed out, you can compile QtBase and the rest of Qt’s essential modules and link them against the default Broadcom libraries, and then link QtWebEngine against some newer version of the library’s headers. This way, you can keep using the graphics driver that is enabled in RaspiOS by default and still use Qt with QtWebEngine!

I might look into switching to the Mesa drivers entirely at some point in the future. 🙂 Until then, you’ll almost certainly find tutorials using the Mesa drivers elsewhere.

References

I’d like to point you to some of the websites, blogs and tutorials that helped me get this far. If you are stuck, maybe you’ll find some useful information there! Plus, I’m really glad these exist, because otherwise I probably would not have figured this out, so they definitely deserve a shoutout!

https://www.raspberrypi.org/forums/viewtopic.php?t=204778
https://ottycodes.wordpress.com/2019/02/21/cross-compiling-qt5-12-for-raspberry-pi3/
https://wiki.qt.io/RaspberryPi2EGLFS
https://wiki.qt.io/RaspberryPiWithWebEngine
https://www.tal.org/tutorials/building-qt-512-raspberry-pi
https://mechatronicsblog.com/cross-compile-and-deploy-qt-5-12-for-raspberry-pi/
http://www.bildungsgueter.de/RaspberryIntro/Pages/GPULibs001.htm

https://github.com/UvinduW/Cross-Compiling-Qt-for-Raspberry-Pi-4 [Thanks to Manish Buttan for this link; RPi4 and no QTWebEngine, but otherwise well-structured and up-to-date]

37 Thoughts on “Cross Compiling Qt 5.15 (with QtWebEngine) for Raspberry Pi 3

  1. Nice tutorial, thanks!

  2. Hello friend, very very nice tutorial, the only one i found working !!!

  3. hi after i run
    (((make -j4 2>&1 | tee ../makeWebengine$(date +”%Y-%m-%d_%H-%M”).log
    make install 2>&1 | tee ../installWebengine$(date +”%Y-%m-%d_%H-%M”).log)))
    i got noting to be done for install and i tried steps two times even update-upgrade still qt wont install

    • Hi amir!
      I would guess your build (the “make” command) has failed, so “make install” has nothing to do.
      Have you checked the build log (makeWebengineXXX.log) for errors? You should be able to find which component caused your problems there and get some idea where to look further.

  4. hi help pls getting this error
    ninja: build stopped: subcommand failed.
    make[3]: *** [Makefile.gn_run:365: run_ninja] Error 1
    make[3]: Leaving directory ‘/opt/qt5pi/buildWebengine/src/core’
    make[2]: *** [Makefile:82: sub-gn_run-pro-make_first] Error 2
    make[2]: Leaving directory ‘/opt/qt5pi/buildWebengine/src/core’
    make[1]: *** [Makefile:79: sub-core-make_first] Error 2
    make[1]: Leaving directory ‘/opt/qt5pi/buildWebengine/src’
    make: *** [Makefile:49: sub-src-make_first] Error 2

    • Hi john!
      ninja is chromium’s build system. What you posted just means *something* has failed in your build. You have to look further up in your build log to find out what’s the root cause. Maybe search for “error”, “fail”, … in your makeXXX.log. Usually there are C++ compiler errors somewhere and you can find some hints by googling those. Maybe some dependency is missing or something like that.

  5. hi
    i got error when trying make -j4…….>>>buildwebengine/src
    Please submit a full bug report,
    with preprocessed source if appropriate.
    See for instructions.
    ninja: build stopped: subcommand failed.
    make[2]: *** [Makefile.gn_run:367: run_ninja] Error 1
    make[2]: Leaving directory ‘/opt/qt5pi/buildWebengine/src/core’
    make[1]: *** [Makefile:82: sub-gn_run-pro-make_first] Error 2
    make[1]: Leaving directory ‘/opt/qt5pi/buildWebengine/src/core’
    make: *** [Makefile:79: sub-core-make_first] Error 2

    how fix it:(

    • Hi amir!
      ninja is chromium’s build system. What you posted just means *something* has failed in your build. You have to look further up in your build log to find out what’s the root cause. Maybe search for “error”, “fail”, … in your makeXXX.log. Usually there are C++ compiler errors somewhere and you can find some hints by googling those. Maybe some dependency is missing or something like that.

      • i try ro run make with sudo but still got same error
        i try to google it but didnt find anything
        Fatal error: can’t create obj/third_party/boringssl/boringssl/poly1305_arm.o: Permission denied

        • I’m not sure I can help you mate. Carefully double-check that your configure summary looks ok (I linked mine above for comparison), that you are in the correct directory, have write permission, have all dependencies installed and followed every step correctly.
          From the line you gave me I can just tell you that SSL didn’t build correctly. You need to find out why you don’t have permission to create the file in question. Maybe make sure the /opt/qt5pi/ folder and all subfolders are owned by your user and not root or someone else. Running stuff as sudo might have broken your permissions.
          If there are still errors remaining, it’s not going to be easy and will require some research and trial&error on your own.

  6. Friedemann on 11. October 2020 at 17:40 said:

    Hey thanks a lot! Unfortunately I can’t build the webengine… it fails with an “internal compiler error”
    I followed yout tutorial step by step with a fresh ubuntu vm and a brand new raspberryOS image.
    Do you have any idea what’s going wrong here? Thanks a lot!

    FAILED: obj/skia/skia_core_and_effects/SkOverdrawCanvas.o
    /opt/raspiToolchains/gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ -MMD -MF obj/skia/skia_core_and_effects/SkOverdrawCanvas.o.d -DUSE_UDEV -DUSE_AURA=1 -DUSE_NSS_CERTS=1 -DUSE_OZONE=1 -DOFFICIAL_BUILD -DTOOLKIT_QT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DNO_UNWIND_TABLES -DCR_SYSROOT_HASH=3fcc1d4e44127006318371002a0f421a4fde2ab4 -DNDEBUG -DNVALGRIND -DDYNAMIC_ANNOTATIONS_ENABLED=0 -DSK_CODEC_DECODES_PNG -DSK_CODEC_DECODES_WEBP -DSK_ENCODE_PNG -DSK_ENCODE_WEBP -DSK_USER_CONFIG_HEADER=\”../../skia/config/SkUserConfig.h\” -DSK_GL -DSK_CODEC_DECODES_JPEG -DSK_ENCODE_JPEG -DSK_USE_LIBGIFCODEC -DSK_VULKAN_HEADER=\”../../skia/config/SkVulkanConfig.h\” -DSK_VULKAN=1 -DSK_SUPPORT_GPU=1 -DSK_GPU_WORKAROUNDS_HEADER=\”gpu/config/gpu_driver_bug_workaround_autogen.h\” -DVK_NO_PROTOTYPES -DSKIA_IMPLEMENTATION=1 -DSK_ARM_HAS_NEON -DSK_GAMMA_EXPONENT=1.2 -DSK_GAMMA_CONTRAST=0.2 -DSK_DEFAULT_FONT_CACHE_LIMIT=20971520 -Igen -I../../../../qt5/qtwebengine/src/3rdparty/chromium -I../../../../qt5/qtwebengine/src/3rdparty/chromium/third_party/skia -I../../../../qt5/qtwebengine/src/3rdparty/chromium/third_party/libgifcodec -I../../../../qt5/qtwebengine/src/3rdparty/chromium/third_party/vulkan/include -I../../../../qt5/qtwebengine/src/3rdparty/chromium/third_party/skia/third_party/vulkanmemoryallocator -I../../../../qt5/qtwebengine/src/3rdparty/chromium/third_party/vulkan/include -fno-strict-aliasing –param=ssp-buffer-size=4 -fstack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fPIC -pipe -pthread -march=armv8-a -mfloat-abi=hard -mtune=cortex-a53 -mfpu=neon -mthumb -fno-omit-frame-pointer -g0 -fvisibility=hidden -O2 -fno-ident -fdata-sections -ffunction-sections -Wno-psabi -Wno-unused-local-typedefs -Wno-maybe-uninitialized -Wno-deprecated-declarations -fno-delete-null-pointer-checks -Wno-comments -Wno-packed-not-aligned -Wno-dangling-else -Wno-missing-field-initializers -Wno-unused-parameter -std=c++17 -std=gnu++14 -fno-exceptions -fno-rtti –sysroot=../../../../sysroot -fvisibility-inlines-hidden -std=c++17 -Wno-narrowing -Wno-class-memaccess -Wno-attributes -Wno-class-memaccess -Wno-subobject-linkage -Wno-invalid-offsetof -Wno-return-type -Wno-deprecated-copy -c ../../../../qt5/qtwebengine/src/3rdparty/chromium/third_party/skia/src/core/SkOverdrawCanvas.cpp -o obj/skia/skia_core_and_effects/SkOverdrawCanvas.o
    In file included from ../../../../qt5/qtwebengine/src/3rdparty/chromium/third_party/skia/src/core/SkGlyph.h:16:0,
    from ../../../../qt5/qtwebengine/src/3rdparty/chromium/third_party/skia/src/core/SkGlyphBuffer.h:12,
    from ../../../../qt5/qtwebengine/src/3rdparty/chromium/third_party/skia/src/core/SkGlyphRunPainter.h:13,
    from ../../../../qt5/qtwebengine/src/3rdparty/chromium/third_party/skia/src/core/SkOverdrawCanvas.cpp:19:
    ../../../../qt5/qtwebengine/src/3rdparty/chromium/third_party/skia/include/private/SkVx.h:559:76: interner Compiler-Fehler: in instantiate_decl, bei cp/pt.c:22741
    bit_pun(e)));
    ^

  7. Friedemann on 11. October 2020 at 18:38 said:

    Solved the “internal compiler error” mentioned in my post with the given solution here: https://bugzilla.redhat.com/show_bug.cgi?id=1848011

    Hope this will help somebody 😉

  8. Manish Buttan on 29. October 2020 at 13:56 said:

    Hello, Thanks for this tutorial. Everything seems to work fine, but I am getting this error when I run the app on the RPi from Qt on Ubuntu:

    QML debugging is enabled. Only use this in a safe environment.
    qt.qpa.plugin: Could not find the Qt platform plugin “xcb” in “”
    * failed to add service – already in use?

    Any advice?

    • Manish+Buttan on 29. October 2020 at 14:16 said:

      Got this message when I ran with export QT_DEBUG_PLUGINS=1

      QFactoryLoader::QFactoryLoader() checking directory path “/home/pi/InstagoQt/bin/egldeviceintegrations” …
      loaded library “/usr/local/qt5pi/plugins/egldeviceintegrations/libqeglfs-brcm-integration.so”
      * failed to add service – already in use?

    • Hi,
      I think I remember having this issue. First, make sure you have selected the right GL driver in raspi-config. Remember, in this tutorial I use the Broadcom (‘Legacy’) driver.
      Then, whenever you do switch your driver, the memory split gets reset. You should play with the exact value yourself, but start with setting 256MB of RAM towards the GPU in raspi-config and try again! 🙂

      If that doesn’t help, maybe double-check if your configure.log looks alright – I have linked mine above.
      Other tricks in my debugging arsenal:
      – Try if it makes a difference if you run your executable from your Pi’s console. It should be located in the home directory.
      – Use ‘ldd yourExecutable’ on your Pi to check if all required libraries are found, and found in the right places. Possibly use ‘sudo ldconfig’ to update your let’s call it ‘library cache’.

      Good luck!

      • Manish+Buttan on 30. October 2020 at 05:13 said:

        Thank you for your reply. I actually copy pasted every single step from your article by yet I am getting a different output on configure compared to yours. I have pasted it below. Can you please let me know what I am doing wrong?

        Configure summary:

        Building on: linux-g++ (x86_64, CPU features: mmx sse sse2)
        Building for: devices/linux-rasp-pi3-brcm-g++ (arm, CPU features: neon)
        Target compiler: gcc 7.5.0
        Configuration: cross_compile compile_examples enable_new_dtags largefile neon precompile_header shared shared rpath release c++11 c++14 c++17 c++1z concurrent dbus reduce_exports stl
        Build options:
        Mode …………………………….. release
        Optimize release build for size …….. no
        Building shared libraries ………….. yes
        Using C standard ………………….. C11
        Using C++ standard ………………… C++17
        Using ccache ……………………… no
        Using new DTAGS …………………… yes
        Relocatable ………………………. yes
        Using precompiled headers ………….. yes
        Using LTCG ……………………….. no
        Target compiler supports:
        NEON …………………………… yes
        Build parts ………………………. libs
        Qt modules and options:
        Qt Concurrent …………………….. yes
        Qt D-Bus …………………………. yes
        Qt D-Bus directly linked to libdbus …. yes
        Qt Gui …………………………… yes
        Qt Network ……………………….. yes
        Qt Sql …………………………… yes
        Qt Testlib ……………………….. yes
        Qt Widgets ……………………….. yes
        Qt Xml …………………………… yes
        Support enabled for:
        Using pkg-config ………………….. yes
        udev …………………………….. yes
        Using system zlib …………………. yes
        Zstandard support …………………. no
        Qt Core:
        DoubleConversion ………………….. yes
        Using system DoubleConversion …….. no
        GLib …………………………….. yes
        iconv ……………………………. no
        ICU ……………………………… yes
        Built-in copy of the MIME database ….. yes
        Tracing backend ……………………
        Logging backends:
        journald ……………………….. no
        syslog …………………………. no
        slog2 ………………………….. no
        PCRE2 ……………………………. yes
        Using system PCRE2 ………………. no
        Qt Network:
        getifaddrs() ……………………… yes
        IPv6 ifname ………………………. yes
        libproxy …………………………. no
        Linux AF_NETLINK ………………….. yes
        OpenSSL ………………………….. yes
        Qt directly linked to OpenSSL …….. no
        OpenSSL 1.1 ………………………. yes
        DTLS …………………………….. yes
        OCSP-stapling …………………….. yes
        SCTP …………………………….. no
        Use system proxies ………………… yes
        GSSAPI …………………………… no
        Qt Gui:
        Accessibility …………………….. yes
        FreeType …………………………. yes
        Using system FreeType ……………. yes
        HarfBuzz …………………………. yes
        Using system HarfBuzz ……………. yes
        Fontconfig ……………………….. yes
        Image formats:
        GIF ……………………………. yes
        ICO ……………………………. yes
        JPEG …………………………… yes
        Using system libjpeg …………… yes
        PNG ……………………………. yes
        Using system libpng ……………. yes
        Text formats:
        HtmlParser ……………………… yes
        CssParser ………………………. yes
        OdfWriter ………………………. yes
        MarkdownReader ………………….. yes
        Using system libmd4c …………… no
        MarkdownWriter ………………….. yes
        EGL ……………………………… yes
        OpenVG …………………………… no
        OpenGL:
        Desktop OpenGL ………………….. no
        OpenGL ES 2.0 …………………… yes
        OpenGL ES 3.0 …………………… no
        OpenGL ES 3.1 …………………… no
        OpenGL ES 3.2 …………………… no
        Vulkan …………………………… yes
        Session Management ………………… yes
        Features used by QPA backends:
        evdev ……………………………. yes
        libinput …………………………. yes
        INTEGRITY HID …………………….. no
        mtdev ……………………………. yes
        tslib ……………………………. yes
        xkbcommon ………………………… yes
        X11 specific:
        XLib …………………………… yes
        XCB Xlib ……………………….. yes
        EGL on X11 ……………………… yes
        xkbcommon-x11 …………………… no
        QPA backends:
        DirectFB …………………………. no
        EGLFS ……………………………. yes
        EGLFS details:
        EGLFS OpenWFD …………………… no
        EGLFS i.Mx6 …………………….. no
        EGLFS i.Mx6 Wayland ……………… no
        EGLFS RCAR ……………………… no
        EGLFS EGLDevice …………………. yes
        EGLFS GBM ………………………. no
        EGLFS VSP2 ……………………… no
        EGLFS Mali ……………………… no
        EGLFS Raspberry Pi ………………. yes
        EGLFS X11 ………………………. yes
        LinuxFB ………………………….. yes
        VNC ……………………………… yes
        Qt Sql:
        SQL item models …………………… yes
        Qt Widgets:
        GTK+ …………………………….. no
        Styles …………………………… Fusion Windows
        Qt PrintSupport:
        CUPS …………………………….. yes
        Qt Sql Drivers:
        DB2 (IBM) ………………………… no
        InterBase ………………………… no
        MySql ……………………………. no
        OCI (Oracle) ……………………… no
        ODBC …………………………….. yes
        PostgreSQL ……………………….. yes
        SQLite2 ………………………….. yes
        SQLite …………………………… yes
        Using system provided SQLite ……… no
        TDS (Sybase) ……………………… yes
        Qt Testlib:
        Tester for item models …………….. yes
        Qt QML:
        QML network support ……………….. yes
        QML debugging and profiling support …. yes
        QML just-in-time compiler ………….. yes
        QML sequence object ……………….. yes
        QML XML http request ………………. yes
        QML Locale ……………………….. yes
        Qt QML Models:
        QML list model ……………………. yes
        QML delegate model ………………… yes
        Qt Quick:
        Direct3D 12 ………………………. no
        AnimatedImage item ………………… yes
        Canvas item ………………………. yes
        Support for Qt Quick Designer ………. yes
        Flipable item …………………….. yes
        GridView item …………………….. yes
        ListView item …………………….. yes
        TableView item ……………………. yes
        Path support ……………………… yes
        PathView item …………………….. yes
        Positioner items ………………….. yes
        Repeater item …………………….. yes
        ShaderEffect item …………………. yes
        Sprite item ………………………. yes
        Qt Quick Controls 2:
        Styles …………………………… Default Fusion Imagine Material Universal
        Qt Quick Templates 2:
        Hover support …………………….. yes
        Multi-touch support ……………….. yes
        Qt Multimedia:
        ALSA …………………………….. yes
        GStreamer 1.0 …………………….. no
        GStreamer 0.10 ……………………. no
        Video for Linux …………………… yes
        OpenAL …………………………… no
        PulseAudio ……………………….. no
        Resource Policy (libresourceqt5) ……. no
        Windows Audio Services …………….. no
        DirectShow ……………………….. no
        Windows Media Foundation …………… no
        Qt Tools:
        Qt Assistant ……………………… yes
        Qt Designer ………………………. yes
        Qt Distance Field Generator ………… yes
        kmap2qmap ………………………… yes
        Qt Linguist ………………………. yes
        Mac Deployment Tool ……………….. no
        makeqpf ………………………….. yes
        pixeltool ………………………… yes
        qdbus ……………………………. yes
        qev ……………………………… yes
        Qt Attributions Scanner ……………. yes
        qtdiag …………………………… yes
        qtpaths ………………………….. yes
        qtplugininfo ……………………… yes
        Windows deployment tool ……………. no
        WinRT Runner Tool …………………. no
        Qt Tools:
        QDoc …………………………….. yes

        Note: Also available for Linux: linux-clang linux-icc

        Note: PKG_CONFIG_LIBDIR automatically set to /opt/qt5pi/sysroot/usr/lib/pkgconfig:/opt/qt5pi/sysroot/usr/share/pkgconfig:/opt/qt5pi/sysroot/usr/lib/arm-linux-gnueabihf/pkgconfig

        Note: PKG_CONFIG_SYSROOT_DIR automatically set to /opt/qt5pi/sysroot

        Qt is now configured for building. Just run ‘make’.
        Once everything is built, you must run ‘make install’.
        Qt will be installed into ‘/opt/qt5pi/targetBinaries’.

        Prior to reconfiguration, make sure you remove any leftovers from
        the previous build.

        • Honestly, your configure.log looks fine… The critical bits, EGL, OpenGL ES 2.0 and EGLFS Raspberry Pi are ‘yes’, I see no problem there. If anything, you seem to be able to build more options than me, not less. Also your QT as well as your own code seem to build without any issues, which is a good sign.

          Now, the issue that remains is your line ‘* failed to add service – already in use?’. As I understand, everything above that is not related to this error and that is all the information available.
          I have a note saying I ran into this issue myself and was able to fix it by increasing my memory split, as I mentioned before.
          Other than that, I can only guess. Is there something else using your graphics system by any chance? Are you already running a RaspiOS image with a desktop environment instead of the Lite/Headless variant for example, or have you installed anything graphics-related on your image?
          Lastly, I cannot guarantee, of course, that something hasn’t changed in RaspiOS since the time of writing, but if starting over from a clean Raspberry Pi OS Lite image does not work for you (you should try that first), this is the image I used: ‘2020-05-27-raspios-buster-lite-armhf.img’. Maybe try that and work from there, if nothing else works.

          • Manish Buttan on 1. November 2020 at 07:49 said:

            Thank you for your reply. I guess I struggled with a lot of permutations and combinations and read several other articles about this. I know it may not be cool to paste another article link here, so I apologise in advance. This article seemed to work for me on my RPi4. The same article with the GL driver turned off allowed the same SD Card to work on my RPI 3.

            https://github.com/UvinduW/Cross-Compiling-Qt-for-Raspberry-Pi-4

            I guess I may have messed up my install somewhere along the line, or changed something, else everything you wrote would have worked perfectly.

            I appreciate your efforts in helping me out. Feel free to not post this comment on your group if you want. Thanks.

            • No worries, I’m glad you got it working in the end!
              That’s a neat guide I haven’t seen yet, and I’ll gladly link back to it, maybe it will help someone else! 🙂

              • Manish+Buttan on 2. November 2020 at 08:55 said:

                Thank you. Appreciate the spirit of open communication.

                I did have one more question for you if you could help:
                1. I need to install qtmqtt into the build. This module is part of the automation package. I have been able to download it and build it on my desktop and it works perfectly. I am confused about how to build it to the RPI. Any suggestion would be appreciated:
                – Path to qtmqtt – https://github.com/qt/qtmqtt
                – This link helped me build it for desktop – https://stackoverflow.com/questions/48701475/qt-creator-adding-mqtt-library

                Where is the Qt build make of RPI with cross compile? If I build it there, how to I sync it to my desktop for cross compile? Thanks

                • Manish+Buttan on 2. November 2020 at 10:40 said:

                  You can ignore the questions above as I got mqtt to work on the rpi. It was as simple as downloading qtmqtt from git and using the qmake from Qt to build and then rsync the qt folder.

                  I actually had another question. The Qt integration with RPI works well. I am able to build it and run it on RPi using Qt Run button. But the app does not load up no the RPi. It deploys it correctly, and I am able to go to RPi and run the app, and it works perfectly. On the Qt side, as soon as it deploys it, it gives and error Remote Process Crashed. Any ideas how to make it actually work, so I can debug the app on the RPi?

                  • Okay, that just worked for me out of the box…
                    Have you added the lines to your .pro file as I described in the “Setting up Qt Creator” section?
                    Are you logging into ssh with the same user as you let Qt Creator log in with? Because then, they should even have the same permissions…
                    I found out here that something crashes with code 255 which might indicate an ssh error, so maybe check your firewall settings.
                    Last idea I have would be to check if you are actually running the same executable Qt Creator is trying to launch, or if there is somehow looking at an incorrect location or there are multiple versions deployed accidentally or something. Actually, that sounds the most plausible, Qt Creator issuing an ssh command to launch an executable that cannot be found.

                    Now that being said, I personally only tried the remote “Run”, I don’t think I ever used the actual remote debugger. But if I understand you correctly, you also struggle with the run button right now.

                    • Manish Buttan on 6. November 2020 at 15:51 said:

                      I am getting the following error when I hit the run (play) button in Qt creator to run the target on RPi3

                      Could not find DRM device!
                      20:10:45: Remote process crashed.

  9. Mohammad on 1. December 2020 at 05:36 said:

    Hi, very fine work. thanks.
    one question though, why we want to build against Broadcom EGL graphics library? Why we dont just use Mesa and fix relative links at the end?
    It seems that you have used Mesa headers with Broadcom libs. But why we dont use only Mesa libs and headers?

    • Hi,
      there is no reason we couldn’t build against the Mesa drivers. The Broadcom variant is just the first one I got working.
      I want to look into building against Mesa someday, too, but for now this works and its different from all other HowTo’s I found so far, which is why I posted it.
      That being said, it’s not as simple as just changing the symlinks as the libraries are not direclty exchangable. You can see in the configure.log that there are some features that are in place just to talk to the Broadcom drivers:
      EGL ……………………………… yes
      OpenVG …………………………… no
      OpenGL:
      Desktop OpenGL ………………….. no
      OpenGL ES 2.0 …………………… yes
      OpenGL ES 3.0 …………………… no
      OpenGL ES 3.1 …………………… no
      OpenGL ES 3.2 …………………… no
      Vulkan …………………………… no

      EGLFS ……………………………. yes
      EGLFS details:
      EGLFS OpenWFD …………………… no
      EGLFS i.Mx6 …………………….. no
      EGLFS i.Mx6 Wayland ……………… no
      EGLFS RCAR ……………………… no
      EGLFS EGLDevice …………………. no
      EGLFS GBM ………………………. no
      EGLFS VSP2 ……………………… no
      EGLFS Mali ……………………… no
      EGLFS Raspberry Pi ………………. yes
      EGLFS X11 ………………………. no

      Unfortunately, as I have not yet done a build using the Mesa drivers, I can’t tell you exactly what the differences are, neither in the configure process nor performancewise. But I think you will find plenty of tutorials on the internet if you need to go that route and use the Mesa drivers. That being said, using the Broadcom drivers works just fine for me 😉

  10. Hello! Thanks for this tutorial.
    What operating system did you have on the host machine?

  11. if u have an error u can use “make -i -k ‘ to skip errors about sub-module,s error qtwebengine

  12. Vitbas on 6. September 2021 at 07:36 said:

    Tell me how to fix on raspberry 3b + with a 7-inch display:

    Unable to query physical screen size, defaulting to 100 dpi.
    To override, set QT_QPA_EGLFS_PHYSICAL_WIDTH and QT_QPA_EGLFS_PHYSICAL_HEIGHT (in millimeters).

    • Hi! Everything should still work regardless of this message. I get it, too, it’s normal. 🙂
      It just means Qt assumes you run a 100dpi monitor, so some GUI elements might appear too big or too small on your actual display. Your 7-inch display probably has higher dpi. If it bothers you, you can try to set the two macros, but I have never done that myself.

  13. Diego Tamburini on 20. December 2021 at 14:29 said:

    Good morning,
    I failed many times in cross compiling qt-web engine with this error:

    [4/13058] /home/administrator/raspi/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -MMD -MF obj/third_party/zlib/bundled_zlib/deflate.o.d -DUSE_UDEV -DUSE_AURA=1 -DUSE_NSS_CERTS=1 -DUSE_OZONE=1 -DOFFICIAL_BUILD -DTOOLKIT_QT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DNO_UNWIND_TABLES -DCR_SYSROOT_HASH=3fcc1d4e44127006318371002a0f421a4fde2ab4 -DNDEBUG -DNVALGRIND -DDYNAMIC_ANNOTATIONS_ENABLED=0 -DZLIB_IMPLEMENTATION -DADLER32_SIMD_NEON -DINFLATE_CHUNK_SIMD_NEON -DCRC32_ARMV8_CRC32 -DARMV8_OS_LINUX -Igen -I../../3rdparty/chromium -I../../3rdparty/chromium/third_party/zlib -fno-strict-aliasing –param=ssp-buffer-size=4 -fstack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fPIC -pipe -pthread -march=armv8-a -mfloat-abi=hard -mtune=cortex-a53 -mfpu=neon -mthumb -O2 -fno-ident -fdata-sections -ffunction-sections -fno-omit-frame-pointer -g0 -fvisibility=hidden -Wno-psabi -Wno-unused-local-typedefs -Wno-maybe-uninitialized -Wno-deprecated-declarations -fno-delete-null-pointer-checks -Wno-comments -Wno-packed-not-aligned -Wno-dangling-else -Wno-missing-field-initializers -Wno-unused-parameter -std=gnu11 –sysroot=../../../../../../sysroot -c ../../3rdparty/chromium/third_party/zlib/deflate.c -o obj/third_party/zlib/bundled_zlib/deflate.o
    FAILED: obj/third_party/zlib/bundled_zlib/deflate.o
    /home/administrator/raspi/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -MMD -MF obj/third_party/zlib/bundled_zlib/deflate.o.d -DUSE_UDEV -DUSE_AURA=1 -DUSE_NSS_CERTS=1 -DUSE_OZONE=1 -DOFFICIAL_BUILD -DTOOLKIT_QT -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -DNO_UNWIND_TABLES -DCR_SYSROOT_HASH=3fcc1d4e44127006318371002a0f421a4fde2ab4 -DNDEBUG -DNVALGRIND -DDYNAMIC_ANNOTATIONS_ENABLED=0 -DZLIB_IMPLEMENTATION -DADLER32_SIMD_NEON -DINFLATE_CHUNK_SIMD_NEON -DCRC32_ARMV8_CRC32 -DARMV8_OS_LINUX -Igen -I../../3rdparty/chromium -I../../3rdparty/chromium/third_party/zlib -fno-strict-aliasing –param=ssp-buffer-size=4 -fstack-protector -fno-unwind-tables -fno-asynchronous-unwind-tables -fPIC -pipe -pthread -march=armv8-a -mfloat-abi=hard -mtune=cortex-a53 -mfpu=neon -mthumb -O2 -fno-ident -fdata-sections -ffunction-sections -fno-omit-frame-pointer -g0 -fvisibility=hidden -Wno-psabi -Wno-unused-local-typedefs -Wno-maybe-uninitialized -Wno-deprecated-declarations -fno-delete-null-pointer-checks -Wno-comments -Wno-packed-not-aligned -Wno-dangling-else -Wno-missing-field-initializers -Wno-unused-parameter -std=gnu11 –sysroot=../../../../../../sysroot -c ../../3rdparty/chromium/third_party/zlib/deflate.c -o obj/third_party/zlib/bundled_zlib/deflate.o
    In file included from ../../3rdparty/chromium/third_party/zlib/deflate.c:54:0:
    ../../3rdparty/chromium/third_party/zlib/contrib/optimizations/insert_string.h:58:42: error: attribute(target(“arch=armv8-a+crc”)) is unknown
    const Pos str) {
    ^~~~~
    cc1: warning: unrecognized command line option ‘-Wno-packed-not-aligned’

    These are my questions on the forum:

    https://forum.qt.io/topic/132894/cross-compile-qtwebengine-for-raspberry-3/4

    https://stackoverflow.com/questions/70377696/cross-compilation-qt-5-15-on-raspberry-pi3-with-qtwebengine?noredirect=1#comment124406726_70377696

    Could you please help me understanding where is my problem? Thanks, Diego

    • Hi Diego!

      There seems to be some error with zlib. That’s an third-party library for (de-)compression. I don’t immediately see what the problem is, but as a start, you can try disabling zlib altogether and try if the build works without it.
      To do this, add -no-zlib to your ./configure line, like described here: https://doc.qt.io/qt-5/configure-options.html#third-party-libraries
      If this works, then you know where your problem lies, and you can then search for solutions – if you even need zlib support.

      As you see in the linked article, Qt can use either the version of zlib shipped with Qt or the one already installed on your computer. This might be the origin of your problems, so in a second step, you could try using a different version of zlib. In my article, I link to the output of my configure script (in step 11 & 13), and there you can see I apparently used some zlib version installed on my system (“Using system zlib …………………. yes”).

  14. Hi there,
    I have encountered an issue compiling Qt 5.15.5 for RPiOS Buster on an RPi 3 A+. Basically, a whole bunch of stuff is failing to link correctly, apparently because of a mismatching librt version.
    It’s required by OpenGL ES2, EGLFS and other hardware-level Qt libs.

    As for the first two, I simply added ‘-lrt’ to the QMAKE_LIBS_OPENGL_ES2 and QMAKE_LIBS_EGL lines in the device config file.
    This allows the configure script to successfully get to the end of the OpenGL ES2 and EGLFS tests, making them available in the final config summary.

    But Qt5 still doesn’t compile… As far as I can tell, in a default config, the modules involved are QtSerialBus, QtSerialPort and QtTools (QtDbus, specifically). For my application, I don’t need any of those, so I’ve excluded them from the build.
    I’m not exactly sure where am I supposed to add eventual missing libraries for this scope, however. Any clue?

    Zago

    • Hi!
      That sounds a bit fiddly.
      First of all, Qt tries to find the required library options using the pkg-config utility, as I hinted at in my modification of the qmake.conf. So manually checking the output of pkg-config --libs ... might help you get to the core of the issue. Maybe trying to fetch the right library versions is the easiest way.

      I don’t quite understand the second part of your question, unfortunately. What I get is that you have removed some problematic modules from your configuration, but it still does not build successfully due to some missing libraries?
      Again, if that’s the case, the best way would be to fix you system so that (a) the correct libraries are present and (b) they are correctly reported using pkg-config – which might not always be the same thing.
      Without more insight on what’s failing for you, I can only point you to the other device config options documented here; or it might be a matter of digging through the qt source code repo (searching for keywords from the errors in your build log, for example), which is what I did when debugging.

Leave a Reply

Your email address will not be published. Required fields are marked *

Post Navigation