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.
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.
#!/bin/sh WORKINGDIRECTORY=$HOME/raspberry TOOLCHAIN=gcc-4.7-linaro-rpi-gnueabihf MOUNTPOINT=/mnt/raspberry-rootfs export PATH=$PATH:$WORKINGDIRECTORY/$TOOLCHAIN/bin
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.
$ unzip 2013-02-09-wheezy-raspbian.zip ... $ mv 2013-02-09-wheezy-raspbian.img raspberry-working-image.img
Repeat: Make sure you know the correct device to use with the subsequent dd command, or you could lose all your data.
$ dmesg ... sd 7:0:0:0: No Caching mode page present sd 7:0:0:0: Assuming drive cache: write through sd 7:0:0:0: Attached SCSI removable disk
$ sudo dd bs=4M if=raspberry-working-image.img of=/dev/sdb 462+1 records in 462+1 records out 1939865600 bytes (1.9 GB) copied, 404.52 s, 4.8 MB/s
pi$ ifconfig
eth0 Link encap:Ethernet HWaddr xx:xx:xx:xx:xx:xx
inet addr:10.0.0.3 Bcast:10.0.0.255 Mask:255.255.255.0
...
$ ssh [email protected] [email protected]'s password:raspberry pi$
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.
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.
pi$ sudo shutdown -h now
$ 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
$ 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 122880 3788799 1832960 83 Linux
...
$ sudo /sbin/losetup -d /dev/loop0
$ sudo mkdir /mnt/raspberry-rootfs $ sudo mount -o loop,offset=62914560 \ raspberry-working-image.img /mnt/raspberry-rootfs $ ls /mnt/raspberry-rootfs bin dev home lost+found mnt proc run selinux sys usr boot etc lib media opt root sbin srv tmp varFor convenience our setdevenv.sh script sets a mountpoint variable for us, so we can use $MOUNTPOINT instead of the full path.
$ git clone git://gitorious.org/cross-compile-tools/cross-compile-tools.git $ cd cross-compile-tools
$ sudo ./fixQualifiedLibraryPaths $MOUNTPOINT \ ~/raspberry/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-gcc
$ sudo ln -s \ $MOUNTPOINT/opt/vc/include/interface/vmcs_host/linux/vchost_config.h \ $MOUNTPOINT/opt/vc/include/interface/vmcs_host/vchost_config.h
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.
$ tar xvfz qt-everywhere-opensource-src-5.0.2.tar.gz ....
$ git clone git://gitorious.org/bakeqtpi/bakeqtpi.git Cloning into 'bakeqtpi'... $ cd bakeqtpi $ cp 0001-Adjusts-to-build-qtbase-with-support-to-openvg.patch \ ../qt-everywhere-opensource-src-5.0.2/qtbase $ cp 0001-V8-Add-support-for-using-armv6-vfp2-instructions.patch \ ../qt-everywhere-opensource-src-5.0.2/qtjsbackend $ 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
$ cd qt-everywhere-opensource-src-5.0.2/qtbase $ ./configure \ -release \ -opengl es2 \ -optimized-qmake \ -no-pch \ -make libs \ -make tools \ -reduce-relocations \ -reduce-exports \ -sysroot /mnt/raspberry-rootfs \ -device linux-rasp-pi-g++ \ -device-option CROSS_COMPILE=~/raspberry/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf- \ -prefix /usr/local/Qt-5.0.2-raspberry
$ make $ sudo make install $ sudo cp -r /usr/local/Qt-5.0.2-raspberry/mkspecs \ $MOUNTPOINT/usr/local/Qt-5.0.2-raspberry
Qt 5 base will now be installed to /usr/local/Qt-5.0.2-raspberry on both the workstation and the mounted image.
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/$ /usr/local/Qt-5.0.2-raspberry/bin/qmake $ make $ 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 > /usr/local/Qt-5.0.2-raspberry/bin/qmake > make > sudo make install > done
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.
$ sync $ 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
Let's make sure everything is working. Insert the SD card in the Raspberry Pi and boot it up.
$ ssh [email protected] [email protected]'s password:
Then write a quick hello world.
pi$ cat > test.qml import QtQuick 2.0 Rectangle { color: "lightgray" Text { text: "Hello world!" anchors.centerIn: parent } } ^D pi$ /usr/local/Qt-5.0.2-raspberry/bin/qmlscene test.qml
You do not need a special build of Qt Creator to build for the Raspberry Pi. Qt Creator uses Kits to select build configurations.
Here's a typical development workflow using Qt Creator to build for the Raspberry Pi.
$ sudo mount -o loop,offset=62914560 \ raspberry-working-image.img /mnt/raspberry-rootfs
#include#include #include int main(int argc, char *argv) { QGuiApplication a(argc, argv); QQuickView v; v.setResizeMode(QQuickView::SizeRootObjectToView); v.setSource(QUrl("qrc:///main.qml")); v.showFullScreen(); return a.exec(); }
import QtQuick 2.0 Rectangle { color: "green" }
main.qml
target.path = /home/pi INSTALLS += target
Don't forget to unmount the working image when you are through with it!