Book Image

Hands-On Embedded Programming with QT

By : John Werner
Book Image

Hands-On Embedded Programming with QT

By: John Werner

Overview of this book

Qt is an open source toolkit suitable for cross-platform and embedded application development. This book uses inductive teaching to help you learn how to create applications for embedded and Internet of Things (IoT) devices with Qt 5. You’ll start by learning to develop your very first application with Qt. Next, you’ll build on the first application by understanding new concepts through hands-on projects and written text. Each project will introduce new features that will help you transform your basic first project into a connected IoT application running on embedded hardware. In addition to gaining practical experience in developing an embedded Qt project, you will also gain valuable insights into best practices for Qt development and explore advanced techniques for testing, debugging, and monitoring the performance of Qt applications. The examples and projects covered throughout the book can be run both locally and on an embedded platform. By the end of this book, you will have the skills you need to use Qt 5 to confidently develop modern embedded applications.
Table of Contents (22 chapters)
Free Chapter
Section 1: Getting Started with Embedded Qt
Section 2: Working with Embedded Qt
Section 3: Deep Dive into Embedded Qt
Section 4: Advanced Techniques and Best Practices
Appendix A: BigProject Requirements

Building Qt for the Target

While Qt can sometimes be obtained for a specific target, the version we are running isn't available for the Raspberry Pi. Instead, we will look at how to build Qt from the sources. At first, it may seem like a daunting task, but it really is straightforward. Let's get to it:

  1. Before we start building Qt, we are going to make a backup copy of the source directory using tar. Open Command Prompt and cd to the installation directory for Qt 5.12.0. Next, tar up the Src directory, as follows:
[On Host] $ cd ~/Qt/5.12.0
[On Host] $ tar jcvf qt-5.12.0-src.tar.bz2 Src
Always keep the distribution sources untouched and don't build in the installed source directory. Use a copy of the directory instead. That way, should something happen, you won't have to re-download the sources.
  1. Now, extract the tarball into ~/raspi/Src and rename it ~/raspi/qt-5.12.0-src:
[On Host] $ cd ~/raspi
[On Host] $ tar xvf ~/Qt/5.12.0/qt-5.12.0-src.tar.bz2
[On Host] $ mv Src qt-5.12.0-src
Experience is a great teacher. Over the years, I have found that the source code for Qt is so big that simply cleaning up from a build in order to make an adjustment and do another build can take a very long time. So, I discovered a trick—I build Qt in a separate directory from the source code! When I want a fresh build, I simply blow away the build directory and start again!

Fixing the sources

I would love to say that the sources are perfectly ready to build for our Raspberry Pi target, but I can't. There are a few source code issues with Qt 5.12.0 that are not supported by the cross compilers. To account for this, I have generated a patch set for the files. Download the patch file, that is, qt-5.12.0-raspi.patch, from the GitHub repository for this chapter and apply it using the following patch command:

[On Host] $ cd ~/raspi/qt-5.12.0-src
[On Host] $ patch -d qt-5.12.0-Src -p1 < qt-5.12.0-raspi.patch
This section only applies to Qt 5.12.0! If you download 5.12.3 (or later), all of this special setup isn't needed. You can use either version for this book.

Building a program

Now that the sources have been fixed, let's build it. There are two basic steps. The first is to configure the build, while the second is to actually build it.

Configuring the Qt build

Developers are so lucky these days. Back when I first started installing programs from the internet (which wasn't even called the internet back in those days), building a program for your machine meant editing configuration or making files by hand and tweaking various settings with the hope that you could figure out the right ones for your machine.

After what seemed like years, someone finally came up with a brilliant idea: Let's build a program that will automatically test the system and set all of the proper values for building it automatically. We can call it configure. Today, most packages have some sort of configure program that can be run to do all of the setup information.

Of course, Qt is one of these packages. If we were building for the host machine, it would be very straightforward to do, but since we are building for a target, we need to give configure some help.

So as not to pollute the source directory with built objects and to make it easier to "clean" the build should we need to rebuild, we will build in a separate directory.

The following three command lines (yes, the third line is really just one line!) will work for our purposes:

[On Host]$ mkdir build-raspi
[On Host]$ cd build-raspi
[On Host]$ ../qt-5.12.0-src/configure -release -opengl es2 -device linux-rasp-pi3-g++ -device-option CROSS_COMPILE=~/raspi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf- -sysroot ~/raspi/sysroot -opensource -confirm-license -make libs -prefix /usr -extprefix ~/raspi/sysroot/usr -hostprefix ~/raspi/qt5 -v -no-use-gold-linker -webengine-embedded-build -webengine-pepper-plugins -webengine-printing-and-pdf -webengine-proprietary-codecs -webengine-spellchecker -qt-sqlite -feature-webengine-embedded-build -feature-webengine-printing-and-pdf -skip qtscript -webengine-webrtc

There are no spaces after any dashes, even though the line may be wrapped at them. These commands should be issued in the ~/raspi directory. Why don't you make the line run and, while it does its work, take a look at the Decoding the configure command section to understand what you told it to do.

Decoding the configure command

As the configure command has developed, cross compiling has actually become fairly easy to configure, even if it looks complex at first. The following table breaks down the parts of the command line so that you can understand what's happening a bit better:




The command to run


Build a release version

-opengl es2

Enable OpenGL ES2

-device linux-rasp-pi3-g++

Build for the Raspberry Pi 3 target

-device-option CROSS_COMPILE=~

What cross compiler to use
-sysroot ~/raspi/sysroot The location of the Target's root filesystem on the host


Build the Open Source version


Accept the license without a prompt
-make libs Make the libraries
-prefix /usr Where to install on the Target's root filesystem
-extprefix ~/raspi/sysroot/usr The installation location on the host copy of the root filesystem
-hostprefix ~/raspi/qt5 Where to put host files for cross compilation for the Target
-v Be verbose about what is happening
-no-use-gold-linker Don't use the Gold Linker
-webengine-embedded-build Build WebEngine for an embedded environment
-webengine-pepper-plugins Build the Pepper Plugin for WebEngine
-webengine-printing-and-pdf Build support for PDF and printing in WebEngine
-webengine-proprietary-codecs Build proprietary codecs for WebEngine
-webengine-spellchecker Build the WebEngine Spell Checker
-qt-sqlite Build support for the SQLite Database
-skip qtscript Don't build the Qt Script component
Most incarnations of configure can tell you more about what options they support. Try running ./configure --help to see what else can be controlled, or refer to

Building the code

If the configuration step was successful, then it's time to build the code using the make command. If not, examine the output of configure and try to identify what is missing.

To speed things up, we will run a parallel build job. For most systems, you want to split the build into twice the number of threads as the number of processors. For a quad core processor, that means eight threads:

[On Host] $ make -j 8

If the build worked without error, install the build using the following command:

[On Host] $ make install

If there were errors during the build, try building without multiple jobs and look at where the build stopped for clues as to what needs to be fixed.

More information on how to build Qt from sources can be found on the Qt website at

Synchronizing the new components with the target

When we built Qt, we built it into the local copy of the Target's root filesystem. Now, we need to push the changes back to the Target. Once again, we will use rsync to make that happen, as follows:

[On Host] $ cd ~/raspi/sysroot
[On Host] $ rsync -avz . root@raspberrypi:/