Cross Compiling Qt4 Applications for the Raspberry Pi

This blog post will demonstrate how to cross compile Qt4 applications for the Raspberry Pi (RPi). The approach taken in this entry is a little different from that taken by other tutorials such as this or this. The complete cross compilation of the Qt4 or Qt5 libraries will NOT be covered. Instead, the Qt4 libraries available in the Raspbian’s repos will be installed on the Raspberry Pi and the RPi’s root filesystem will then be mounted onto the PC over the network using SSHFS. The RPi’s cross compiling toolchain will then build qt apps by compiling Qt4 source code on the PC and linking it to the Qt4 libraries available via the SSHFS-mounted RPi filesystem.

Simple QT4 application cross-compiled on PC

The challenge with such an approach is the inability to use either the native qmake on the PC or the RPi. Both were built to be used natively on their respective platforms. While cross-compiling qmake and customizing it may be possible, the approach presented here will circumvent qmake altogether. Instead, a custom makefile will be used to successfully cross-compile Qt4 applications.

My username on my Linux PC is ‘halherta’ and by RPI’s IP address is ‘192.168.0.104’. Please replace these with your appropriate username and RPI IP address as per your setup.

Bring up the RPi with Raspbian OS:

First we need to boot Raspbian on the Raspberry Pi. If you don’t already have Raspbian running on the RPi or need to do a clean install of Raspbian OS on the RPi, do the following:

Install the Raspbian OS on an SD Card (4GB should be OK but 8GB is better)

Create a $HOME/rpi directory on your Linux PC. Download the cross-compiling toolchain for the RPi into that directory on your Linux PC and add it’s bin directory to the PATH variable in your .bashrc as instructed here .

Verify that the cross-compiling toolchain is installed on your PC by running the following command:

After installing the RPi cross-compiling toolchain, we will need to install SSHFS on the PC. This will allow us to mount our RPi’s root filesystem onto our PC over the network.

sudo apt-get install sshfs

once SSHFS is installed on the PC we need to add the current user to the fuse group. This will grant the user access to the mounted SSHFS partition

sudo usermod -a -G fuse halherta

The next step is to install Qt4’s meta object compiler known as ‘moc’ or ‘moc-qt4′ on the Linux PC. This compiler probes all the header files that contain Qt4 object/class declarations and generates one additional source file (.moc.cpp) per header file (.h). These generated source files contain necessary Qt4 boilerplate code. The ‘moc-qt4′ tool generates source, not binaries. This means that its OK to use the ‘moc-qt4′ tool available on the PC in our cross-compiling setup.

Too install the ‘moc-qt4′ tool:

sudo apt-get install libqt4-dev-bin

Verify that the moc-qt4 tool is indeed installed by running:

moc-qt4 -v

If successful the output of the above command should be similar to:

Qt Meta Object Compiler version 63 (Qt 4.8.6)

Make sure that you are using the ‘moc-qt4′ tool. The Qt5 based ‘moc’ tool is NOT compatible with Qt4 builds.

Mount the RPi over SSHFS and prepare the PC for cross compilation of Qt4 apps

Create a $HOME/rpi/mntrpi directory on your Linux PC.

Now mount the RPI’s root file system into $HOME/rpi/mntrpi on your PC over SSHFS by running the following command:

In order to use SSHFS for mounting you need to be root, hence the use of sudo preceding the command itself. After typing out the command, type the RPI’s username (pi) & IP address (192.1668.0.104) followed by a colon and the directory to be mounted. In this case we will mount the rpi’s root directory into ‘/home/halherta/rpi/mntrpi/’ on our PC. The other two flags do the following:

transform_symlinks – needed so that absolute symlinks in the RPI’s filesystem are transformed to relative ones. In this way a symlink on the RPI filesystem continue to point to the appropriate file on the RPI filesystem and not a similarly named file on the host system.

allow_other - needed to allow all users (not just the root user) on the PC access to the RPi’s root filesystem

Now if we list the contents of ‘/home/halherta/rpi/mntrpi/’ we should see our entire RPI root filesystem in all of its glory.

On the Linux PC, create two soft links in the /lib && /usr/lib directories :

Verify that the directory soft links indeed exist with the following two commands:

ls -ld /lib/arm-linux-gnueabihf

ls -ld /usr/lib/arm-linux-gnueabihf

Download the following compressed file containing source code for a simple Qt4 application and the makefile. qttest.tar.gz

untar the file in your home directory or in ‘/home/halherta/rpi’

tar xvzf qttest.tar.gz

Cross-compile the Qt4 Application

cd into the qttest directory and type ‘make’. Before typing ‘make’, be sure that the RPI’s filesystem is mounted via SSHFS! If it is not this step will fail!!!!! This is because the makefile expects to find the RPI’s filesystem at ‘/home/halherta/rpi/mntrpi’. This step will also fail if the Qt4 libraries and tools were not installed properly as instructed earlier in this tutorial.

cross-compilation (building) of a simple QT4 application for the RPI on a PC

We can now move the application binary ‘target_bin’ into the RPI’s file system with a simple copy command:

cp target_bin $HOME/rpi/mntrpi/home/pi

To unmount the SSHFS partition type:

sudo umount $HOME/rpi/mntrpi

Make sure that you unmount the SSHFS/RPI partition whenever its not needed, as it takes quite a lot of cycles/bandwidth to maintain this network partition.

We can now VNC into our RPI or login via SSH with X11 forwarding and run the ‘target_bin’ binary.

The result is shown in the the figure displayed at the top of this blog entry.