Qt on beaglebone black screenThis tutorial shows you how to set up a Qt 5.2.1 cross compile environment for the Beaglebone Black on Ubuntu. I had some trouble in the past with this procedure, so here I show you how I accomplished this task.

I choose the Ubuntu 14.04 LTS image for the Beaglebone Black, because it will be supported from Canonical officially until April 2019 and it’s a very nice and minimalistic image. So in this part of the tutorial we will create an Ubuntu image with all needed packages.

In this tutorial, I will speak about two systems:

  • host: with host I mean your PC, running Ubuntu, where the cross compile environment will be set up and where you will be able to cross compile Qt application for the Beaglebone Black.
  • target: with target I mean the Beaglebone Black system.

Requirements

  • Beaglebone Black
  • micoSD (>= 2 GB) and an adapter for the PC
  • Ethernet cable

Prepare the microSD card (on host)

You can find the installation instructions on the armhf homeage, but for the completeness, i will show you this steps to. First we need to prepare the partitions on the microSD card.

Inset the microSD in your computer and check which device is your microSD with following command:

$ export DISK=/dev/sdc

 Now we have to create two partitions on this microSD card. One for the boot loader (u-boot) and one for the root file system (rootfs). Make shore the microSD card is not mounted.

Note: please be very careful in this step, you can delete your whole system if you choose the wrong device!! This will delete all data from your microSD card!!

$ lsblk

NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0 465,9G  0 disk 
├─sda1   8:1    0   200M  0 part /boot/efi
├─sda2   8:2    0    45G  0 part 
├─sda3   8:3    0 279,4G  0 part /
└─sda4   8:4    0 139,7G  0 part 
sdc      8:32   1   1,9G  0 disk 
└─sdc1   8:33   1   1,7G  0 part 

$ sudo fdisk $DISK

 Print the partition table using p to make sure this is the correct device. (In this example it is a 2 GB microSD card):

Command (m for help): p
Disk /dev/sdc: 1,9 GiB, 2002780160 bytes, 3911680 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device     Boot Start     End Sectors  Size Id Type
/dev/sdc1  *     2048 3481599 3479552  1,7G 83 Linux

 Delete all partitions (using d, enter):

Command (m for help): d
Selected partition 1
Partition 1 has been deleted.

Note: If you have more than one partition repeat this step until each partition is deleted on the microSD.

Create a new dos partition table (using o):

Command (m for help): o
Created a new DOS disklabel with disk identifier 0xe7264b01.

 Create a new 1 MiB partition for the boot loader (n, enter, enter, enter, 4095):

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): 
Partition number (1-4, default 1): 1
First sector (2048-3911679, default 2048): 
Last sector, +sectors or +size{K,M,G,T,P} (2048-3911679, default 3911679): 4095

 Change the partition type to W95 FAT32 (t, b):

Command (m for help): t
Selected partition 1
Hex code (type L to list all codes): b
If you have created or modified any DOS 6.x partitions, please see the fdisk documentation for additional information.
Changed type of partition 'Linux' to 'W95 FAT32'.

 

Enable the boot flag for this partition (a):

Command (m for help): a
Selected partition 1
The bootable flag on partition 1 is enabled now.    

Created a second partition for the rootfs with the rest of the storage (n, enter, enter, enter, enter):

Command (m for help): n
Partition type
   p   primary (1 primary, 0 extended, 3 free)
   e   extended (container for logical partitions)
Select (default p): 

Using default response p.
Partition number (2-4, default 2): 
First sector (4096-3911679, default 4096): 
Last sector, +sectors or +size{K,M,G,T,P} (4096-3911679, default 3911679): 

Created a new partition 2 of type 'Linux' and of size 1,9 GiB.

Now your partition table should look something like this:

Command (m for help): p
Disk /dev/sdc: 1,9 GiB, 2002780160 bytes, 3911680 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xe7264b01

Device     Boot Start     End Sectors  Size Id Type
/dev/sdc1  *     2048    4095    2048    1M  b W95 FAT32
/dev/sdc2        4096 3911679 3907584  1,9G 83 Linux

Write the partition table to the disk and exit using w:

Command (m for help): w

The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

Format the two partitions:

$ sudo mkfs.vfat ${DISK}1 -n BOOT
$ sudo mkfs.ext4 ${DISK}2 -L rootfs

