Beginner’s guide to cross-compile Qt5 on RaspberryPi
Table of Content
This is a step by step guide to help beginners to: cross-compile QT5 for RaspberryPi(wheezy), create, deploy and run an example project. This article will focus on simplicity, so if you are looking for additional customization, please check a more detailed guide [qt-project.org].
- $ ./bakeqtpi.bash --help
First we create a folder to hold the source code and all the required files to do the cross-compilation. We chose to create a directory named “opt” in the home folder:
- paulo@westeros:~$ mkdir ~/opt
- paulo@westeros:~$ cd ~/opt
Now, download the following files:
- Raspbian Wheezy image from (here [raspberrypi.org]):
- paulo@westeros:~/opt$ wget http://files.velocix.com/c1410/images/raspbian/2012-07-15-wheezy-raspbian/2012-07-15-wheezy-raspbian.zip
- paulo@westeros:~/opt$ unzip 2012-07-15-wheezy-raspbian.zip
And mount it:
- paulo@westeros:~/opt$ sudo mkdir /mnt/rasp-pi-rootfs
- paulo@westeros:~/opt$ sudo mount -o loop,offset=62914560 2012-07-15-wheezy-raspbian.img /mnt/rasp-pi-rootfs
- The toolchain built by Donald:
- paulo@westeros:~/opt$ wget http://blueocean.qmh-project.org/gcc-4.7-linaro-rpi-gnueabihf.tbz
- (or a mirror at http://swap.tsmt.eu/gcc-4.7-linaro-rpi-gnueabihf.tbz with sha1 f6255c6aca925239dc943d22a794f642daa17e65)
- paulo@westeros:~/opt$ tar -xf gcc-4.7-linaro-rpi-gnueabihf.tbz
Pro tip: don’t build your own cross-compiler. You’ll overlook something important and loose a couple of hours of your life for nothing. A suitable Raspberry Pi cross-compiler is also available here: https://github.com/raspberrypi/tools
It is a 32-bit build so if you are running on a 64-bit machine (you probably are) you need to install ia32-libs:
- paulo@westeros:~/opt$ sudo apt-get install ia32-libs
- Clone the cross-compile-tools repository:
- paulo@westeros:~/opt$ git clone git://gitorious.org/cross-compile-tools/cross-compile-tools.git
- Clone and init the Qt5 repository:
- paulo@westeros:~/opt$ git clone git://gitorious.org/qt/qt5.git
- paulo@westeros:~/opt$ cd qt5
- paulo@westeros:~/opt/qt5$ ./init-repository
If you’re behind a firewall ./init-repository might fail. First run this command:
- paulo@westeros:~/opt/qt5$ sed -i 's/git:\/\//https:\/\/git./' .gitmodules
- paulo@westeros:~/opt/qt5$ ./init-repository -f
- Finally, apply a patch on the qtjsbackend repository:
- paulo@wseteros:~/opt/qt5$ cd ~/opt/qt5/qtjsbackend
- paulo@wseteros:~/opt/qt5/qtjsbackend$ git fetch https://codereview.qt-project.org/p/qt/qtjsbackend refs/changes/56/27256/4 && git cherry-pick FETCH_HEAD
Now the we have all the resources needed to compile qt5 for raspberry, we need to execute a script to fix symlinks and lib paths:
- paulo@westeros:~$ cd ~/opt/cross-compile-tools
- paulo@westeros:~$ sudo ./fixQualifiedLibraryPaths /mnt/rasp-pi-rootfs/ ~/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-gcc
Go to the qt5/qtbase folder and run:
- paulo@westeros:~/opt/qt5/qtbase$ ./configure -opengl es2 -device linux-rasp-pi-g++ -device-option CROSS_COMPILE=~/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf- -sysroot /mnt/rasp-pi-rootfs -opensource -confirm-license -optimized-qmake -reduce-relocations -reduce-exports -release -make libs -prefix /usr/local/qt5pi
- paulo@westeros:~/opt/qt5/qtbase$ make -j 4
- paulo@westeros:~/opt/qt5/qtbase$ sudo make install
Note: if you want the qmlscene binary you should add -make tools to the ./configure command.
Compiling other modules
Now that you have qmake, you can cross-compile the other modules. To avoid dependencies errors, the following order is sugested:
qtimageformats, qtsvg, qtjsbackend, qtscript, qtxmlpatterns, qtdeclarative, qtsensors, qt3d, qtgraphicaleffects, qtjsondb, qtlocation, qtdocgallery.
To compile, you must do like the example below:
- paulo@westeros:~/opt/qt5$ cd qtimageformats
- paulo@westeros:~/opt/qt5/qtimageformats$ /usr/local/qt5pi/bin/qmake .
- paulo@westeros:~/opt/qt5/qtimageformats$ make -j4
- paulo@westeros:~/opt/qt5/qtimageformats$ sudo make install
We have all the modules installed in the wheezy image, now we can copy it to the sdcard using dd:
- paulo@westeros:~/opt/qt5$ cd ~/opt/
- paulo@westeros:~/opt$ sync; sudo umount /mnt/rasp-pi-rootfs
- paulo@westeros:~/opt$ sudo dd bs=1M if=2012-07-15-wheezy-raspbian.img of=/dev/sdb; sync
obs: Check the entry point of your sdcard. Mine was /dev/sdb.
Notes for OSX
- Because your sdcard will be partitioned, OSX won’t let you umount it, so you’ll need to type:
- sudo diskutil umountDisk /dev/disk3
where “disk3” will be the /dev/diskXsY where your sdcard first appeared.
- To perform dd you will need to use the *r*disk index, so if your sdcard is disk3 you will need to type:
- sudo dd bs=1M if=2012-07-15-wheezy-raspbian.img of=/dev/rdisk3; sync
Boot up your pi.
Configuring Qt Creator
To use Qt Creator properly, you must configure the “Qt Version” and “Tool Chains” sections.
Tool Chain Settings
go to Tools -> Options.. -> Build & Run -> Compilers tab.
click in “Add -> GCC”.
On “Compiler Path” set to “/home/<you>/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-g++”.
Name it “ARM GCC” or similar.
obs: Adjust it to your username.
Qt Version settings.
Now go to Tools -> Options.. -> Build & Run -> Qt Versions tab.
Click in “Add..” and choose you qmake for raspberry “/usr/local/qt5pi/bin/qmake”.
Note for OSX
- Because /usr is not visible by default, you first need to open a terminal and type:
- sudo SetFile -a v /usr
- After you’ve completed the qmake selection, if you wish to make /usr invisible again, type the same command with a capital V :
- sudo SetFile -a V /usr
Configure Linux Devices
Go to Tools -> Options… -> Devices -> Devices tab.
Add a new configuration setting a “Generic Linux Device”
Hostname or IP address is the IP of your raspberry
user is pi
password is raspberry
obs: if your not did change it.
Now you are ready to run your first Qt raspberry pi project.
You can download a hello world project:
- paulo@westeros:~$ git clone https://git.gitorious.org/qt5-raspberrypi-example/qt5-raspberrypi-example.git
Open the project in Qt Creator and go to the Projects pane.
Click Manage Kits and then Add.
Name: Raspberry Pi
Device Type: Generic Linux Device
Device: Raspberry Pi
Compiler: ARM GCC
Debugger->Manage->Edit->”/home/<you>/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-gdb” (change your username)
Qt version: Qt 5.x.x (qt5pi)
Ok->Add Kit->Raspberry Pi
Then go to the “Rasperry Pi” kit tab->System Environment and add LD_LIBRARY_PATH which is set to /usr/local/qt5pi/lib
Now you can build and run your application from Qt Creator.
Qt version not properly installed
You need to keep the SD card image mounted during development!
If QtCreator still reports this after mounting the SD card image, then you may need to create the directories missing from
or whatever the mount path is (these will probably include bin, translations, and so on). You can create empty directories using the mkdir command.
The default mkspec symlink is broken.
It means that mkspec is not found on your sysroot, so your must copy it.
- paulo@westeros:~$ sudo cp -r /usr/local/qt5pi/mkspecs/ /mnt/rasp-pi-rootfs/usr/local/qt5pi/
If the problem persists, create the missing symlink, e.g.
- sudo ln -s /usr/local/qt5pi/mkspecs/devices/linux-rasp-pi-g++ /usr/local/qt5pi/mkspecs/default
It is probably a good idea to do the same for the sysroot mkspecs.
Include <QtGui/QtGui>: No such file or directory
It seems Qt’s include was not found and you must add it to you .pro file:
- INCLUDEPATH += /mnt/rasp-pi-rootfs/usr/local/qt5pi/include/
cc1: fatal error: .pch/release-shared/QtGui: No such file or directory
Some people have seen this error. Adding the “-no-pch” option when running configure should prevent it.
Getting Could not determine the target architecture! and Could not determine the host architecture!
If you are getting this kind of error, it is possible that your current git branch is something other than master. To be sure, do the following:
- daniel@daniel-t3500 : ~/opt/qt5/qtbase $ git branch
If it shows like this:
- * (no branch)
Then you must checkout to master branch before running ./configure:
- daniel@daniel-t3500 : ~/opt/qt5/qtbase $ git checkout master
- daniel@daniel-t3500 : ~/opt/qt5/qtbase $ git branch
- * master
It is also good to fetch the latest commits and apply them by doing:
- daniel@daniel-t3500 : ~/opt/qt5/qtbase $ git pull
Also, check for the installation of libz (32 bits) in yor system. In ubuntu (64 bits) you might just:
- sudo apt-get install lib32z1-dev
After the ./configure script has failed first run these commands before restarting ./configure:
- daniel@daniel-t3500 : ~/opt/qt5/qtbase $ git reset --hard
- daniel@daniel-t3500 : ~/opt/qt5/qtbase $ git git clean -dxf
EGL Error : Could not create the egl surface: error = 0×3000
Try allocating more memory to video (try 64 or 128MB). Use the raspi-config utility to change this.
- pi@raspberrypi ~ $ sudo raspi-config
ABI detection failed
You will need Qt Creator 2.6 for Qt5 up to and including beta2.
Any Qt 5 later than that will need to use nightly snapshots (or will have to wait for Qt Creator 2.6.1): After the beta2 all libraries were renamed again.
See this forum thread for more details [qt-project.org]
./configure: 2654: ./configure: /home/<you>/opt/gcc-4.7-linaro-rpi-gnueabihf/bin/arm-linux-gnueabihf-g++: not found -reduce-exports was requested but this compiler does not support it
The error message is totally misleading. The real cause is that the precompile toolchain is 32-bit, so you need to:
- sudo apt-get install ia32-libs
make: g++: Command not found
Qt requires a native (non-cross-compiling) copy of g++ to be installed in order to build qmake. You can’t use clang. Fix with:
- sudo apt-get install g++
/mnt/rasp-pi-rootfs/usr/lib/arm-linux-gnueabihf/libdl.a(dlopen.o): In function `dlopen’: (.text+0xc): undefined reference to `__dlopen’
You need to run the ./fixQualifiedLibraryPaths again.
cc1: fatal error: .pch/release-shared/Qt5Gui: No such file or directory
Try adding -no-pch to the ./configure command line.
Cannot create forwarding script Betrete ‘qtactiveqt’.git/hooks/commit-msg: Datei oder Verzeichnis nicht gefunden
- unset LANG
- ./init-repository -f