Build Qt 5.11 for cross-compilation for RPi Zero

What do I have and what do I want to get?

I have several RPi Zero W with Raspbian Stretch Lite on it and want to develop Qt/QML application for it. It should be headless developing – I have and do not use monitor and/or keyboard on my Pi.

Since Qt/QML is my weapon of choice, I’d like to have all development+debug happen inside QtCreator (4.5.1). I want to be able do deploy over Wi-Fi.

Described method should work well for all RPi’s that has same architecture as RPi Zero. I suppose that you’ll get less problems with future Qt versions (e.g. 5.11.2+).

This is not intended for running desktop-style, windowed Qt apps under X11, but rather for the real embedded/device creation use case where the Qt app runs full-screen on top of dispmanx/EGL using the Broadcom drivers.

If you have any troubles connecting your RPi to your local network and basic software configuration on RPi, ensure you’ve already read official documentation Remote Access: IP address, Remote Access: SSH. If you got in troubles of connecting to unknown (yet) Wi-Fi – refer to my previous article.


This article is simplified merge of several articles. You can find list of used sources at the bottom of this article.

All this article is about how to set up the toolchain to be able to cross-compile code for the Raspberry Pi on the desktop development computer. While you can compile natively on a Raspberry Pi, a modern desktop computer is at least an order of magnitude faster and will quickly pay off in time saved.

Your Raspberry Pi will need to be reachable over the network by ssh. After completing all those steps you should now have a toolchain and the necessary files from the Raspberry Pi’s root filesystem to be able to cross-compile software for it.


Prepare RPi

Herein and after I’ll stick to numbering used in 2.

[on RPi] (optional) Run raspi-config, change it to boot to the console instead of X, change the GPU memory to 256 MB:

sudo raspi-config

[on RPi] For Raspbian Stretch you need also to update your RPi (see here):

sudo rpi-update
reboot

[on RPi] Install a bunch of development files (for simplicity we use build-dep, not everything is really needed, but it is easier this way).

Edit sources list in /etc/apt/sources.list with use of your favorite editor (nano/vim) and uncomment the deb-src line:

sudo nano /etc/apt/sources.list

Update your system and install required libraries:

sudo apt-get update
sudo apt-get build-dep qt4-x11
sudo apt-get build-dep libqt5gui5
sudo apt-get install libudev-dev libinput-dev libts-dev libxcb-xinerama0-dev libxcb-xinerama0

[on RPi] Prepare our target directory

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

Prepare PC

[on host PC] Create our working directory and get a toolchain:

mkdir ~/raspi
cd ~/raspi
git clone https://github.com/raspberrypi/tools

[on host PC] Create a sysroot. Using rsync we can properly keep things synchronized in the future as well. Replace raspberrypi.local with the address of the Pi.

mkdir sysroot sysroot/usr sysroot/opt
rsync -avz pi@raspberrypi.local:/lib sysroot
rsync -avz pi@raspberrypi.local:/usr/include sysroot/usr
rsync -avz pi@raspberrypi.local:/usr/lib sysroot/usr
rsync -avz pi@raspberrypi.local:/opt/vc sysroot/opt

[on host PC] Adjust symlinks to be relative. Use provided script, because the old fixQualifiedLibraryPaths is not working properly:

wget https://raw.githubusercontent.com/riscv/riscv-poky/priv-1.10/scripts/sysroot-relativelinks.py
chmod +x sysroot-relativelinks.py
./sysroot-relativelinks.py sysroot

  1. This step will be a bit different then described in original article. We are going to get a bit more than just qtbase.

We are going to get full sources (of modules that are interesting to us) of Qt 5.11.1 and build it. To do it one just need to execute this script:

Get Qt 5.11.1 and init its modules

Script will do a git clone of git://code.qt.io/qt/qt5.git and init all required submodules. In our case it is:

default module subset without: qtwebkit, qtwebkit-examples, qtwebengine, qt3d, qtactiveqt, qtandroidextras, qtandroidextras, qtandroidextras, qtandroidextras, qtlocation, qtpurchasing, qtwayland, qtwinextras, qtspeech

Downloading will take some time. Be patient.

[on host PC]

If you’ve already obtained Qt 5.11.1 sources you’ll be able to build it. To do it in a quick and easy way: Qt 5.11.1 configure and build for RPi crosscompile.

Few notes about that script:

Update your home dir!

  • Ensure that you have the same file structure.
  • Beware, there is pause in that script – comment it if you don’t like it.
  • Use it with time measurement, just for comparation: time ./rpi_build_qt.sh