Install u-boot to the first partition:

$ wget http://s3.armhf.com/dist/bone/bone-uboot.tar.xz
$ sudo mkdir /mnt/boot
$ sudo mount ${DISK}1 /mnt/boot
$ sudo tar xJvf bone-uboot.tar.xz -C /mnt/boot

Install rootfs to the second partition:

$ wget http://s3.armhf.com/dist/bone/ubuntu-trusty-14.04-rootfs-3.14.4.1-bone-armhf.com.tar.xz
$ sudo mkdir /mnt/rootfs
$ sudo mount ${DISK}2 /mnt/rootfs
$ sudo tar xJvf ubuntu-trusty-14.04-rootfs-3.14.4.1-bone-armhf.com.tar.xz -C /mnt/rootfs

Unmount the partitions:

$ sudo umount ${DISK}1  
$ sudo umount ${DISK}2  

Now insert the microSD into the Beaglebone Black, connect the ethernet cable
and power it on.


Install the build dependencies (on target)

In order to find out the IP address of the Beaglebone Black you can search it in your network with the nmap command. Assuming your router has the IP 192.168.1.1 you can use nmap as following:

$ sudo nmap -sP 192.168.1.1/24

You should get a list of all devices connected to the network. An example of a Beaglebone Black could look like this:

Nmap scan report for 192.168.1.54
Host is up (-0.093s latency).
MAC Address: 11:22:33:44:55:66 (Texas Instruments)

Note: the device with Texas Instruments in it is possibly the Beaglebone Black.

Connect to the new system with the user ubuntu and the password ubuntu:

$ ssh This email address is being protected from spambots. You need JavaScript enabled to view it. 
This email address is being protected from spambots. You need JavaScript enabled to view it.'s password: ubuntu

Update and upgrade all packages:

Note: the sudo password for root is also ubuntu. The ssh login for root is by default disabled. You can change that in the /etc/ssh/sshd_config by replacing the line PermitRootLogin without-password with PermitRootLogin yes. It’s recommended to set the root password first with `passwd`.

$ sudo apt-get update
$ sudo apt-get upgrade

Installing the kernel header files (on target)

If you want to build or cross compile kernel modules for the Beaglebone Black, you need to install the kernel header files for the kernel in this image. for that you can run following commands in your fresh system:

$ wget http://s3.armhf.com/dist/bone/linux-headers-3.14.4.1-bone-armhf.com.tar.xz
$ sudo tar xJvf linux-headers-3.14.4.1-bone-armhf.com.tar.xz -C /
$ rm linux-headers-3.14.4.1-bone-armhf.com.tar.xz

Installing build dependencies for Qt 5.2.1 (on target)

Since this tutorial shows hot to cross compile Qt 5.2.1 which is available in the repository, we need to install the build dependencies of the Qt packages. A good reference can be found here.

$ sudo apt-get build-dep qt5-default

Install all dependencies for libxcb:

$ sudo apt-get install "^libxcb.*" libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev

If you want to crosscompile the QtMultimedia module you will need:

$ sudo apt-get install libasound2-dev libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev

If you want to build the QtWebEngine:

$ sudo apt-get install libcap-dev libbz2-dev libgcrypt11-dev libpci-dev libnss3-dev build-essential libxcursor-dev libxcomposite-dev libxdamage-dev libxrandr-dev libdrm-dev libfontconfig1-dev libxtst-dev libasound2-dev gperf libcups2-dev libpulse-dev libudev-dev libssl-dev flex bison ruby

If you want to build QtConnectivity module (Blutooth support):

$ apt-get install bluez libbluetooth-dev bluetooth bluez-tools

If you are working with I2C you will also need the libi2c-dev:

$ apt-get install i2c-tools libi2c-dev

Clean up rootfs (on target)

In order to keep the cross compile rootfs as small as possible, you can delete all the downloaded packages, which are already installed:

$ sudo apt-get clean

Now power off the Beaglebone Black and insert the microSD in the host.

Set up the cross compile environment (on host)

Create the working directory, where the whole cross compile environment will be created:

$ sudo mkdir /opt/qt-beaglebone-black/
$ sudo chown $USER /opt/qt-beaglebone-black/
$ cd /opt/qt-beaglebone-black/

