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
- Update the Pi. No need to
rpi-update
! - Install dependencies
- 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:
fontconfig | supplies fonts for Qt |
dbus | inter-process communication |
nss | SSL and such |
xkbcommon | keyboard handling |
jpeg | well, jpeg |
asound | ALSA. Only needed if you want sound. |
udev | mouse / keyboard hotplugging support. |
gles2-mesa | Mesa version of the graphics drivers, including headers. I’ll get into this later. |
On Host Machine
- Install dependencies
sudo apt-get install g++-multilib python pkg-config gperf bison flex libnss3-dev
- 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.
- Create a build directory
sudo mkdir /opt/qt5pi sudo chown 1000:1000 /opt/qt5pi cd /opt/qt5pi
- 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.
- 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
- 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.
- 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
- 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.
- 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
- 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.
- 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
- 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]
Nice tutorial, thanks!
Thank you! Yours was very helpful to me, too!
Hello friend, very very nice tutorial, the only one i found working !!!
Thank you, I’m glad you liked it!
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.
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.
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.
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)));
^
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 😉
Hi. I couldn’t figure out what to do. Can you explain more? thanks.
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?
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!
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.
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! 🙂
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
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.
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.
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 😉
Hello! Thanks for this tutorial.
What operating system did you have on the host machine?
Hi!
I was using Ubuntu, but any Linux distro should work 🙂
if u have an error u can use “make -i -k ‘ to skip errors about sub-module,s error qtwebengine
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.
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”).
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.
I done every step and meet this error. Can somebody help me ?
Error: The compiler “G++ Raspi Cross 7.5.0 (Linaro)” (x86-linux-generic-elf-64bit) cannot produce code for the Qt version “Qt 5.15.14 (hostBinaries)” (arm-linux-generic-elf-32bit).
Can you provide a bit more context? In which step do you get this error?
At first, it sounds like some mismatch between compilers, or maybe between 32bit and 64bit