Skip to content
nezticle edited this page Aug 10, 2012 · 13 revisions

The objective of this page is to give a complete walkthrough of how to go from nothing, to adding additional libraries (Qt5 with Wayland support), and building for and deploying applications to the Raspberry Pi using the Bsquask SDK.

Getting and building the Bsquask SDK

Clone the RaspberryPi-BuildRoot project into your local code directory:
cd ~/Code/
git clone git@github.com:nezticle/RaspberryPi-BuildRoot.git BuildRoot

Create the directory where you want your SDK to be built:
export BSQUASK_DIR=/opt/bsquask
mkdir -p $BSQUASK_DIR

Enter the BuildRoot directory and generate a Makefile for your SDK:
cd BuildRoot
make raspberrypi_defconfig O=$BSQUASK_DIR
You may be missing some build dependancies (flex, bison, etc...) but you will be warned about what packages you need to install if this is the case.

Change to your SDK directory and and start the build (this can take a few hours the first time).
cd $BSQUASK_DIR
make
Do not use the -j option with this Makefile! The number of make jobs is specified by the BuildRoot configuration, and overriding this with the -j flag here breaks the build system. If you want to change the number of build jobs run:
sed 's/BR2_JLEVEL=5/BR2_JLEVEL=N/' .config > .tmp_config; mv .tmp_config .config
replacing the N with the number of build jobs, then run make as above

Using Generated Image on the Raspberry Pi

First you need to obtain an SD card that has the correct partitions setup. It needs to be setup as follows:

  • 75MB fat32 partition
  • 500MB or greater ext4 partition (ideally using the remainder of the card)

If you need help with this, the Raspberry Pi wiki has a guide that's pretty close (make sure to use ext4 instead of ext3).

When you have this setup, mount the the two partitions (assuming /media/BOOT for the fat32 partiion, and /media/rootfs for the ext4). The run the following commands to install the rootfs:
cd $BSQUASK_DIR/images
tar -zxvf boot.tar.gz -C /media/BOOT
sudo tar -zxvf rootfs.tar.gz -C /media/rootfs
Make sure you are root(sudo) when extracting rootfs.tar.gz, or you will have problems on boot

Now place the SD card in your Raspberry Pi and power on. If everything went as planned, you should get a login prompt for Bsquask (linux).
Easy right?

Basics of Using the SDK

Lets set a few more environment variables to make things easier:
export BSQUASK_HOST_DIR=$BSQUASK_DIR/host
export BSQUASK_STAGING_DIR=$BSQUASK_DIR/staging
export BSQUASK_TARGET_DIR=$BSQUASK_DIR/target

$BSQUASK_HOST_DIR is the directory containing the native built tools for your machine like your cross compiler. If you want to make use these tools then you will want to add these them to your path:
export PATH=$BSQUASK_HOST_DIR/usr/bin:$PATH

$BSQUASK_STAGING_DIR is the location of your sysroot. This is where you install everything that you've built for your device, including development headers and debug symbols.

$BSQUASK_TARGET_DIR is the location you use to build images. This is what you are deploying to your device, so only things you want to be in your images (like stripped binaries).

Building Qt 5 qtbase module

First, get a copy of the qtbase module:
mkdir -p ~/Code/qt5
cd ~/Code/qt5
git clone git://gitorious.org/qt/qtbase.git
cd qtbase

Now configure qtbase with the following command: ./configure -prefix /usr -hostprefix $BSQUASK_HOST_DIR/usr -release -device pi -make libs \
-device-option CROSS_COMPILE=$BSQUASK_HOST_DIR/usr/bin/arm-raspberrypi-linux-gnueabi- \
-device-option DISTRO=bsquask -sysroot $BSQUASK_STAGING_DIR -no-neon -opensource -confirm-license

And build qtbase:
make

And install everything into your SDK with:
make install

Now if you added $BSQUASK_HOST_DIR/usr/bin to your PATH as suggested above, you will see that running which qmake shows the version of qmake you just built. This is what you will use to cross compile Qt5 projects for Raspberry Pi.

Building other Qt modules

Now that you have qmake built, building any other Qt modules is easy. Obtain the qtxmlpatterns, qtjsbackend, and qtdeclarative modules:
cd ~/Code/qt5
git clone git://gitorious.org/qt/qtxmlpatterns.git
git clone git://gitorious.org/qt/qtjsbackend.git
git clone git://gitorious.org/qt/qtdeclarative.git

Then build qtxmlpatterns:
cd ~/Code/qt5/qtxmlpatterns
qmake
make
make install

Then build qtjsbackend, which still needs an extra patch to properly support the hardfloat ABI on armv6:
cd ~/Code/qt5/qtjsbackend
git fetch https://codereview.qt-project.org/p/qt/qtjsbackend refs/changes/56/27256/2 && git cherry-pick FETCH_HEAD
qmake
make
make install

And finally for all that Qt Quick 2.0 awesomeness:
cd ~/Code/qt5/qtdeclarative
qmake
make
make install

The QML tools will not automatically be compiled if you followed the configure line above. So to compile qmlscene etc.: cd ~/Code/qt5/qtdeclarative/tools
qmake
make
make install

Now so far everything you built is either in the $BSQUASK_HOST_DIR or $BSQUASK_STAGING_DIR, but not actually part of your image yet. To install to your $BSQUASK_TARGET_DIR you need to do:
cp -dpf $BSQUASK_STAGING_DIR/usr/lib/libQt*.so.* $BSQUASK_TARGET_DIR/usr/lib
cp -dpfr $BSQUASK_STAGING_DIR/usr/plugins $BSQUASK_TARGET_DIR/usr
cp -dpf $BSQUASK_STAGING_DIR/usr/bin/qml* $BSQUASK_TARGET_DIR/usr/bin
cp -dpfr $BSQUASK_STAGING_DIR/usr/imports $BSQUASK_TARGET_DIR/usr