$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sda      8:0    0 465,9G  0 disk 
├─sda1   8:1    0   200M  0 part /boot/efi
├─sda2   8:2    0    45G  0 part 
├─sda3   8:3    0 279,4G  0 part /
└─sda4   8:4    0 139,7G  0 part 
sdc      8:32   1   1,9G  0 disk 
├─sdc1   8:33   1     1M  0 part 
└─sdc2   8:34   1   1,9G  0 part 

Create a backup of you rootfs:

$ sudo mount /dev/sdc2 /mnt/rootfs
$ cd /mnt/rootfs
$ sudo tar cpjfv /opt/qt-beaglebone-black/rootfs.tar.bz2 ./
$ sudo chown $USER /opt/qt-beaglebone-black/rootfs.tar.bz2

Cross compile Qt 5.2.1 for Beaglebone Black

For this whole procedure I have written a script which will do everything for you, but for the completeness I will explain what it does in the next chapter.

$ wget http://guh.guru/downloads/scripts/crosscompile-Qt_5.2.1-beaglebone-black.sh
$ chmod +x crosscompile-Qt_5.2.1-beaglebone-black.sh

Your folder should look like this before you start the script:

$ pwd
/opt/qt-beaglebone-black/

$ ls -l
crosscompile-Qt_5.2.1-beaglebone-black.sh
rootfs.tar.bz2

Now you can start the build process by running the script:

Note: please read the script carefully before you start it. The script is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.

./crosscompile-Qt_5.2.1-beaglebone-black.sh

Once the script is finished, you should be have a working crosscompile environment and can jump to the chapter Set up QtCreator or read the explanation during the build process.

Explanation of the script

Since this script is the result of quiet a few runns here is the manual procedure and explanation of the script steps.

Download Qt source code and the cross compiler

You can find the qt source code files here:

$ wget http://download.qt.io/archive/qt/5.2/5.2.1/single/qt-everywhere-opensource-src-5.2.1.tar.xz

$ md5sum qt-everywhere-opensource-src-5.2.1.tar.xz
0c8d2aa45f38be9c3f7c9325eb059d9d

$ tar xfv qt-everywhere-opensource-src-5.2.1.tar.xz

You can find the cross compiler files here:

$ wget http://releases.linaro.org/14.04/components/toolchain/binaries/gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux.tar.xz

$ md5sum gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux.tar.xz
44fbcca1478e477916bdf6a03b6ab85a

$ tar xfv gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux.tar.xz

Export all variables we need during the build process:

$ export CURRENT_DIR=`pwd`
$ export QT_SRCDIR="${CURRENT_DIR}/qt-everywhere-opensource-src-5.2.1"
$ export CC_DIR="${CURRENT_DIR}/gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux"
$ export CC="${CC_DIR}/bin/arm-linux-gnueabihf-"
$ export PREFIX="${CURRENT_DIR}/Qt-5.2.1"
$ export ROOTFS_DIR="${CURRENT_DIR}/rootfs"
$ export LOG_DIR="${CURRENT_DIR}/logfiles"
$ export NPROC=`nproc`

Create qmake mkspecs

Create linux-beaglebone-g++ device

$ cd ${QT_SRCDIR}/qtbase/mkspecs/devices/
$ cp -rv linux-beagleboard-g++ linux-beaglebone-g++
$ sed 's/softfp/hard/' <linux-beagleboard-g++/qmake.conf >linux-beaglebone-g++/qmake.conf

Create the linux-linaro-gnueabihf-g++ qmake configuration

$ cd ${QT_SRCDIR}/qtbase/mkspecs
$ cp -r linux-arm-gnueabi-g++/ linux-linaro-gnueabihf-g++/
$ export TO_REPLACE="arm-linux-gnueabi-"
$ sed "s|${TO_REPLACE}|${CC}|g" <linux-arm-gnueabi-g++/qmake.conf >linux-linaro-gnueabihf-g++/qmake.conf

Fix the library symbolic links

Since the library links in our Beaglebone Black rootfs point to point to the host roofs and not to the crosscompile rootfs thy need to be fixed. This script makes all absolute library symbolic links relative:

Note: this script is originally from https://gitorious.org/cross-compile-tools/cross-compile-tools.git.