Script produces several log files:

  • 00_configure.log – log of configure process
  • 01_build.log – log of build process
  • 02_install.log – log of install process

Refer to that files in case of any problems/errors.

If script fails on any kind of error it is good attitude to clean all well. Do it in a quickest way using this snippet: do_clean.sh.


If you don’t like to use script, please, read on:

The target directory is /usr/local/qt5pi on the Pi, the host tools like qmake will go to ~/raspi/qt5, while make install will target ~/raspi/qt5pi (this is what we will sync to the device). Don’t forget to adjust paths if you changed that. For some reason the ~/ in the paths may not work, if this the case just use full paths. You need to change <qt-version> with a proper Qt version (for example 5.6, or 5.9.1; note that version 5.9.1 is a tag not a branch, so you may want to create a local branch with it). You need to change <rpi-version> with a proper Raspberry Pi version.

Use:

  • linux-rasp-pi-g++ for RPi (including Zero, Zero W),
  • linux-rasp-pi2-g++ for RPi2 and
  • linux-rasp-pi3-g++ for RPi3.

If your system is 64 bit you may also edit device option to:

-device-option CROSS_COMPILE=~/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf-

For higher Qt version (like 5.9.1) you may also need to add

-no-use-gold-linker

option.

You probably also want to add -jn option to make command, where n is a number of cores you like to use for the complication.

git clone git://code.qt.io/qt/qtbase.git -b &lt;qt-version&gt;
cd qtbase
./configure -release -opengl es2 -device &lt;rpi-version&gt; -device-option CROSS_COMPILE=~/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf- -sysroot ~/raspi/sysroot -opensource -confirm-license -make libs -prefix /usr/local/qt5pi -extprefix ~/raspi/qt5pi -hostprefix ~/raspi/qt5 -v

make
make install

If you failed, you can clear everything with:

git clean -dfx

[on host PC] Deploy Qt to the device. We simply sync everything from ~/raspi/qt5pi to the prefix we configured above.

rsync -avz qt5pi pi@raspberrypi.local:/usr/local

Time to test it!

[on host PC] Build an example up to test if everything went well. After proper build, copy an executable to the device.

cd qt5/qtbase/examples/corelib/threads/semaphores/
~/raspi/qt5/bin/qmake
make

scp semaphores pi@raspberrypi.local:/home/pi

[on RPi] Update the device to let the linker find the Qt libs:

echo /usr/local/qt5pi/lib | sudo tee /etc/ld.so.conf.d/qt5pi.conf
sudo ldconfig

If you’re facing issues with running the example, try to use 00-qt5pi.conf instead of qt5pi.conf, to introduce proper order.


[on RPi] Fix the EGL/GLES libraries. The device may have the Mesa version of libEGL and libGLESv2 in /usr/lib/arm-linux-gnueabihf, resulting Qt apps picking these instead of the real thing from /opt/vc/lib. This may be fine for X11 desktop apps not caring about OpenGL performance but is totally useless for windowing system-less, fullscreen embedded apps. You may want to save the originals somewhere, just in case. Make sure you’re in /home/pi aka ~ when you run these commands:

sudo mv /usr/lib/arm-linux-gnueabihf/libEGL.so.1.0.0 /usr/lib/arm-linux-gnueabihf/libEGL.so.1.0.0_backup
sudo mv /usr/lib/arm-linux-gnueabihf/libGLESv2.so.2.0.0 /usr/lib/arm-linux-gnueabihf/libGLESv2.so.2.0.0_backup
sudo ln -s /opt/vc/lib/libEGL.so /usr/lib/arm-linux-gnueabihf/libEGL.so.1.0.0
sudo ln -s /opt/vc/lib/libGLESv2.so /usr/lib/arm-linux-gnueabihf/libGLESv2.so.2.0.0
Please make sure to also add missing symbolic links:
sudo ln -s /opt/vc/lib/libEGL.so /opt/vc/lib/libEGL.so.1
sudo ln -s /opt/vc/lib/libGLESv2.so /opt/vc/lib/libGLESv2.so.2

[on RPi] Run example, that we’ve built before.


P.S.: Script to update, sync environment: Update environment


  1. ICS: Configuring Qt Creator for the Raspberry Pi
  2. RaspberryPi2EGLFS on wiki.qt.io
  3. Building Qt 5 from Git on wiki.qt.io
comments powered by Disqus