Then the easiest thing to do is create a new image with your extended SDK:
cd $BSQUASK_DIR
make

Then extract the generated tarballs to your sd card again.

Building QtWayland (libwayland)

The first thing you should do is get the wayland and qtwayland source code:
cd ~/Code/
git clone git://anongit.freedesktop.org/wayland/wayland
cd ~/Code/qt5/
git clone git://gitorious.org/qt/qtwayland.git

Wayland is a bit of a moving target, so qtwayland specifies a know-to-be-working sha1 for libwayland. So we need to make sure the wayland repo is pointed at this sha1. You can find out what sha1 to use by doing:
cat ~/Code/qt5/qtwayland/wayland_sha1.txt

The the sha1 is 94bb47020ae71336be5088824fee38bf3c8d51cc, then to update the wayland repo:
cd ~/Code/wayland
git checkout -b qtwayland 94bb47020ae71336be5088824fee38bf3c8d51cc
This creates a new branch called qtwayland, and resets it to commit 94bb47020ae71336be5088824fee38bf3c8d51cc.

Building the host tool wayland-scanner

The first thing you need to do is to build the native wayland-scanner utility. This tool is used to generate C code from Wayland protocol files, and needs to be run from the host machine when you are cross-compiling Wayland. This is the least savory part of the walkthrough, so bare with me:
cd ~/Code/wayland
./autogen.sh --prefix=$BSQUASK_HOST_DIR/usr
make
Then instead of doing make install, do:
cp src/wayland-scanner $BSQUASK_HOST_DIR/usr/bin

Then clean up the wayland folder, as we're going to reuse it:
make clean

Cross compiling libwayland

Now that we have wayland-scanner as part of our host tools, we can cross compile wayland:
cd ~/Code/wayland
./autogen.sh --host arm-raspberrypi-linux-gnueabi --prefix=$BSQUASK_STAGING_DIR/usr --disable-scanner
make
make install

Building the QtWayland Module

The prerequisites are now in place, so we can build the qtwayland Module:
cd ~/Code/qt5/qtwayland
qmake
make
make install

Deploy libwayland and qtwayland to the image

For libwayland:
cp -dpf $BSQUASK_STAGING_DIR/usr/lib/libwayland*.so.* $BSQUASK_TARGET_DIR/usr/lib

For qtwayland:
cp -dpf $BSQUASK_STAGING_DIR/usr/lib/libQt*.so.* $BSQUASK_TARGET_DIR/usr/lib
cp -dpfr $BSQUASK_STAGING_DIR/usr/plugins $BSQUASK_TARGET_DIR/usr
cp -dpfr $BSQUASK_STAGING_DIR/usr/imports $BSQUASK_TARGET_DIR/usr

Then rebuild the image and deploy to device as we did above.

Deploying directly to device

Most of the time you don't want to have to go through the process of making a new image each time you want to update a file on the system. This is also the case when you are testing the above libraries and their examples. Here is how you can deploy the above directly to your Raspberry Pi:
This assumes you have an entry in your /etc/hosts file for your Raspberry Pi's IP as "raspberrypi"

Copy Qt Libraries:
scp $BSQUASK_STAGING_DIR/usr/lib/libQt*.so.* root@raspberrypi:/usr/lib
Copy Qt Plugins:
scp -r $BSQUASK_STAGING_DIR/usr/plugins root@raspberrypi:/usr
Copy qml binaries (qmlscene): scp $BSQUASK_STAGING_DIR/usr/bin/qml* root@raspberrypi:/usr/bin
Copy QtQuick plugins:
scp -r $BSQUASK_STAGING_DIR/usr/imports root@raspberrypi:/usr
Copy Qt Examples (including example Compositors for qtwayland):
scp -r $BSQUASK_STAGING_DIR/usr/examples root@raspberrypi:/usr
Copy wayland libraries:
scp $BSQUASK_STAGING_DIR/usr/lib/libwayland*.so.* root@raspberrypi:/usr/lib

Building and Deploying Qt applications

So far the above demonstrates how you can build libraries, but not any examples of applications. Cross compiling Qt applications is quite simple now that we have qmake. Just run qmake on the .pro file of the project you want to build, and then run make

Tips and Tricks

I usually develop my code in Qt Creator, and this makes it fairly strait-forward to create, build, deploy to the Raspberry Pi. Then it's also possible to run or debug an application from Qt Creator on the device. To set this up though, (especially when dealing with libraries you need installed in your SDK and deployed to device) you have to keep a few things in mind.

When setting up .pro files LIB_DIR and INCLUDEPATH should reference areas inside of your Sysroot:
INCLUDEPATH += $$BSQUASK_STAGING_DIR/usr/include
LIB_DIR += $BSQUASK_STAGING_DIR/usr/lib
but for your "INSTALLS", these should be the location of where you want to be installed on device:
target.path = /usr/lib
This is needed for the "Deploy to device" feature to work. However the conflicts with where "make install" wants to install your files (in this case your target files would be installed in your system /usr/lib, instead of your sysroot). To work around this you must export the INSTALL_ROOT environment variable to the location of your sysroot:
export INSTALL_ROOT=$BSQUASK_STAGING_DIR
"make install" now installs your target files in $BSQUASK_STAGING_DIR/usr/lib