$ cd ${CURRENT_DIR}
$ wget http://guh.guru/downloads/scripts/fixQualifiedLibraryPaths
$ chmod +x fixQualifiedLibraryPaths

$ sudo ./fixQualifiedLibraryPaths ${ROOTFS_DIR} ${CC}g++

Configure qtbase

$ cd ${QT_SRCDIR}/qtbase/

Now it’s time to run the configure script:

$./configure -prefix ${PREFIX} -sysroot ${ROOTFS_DIR} -device linux-beaglebone-g++ -xplatform linux-linaro-gnueabihf-g++ -device-option CROSS_COMPILE=${CC} -release -silent -opensource -confirm-license -continue -v -nomake examples -nomake tests 2>&1 | tee -a ${LOG_DIR}/qtbase-configure-log.txt 

Note: the output of the configure process and make process will be stored in the logfiles directory.

Once the configuration script is finished, your configuration should look like this:

Build options:
  Configuration .......... accessibility accessibility-atspi-bridge alsa audio-backend c++11 clock-gettime clock-monotonic compile_examples concurrent cross_compile cups dbus egl eglfs evdev eventfd fontconfig full-config getaddrinfo getifaddrs glib gtk2 gtkstyle iconv icu inotify ipv6ifname large-config largefile linuxfb medium-config minimal-config mremap neon nis no-harfbuzz opengl openssl openvg pcre png posix_fallocate precompile_header pulseaudio qpa qpa reduce_exports reduce_relocations release rpath shared silent small-config system-freetype system-jpeg system-zlib xcb xcb-glx xcb-render xcb-sm xcb-xlib xinput2 xlib xrender 
  Build parts ............ libs
  Mode ................... release
  Using C++11 ............ yes
  Using PCH .............. yes
  Target compiler supports:
    iWMMXt/Neon .......... no/yes

Qt modules and options:
  Qt D-Bus ............... yes (loading dbus-1 at runtime)
  Qt Concurrent .......... yes
  Qt GUI ................. yes
  Qt Widgets ............. yes
  JavaScriptCore JIT ..... yes (To be decided by JavaScriptCore)
  QML debugging .......... yes
  Use system proxies ..... no

Support enabled for:
  Accessibility .......... yes
  ALSA ................... yes
  CUPS ................... yes
  FontConfig ............. yes
  FreeType ............... system
  Iconv .................. yes
  ICU .................... yes
  Image formats: 
    GIF .................. yes (plugin, using bundled copy)
    JPEG ................. yes (plugin, using system library)
    PNG .................. yes (in QtGui, using bundled copy)
  Glib ................... yes
  GTK theme .............. yes
  Large File ............. yes
  mtdev .................. no
  Networking: 
    getaddrinfo .......... yes
    getifaddrs ........... yes
    IPv6 ifname .......... yes
    OpenSSL .............. yes (loading libraries at run-time)
  NIS .................... yes
  OpenGL ................. desktop
  OpenVG ................. yes-auto
  PCRE ................... yes (bundled copy)
  pkg-config ............. yes 
  PulseAudio ............. yes
  QPA backends: 
    DirectFB ............. no
    EGLFS ................ yes
    KMS .................. no
    LinuxFB .............. yes
    XCB .................. yes (system library)
      MIT-SHM ............ yes
      Xcb-Xlib ........... yes
      Xcursor ............ yes (loaded at runtime)
      Xfixes ............. yes (loaded at runtime)
      Xi ................. no
      Xi2 ................ yes
      Xinerama ........... yes (loaded at runtime)
      Xrandr ............. yes (loaded at runtime)
      Xrender ............ yes
      XKB ................ yes
      XShape ............. yes
      XSync .............. yes
      XVideo ............. yes
  Session management ..... yes
  SQL drivers: 
    DB2 .................. no
    InterBase ............ no
    MySQL ................ no
    OCI .................. no
    ODBC ................. yes (plugin)
    PostgreSQL ........... no
    SQLite 2 ............. no
    SQLite ............... yes (plugin, using bundled copy)
    TDS .................. yes (plugin)
  udev ................... no
  xkbcommon .............. yes (system library)
  zlib ................... yes (system library)

Build qtbase

Now we can build qtbase. With following command the build process will be logged in the logfiles/qtbase-build-log.txt file and all CPU’s will be used for compiling:

