This is a HOW TO guide for building Qt 5 for the Raspberry Pi, and building and deploying Qt 5 apps using Qt Creator. This guide will be using Raspbian “Wheezy”, a Debian based distro designed for the Raspberry Pi. This guide also assumes the use of Linux or UNIX on the workstation side.
Note: Throughout this guide the symbol “$” denotes a command prompt on the host workstation, and “pi$” denotes a command prompt on the target Raspberry Pi.
You will need the following downloads:
Please note the user and login for the Linux image. Currently this is user “pi” and password “raspberry”, but this could change in the future.
Install a Toolchain
To build on the Raspberry Pi we need a cross-compile toolchain. The toolchain will contain compilers, linkers and other tools that run on the host workstation but create executables for the target Raspberry Pi.
For embedded development, one normally uses a vendor-supplied toolchain, but in the case of the Raspberry Pi, there is no official vendor supplied toolchain. There are several generic ARM toolchains that will suffice, however, we have chosen to use the same one the bakeqtpi script uses. This is a Linaro based toolchain for the ARMv6 platform with hard floating-point support. Alternatively, we could have built our own toolchain.
We will create a working directory to use named “raspberry”. Our first step is to get and install a cross compiling toolchain.
$ mkdir ~/raspberry
$ cd ~/raspberry
$ wget http://swap.tsmt.eu/gcc-4.7-linaro-rpi-gnueabihf.tbz
$ tar xfj gcc-4.7-linaro-rpi-gnueabihf.tbz
Since this toolchain is built for 32-bit systems, you will need a set of 32-bit libraries installed if you are on a 64-bit system. On Ubuntu systems, this can be accomplished by installing the ia32-libs package. Unfortunately, this is a deprecated transitional package, with no replacement.
$ sudo apt-get install ia32-libs
As a convenience, you can create a setdevenv.sh script in ~/raspberry that can be sourced to set up necessary environment variables.
Prepare the Image
Burn and Boot
Before we can do anything, we need to be able to boot up the Raspberry Pi to a working Raspbian “Wheezy” Linux. We do this by burning a Raspbian image to an SD Card.
Additional packages will be needed on the Raspberry Pi in order to build Qt 5 and run Qt 5 applications.
The first step is to update and upgrade the existing packages.
pi$ sudo apt-get update
pi$ sudo apt-get upgrade
Here is a list of the basic packages needed for building and running Qt 5. These are Ubuntu package names, but there should be similar packages on all Linux distros.
pi$ sudo apt-get install libfontconfig1-dev ...
Setting up libfontconfig1-dev (2.9.0-7.1) ...
If you plan on building QWebKit, you'll need the following additional packages.
For multimedia you will need the following optional packages.
Back to the Workstation
Building software on the Raspberry Pi will be too slow, thus we will need to return to our workstation and use our cross-compile toolchain to perform the remainder of the work.
A traditional method of cross-platform development is to create a chroot or jail environment to build against. However, since we have a working image of the Raspberry Pi, we can use that instead and it will be much easier. There are also minor fixes we need to make to the image.
- First, cleanly shutdown the Raspberry Pi.
- Insert the SD card in the host workstation and copy the card contents back to our working image file. Note that this will create an image the size of the SD card, so make sure you have enough room. Correct for any path and device differences in the following command.
$ sudo dd if=/dev/sdb of=raspberry-working-image.img
7761920+0 records in
7761920+0 records out
3974103040 bytes (4.0 GB) copied, 253.641 s, 15.7 MB/s
- You will need the offset for the Linux image to mount it. If it's not otherwise provided with the download, you can determine it using losetup. There are 512 bytes per sector, so in the example below the offset is 122880 * 512 = 62914560.
$ sudo /sbin/losetup /dev/loop0 raspberry-working-image.img
$ sudo /sbin/fdisk -l /dev/loop0
Device Boot Start End Blocks Id System
/dev/loop0p1 8192 122879 57344 c W95 FAT32
/dev/loop0p2 <strong>122880</strong> 3788799 1832960 83 Linux
$ sudo /sbin/losetup -d /dev/loop0
- Now create a mount point and mount the image:
For convenience our setdevenv.sh script sets a mountpoint variable for us, so we can use $MOUNTPOINT instead of the full path.
$ sudo mkdir /mnt/raspberry-rootfs
$ sudo mount -o loop,offset=62914560 \
$ ls /mnt/raspberry-rootfs
bin dev home lost+found mnt proc run selinux sys usr
boot etc lib media opt root sbin srv tmp var
- Clone the cross-compile-tools repo. This contains some useful scripts, including the important fixQualifiedLibraryPaths script.
$ git clone git://gitorious.org/cross-compile-tools/cross-compile-tools.git
$ cd cross-compile-tools
- Apply the fixQualifiedLibraryPaths script. This fixes the symlinks in the mounted image to be relative instead of absolute. The command is: fixQualifiedLibraryPaths target-rootfs path-to-target-toolchain-compiler
$ sudo ./fixQualifiedLibraryPaths $MOUNTPOINT \
- Finally we need to make some miscellaneous fixes.
$ sudo ln -s \
Building Qt 5
Building Qt 5 will now proceed normally in much the same way as building Qt 5 for the desktop. There are a few minor differences however, such as applying a few patches and providing the appropriate configure options.
Patching Qt 5
- Untar the Qt5 distribution into a build directory.
$ tar xvfz qt-everywhere-opensource-src-5.0.2.tar.gz
- Qt 5 needs to have some patches applied. Unfortunately, it can be hard to know what patches are needed for what version. There is no authoritative repository of good patches for the Raspberry Pi. What works here might not work with the next incremental release of Qt. I am taking these patches from the bakeqtpi repo. YMMV.
$ git clone git://gitorious.org/bakeqtpi/bakeqtpi.git
Cloning into 'bakeqtpi'...
$ cd bakeqtpi
$ cp 0001-Adjusts-to-build-qtbase-with-support-to-openvg.patch \
$ cp 0001-V8-Add-support-for-using-armv6-vfp2-instructions.patch \
$ cd ../qt-everywhere-opensource-src-5.0.2/qtbase
$ patch -p1 < 0001-Adjusts-to-build-qtbase-with-support-to-openvg.patch
$ cd ../qtjsbackend
$ patch -p1 < 0001-V8-Add-support-for-using-armv6-vfp2-instructions.patch
Building Qt 5 Base
- Configure Qt 5. Several options are necessary for the Raspberry Pi. The -sysroot option is very important as it tells the build to use the libraries in our mounted image.
$ cd qt-everywhere-opensource-src-5.0.2/qtbase
$ ./configure \
-opengl es2 \
-make libs \
-make tools \
-sysroot /mnt/raspberry-rootfs \
-device linux-rasp-pi-g++ \
-device-option CROSS_COMPILE=~/raspberry/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf- \
- Double check the configure output to make sure everything looks fine. Then build and install Qt Base. The install target will install to both the host workstation and the mounted image, although it installs different components to each. We manually copy over the mkspecs because the cross-compile build will not do this for us.
$ sudo make install
$ sudo cp -r /usr/local/Qt-5.0.2-raspberry/mkspecs \
Qt 5 base will now be installed to /usr/local/Qt-5.0.2-raspberry on both the workstation and the mounted image.
Building Qt 5 Modules
Repeat the following steps for each additional Qt module you wish to use: qtimageformats, qtjsbackend, qtsvg, qtxmlpatterns, qtdeclarative, qtgraphicaleffects, qtmultimedia, qtscript, qtwebkit. Note, the order of each build is important, as some modules are dependent on others.
For each module:
$ cd qt-everywhere-opensource-src-5.0.2/<module>
$ sudo make install
Alternatively, for a short mini-script to build and install them all:
$ cd qt-everywhere-opensource-src-5.0.2
$ for module in qtimageformats qtjsbackend qtsvg qtxmlpatterns qtdeclarative \
qtgraphicaleffects qtmultimedia qtquick1 qtscript qtwebkit; do
> cd ../$module
> sudo make install
Burn the New Image
Now that Qt has been successfully built and installed, we need to burn this image back to an SD card to use on the Raspberry Pi.
$ sudo umount /mnt/raspberry-rootfs
$ sudo dd bs=4M if=raspberry-working-image.img of=/dev/sdb
947+1 records in
947+1 records out
3974103040 bytes (4.0 GB) copied, 672.988 s, 5.9 MB/s
Quick Sanity Check
Let's make sure everything is working. Insert the SD card in the Raspberry Pi and boot it up.
$ ssh email@example.com
Then write a quick hello world.
pi$ cat > test.qml
import QtQuick 2.0
text: "Hello world!"
pi$ /usr/local/Qt-5.0.2-raspberry/bin/qmlscene test.qml
Setting Up Qt Creator
You do not need a special build of Qt Creator to build for the Raspberry Pi. Qt Creator uses Kits to select build configurations.
- Make sure your development environment is set, and the raspberry working image is mounted.
- Start Qt Creator.
- Bring up the options dialog using Tools -> Options....
- Select the Devices page on the left.
- Click Add... and add an entry for the Raspberry Pi.
- Select Generic Linux Device and click Start Wizard.
- Enter Raspberry Pi for the name of the device.
- Enter the IP address for the Raspberry Pi.
- Enter “pi” for the username.
- Enter “raspberry” for the password.
- Select the Build & Run page on the left.
- Select the Compilers tab.
- Using the Add button, add a GCC compiler.
- Name the compiler “Raspberry Pi Toolchain”.
- Set the path to the toolchain, ~/raspberry/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-g++
- Select the Qt Versions tab.
- Using Add... add a new Qt version.
- Select the path to the appropriate qmake: “/usr/local/Qt-5.0.2-raspberry/bin/qmake”.
- Select the Kits tab.
- Click Add button to add a kit for the Raspberry Pi.
- Enter “Qt 5.0 Raspberry Pi” for name.
- Select Generic Linux Device and Raspberry Pi for device type and device.
- Enter “/mnt/raspberry-rootfs” for the sysroot
- Select Raspberry Pi Toolchain for the compiler.
- Browse to ~/raspberry/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-gdb for the debugger.
- Select Qt-5.0.2-raspberry for the Qt Version.
- Click OK to finalize the configuration.
Typical Development Workflow
Here's a typical development workflow using Qt Creator to build for the Raspberry Pi.
- Mount the working image. The toolchain needs this for the libraries.
$ sudo mount -o loop,offset=62914560 \
- Start Qt Creator
- Start a new project
- File -> New File or Project...
- Select Qt Console Application
- Name the project. I chose “raspberrytest”
- Check Qt 5.0 Raspberry Pi as a project type and uncheck all other types.
- Develop a Qt application as you normally would. In my case, I used the following files (borrowed from a Raspberry Qt example).
int main(int argc, char *argv)
QGuiApplication a(argc, argv);
import QtQuick 2.0
- Set up raspberrytest.pro to correctly deploy.
- Change the QT variable to be “core gui qml quick”
- Add an install target
target.path = /home/pi
INSTALLS += target
- Build the application by selecting Build -> Build All (or click on the hammer icon)
- Deploy and run on the Raspberry Pi by selecting Debug -> Start Debugging (or click the debug icon)
- Stop the app by selecting Debug -> Stop Debugger (or click on red stop icon in debugging bar)
- For final deployment, select Build -> Deploy All
Don't forget to unmount the working image when you are through with it!