$ make -j$NPROC 2>&1 | tee -a ${LOG_DIR}/qtbase-build-log.txt

Once the build process has successfully finished you can install all files. This command will create a $CURDIR/Qt-5.2.1 folder where qmake and the other Qt tools for cross compiling will be installed. The cross compiled Qt libraries will be installed in rootfs/opt/qt-beaglebone-black/Qt-5.2.1/.

$ sudo make install

Build other qt modules

If you need other Qt modules like qtmultimedia or qtserialport you need to compile and install them. Since there is a certain dependency between the Qt modules, the order of the module compilation is important and can be found here:

http://qt-project.org/wiki/Qt_Library_Cross_Dependencies

In order to cross compile a Qt module, we need to use our fresh compiled qmake:

$ export QMAKE_CROSS="${PREFIX}/bin/qmake"
$ cd ${QT_SRCDIR}

Now you can start compiling the modules you need (for me following order worked great):

  1. qtgraphicaleffects
    $ cd qtgraphicaleffects
    $ ${QMAKE_CROSS} 2>&1 | tee -a ${LOG_DIR}/qtgraphicaleffects-qmake-log.txt
    $ sudo make -j${NPROC} 2>&1 | tee -a ${LOG_DIR}/qtgraphicaleffects-make-log.txt
    $ sudo make install
    $ cd ..
    
  2. qttools
    $ cd qttools
    $ ${QMAKE_CROSS} 2>&1 | tee -a ${LOG_DIR}/qttools-qmake-log.txt
    $ sudo make -j${NPROC} 2>&1 | tee -a ${LOG_DIR}/qttools-make-log.txt
    $ sudo make install
    $ cd ..
    
  3. qtscript
    ...
    
  4. qtserialport
  5. qtsensors
  6. qtimageformats
  7. qtsvg
  8. qtactiveqt
  9. qtxmlpatterns
  10. qtdeclarative
  11. qtquick1
  12. qtquickcontrols
  13. qtmultimedia
  14. qtconnectivity

Now you have a working Qt 5.2.1 cross compile environment for the Beaglebone Black. Since you can install Qt native from the repository, you can install qt5-default and all modulus you want on the target system.

Set up QtCreator

Now you can set up you QtCreator with the new cross compile environment. This will allow you to compile and deploy applications to the target Beaglebone Black over the network and follow the debug output in the QtCreater on the host.

Configure device

First we need to create a new Generic Linux Device, which will represent the Beaglebone Black.

  1. In the QtCreator main window click → ToolsOptions
  2. In the left menu click on → DevicesAdd...
  3. Generic Linux DeviceStart Wizard
  4. Fill out the data of your Beaglebone Black
  5. NextFinish

If the test was successful, you can continue.

Configure gcc

  1. In the QtCreator main window click → ToolsOptions
  2. In the left menu click on → Build & RunCompilersAddGCC
  3. Name: BeagleBone Black GCC
  4. Compiler path: /opt/qt-beaglebone-black/gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux/bin/arm-linux-gnueabihf-g++

Configure gdb

  1. In the QtCreator main window click → ToolsOptions
  2. In the left menu click on → Build & RunDebuggersAdd
  3. Name: BeagleBone Black GDB
  4. Path: /opt/qt-beaglebone-black/gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux/bin/arm-linux-gnueabihf-gdb

Configure Qt Version

  1. In the QtCreator main window click → ToolsOptions
  2. In the left menu click on → Build & RunQt VersionAdd
  3. Brows to our crosscompiled qmake, which sould be in /opt/qt-beaglebone-black/Qt-5.2.1/bin/qmakeOpen
  4. Version name: Qt 5.2.1 (BeagleBone Black)

Configure Kit

  1. In the QtCreator main window click → ToolsOptions
  2. In the left menu click on → Build & RunKitsAdd
  3. Name: Beaglebone Black
  4. Next to the name you can set an icon.
  5. Device: Your configured Beaglebone Black device
  6. Sysroot: /opt/qt-beaglebone-black/rootfs
  7. Compiler: BeagleBone Black GCC
  8. Debugger: BeagleBone Black GDB
  9. Qt Version: Qt 5.2.1 (BeagleBone Black)

That’s it. Now you can add the Kit to your project and press the play button!!!

 

 

 

 

Add comment


Security code
Refresh