Showing posts with label Qt. Show all posts
Showing posts with label Qt. Show all posts

Monday, January 19, 2015

Howto: Build Octal Beaglebone Black Cluster

Compiling Qt is getting old. While my applications are not that big, I find myself building Qt from source more often that I would like. I have cross compiled Qt on an x86 Ubuntu machine, but getting the configuration script to properly detect all of the modules is time consuming.

My first idea was to get a few Beaglebones so that I could be building multiple versions at any given time. This worked well, but it still took 20+ hours to get a testable output. If only there was a way to get these Beaglebones to help each other out......ah, but there is!

Enter distcc. Distcc is nice in that it is simply a wrapper around your existing build commands. This means it is easy to setup and use. Distcc works by inserting itself between the make script and the compiler (gcc or g++), which it accomplishes through the standard CC and CXX command line options available through make. By redirecting gcc and g++ commands through distcc, you can get a parallel build across machines using the normal make -j option.

Overview

  • Configure hardware
  • Install image
  • Install packages
  • Configure Main build client
  • Configure compile hosts
  • Run


Hardware

  • 8 Beaglebone Blacks (2 Rev. A6A, 1 Rev. B, 3 Rev. C, 2 Element 14 Rev. C)
  • 16 port Ethernet Switch (N-tron 516TX)
  • 50 Watt 5V DC Power Supply (Omron or Astrodyne)
  • DHCP Server (Asus RT-N56U)
There is nothing special about the hardware. As you can see, I used a wide variety of Beaglebone versions from two suppliers. The support structure is made of 20 mm extruded aluminum and an acrylic sheet:



Software Installation

Use the default operating system image or download a Debian console eMMC flasher such as BBB-eMMC-flasher-debian-7.7-console-armhf-2014-10-29-2gb.img.xz found at the elinux.org site.

Add the required tools:
>sudo apt-get install distcc distcc-pump g++ make


Compile Hosts Configuration

Choose one Beaglebone to set aside as the main build client. Ideally this would be the Beaglebone with the most memory (RAM and filesystem). The other seven "workers" will be referred to as compile hosts. In order to simplify the calling of distcc on the main build client, we need to give our workers hostnames. Run the following three commands on each of them:
> sudo nano /etc/hostname
> sudo nano /etc/hosts
> sudo hostname boris


In the 'hostname' and 'hosts' files, replace the default hostname (usually "beaglebone") with the desired hostname, which in the example above would be "boris".

A reboot will force an update to the hostname, but before we do that, we need to tell distcc to start a service at boot and to allow local network traffic. Edit the first few lines of the /etc/default/distcc config file:
> sudo nano /etc/default/distcc
to look something like this:
# Defaults for distcc initscript
# sourced by /etc/init.d/distcc

#
# should distcc be started on boot?
#
# STARTDISTCC="true"

STARTDISTCC="true"

#
# Which networks/hosts should be allowed to connect to the daemon?
# You can list multiple hosts/networks separated by spaces.
# Networks have to be in CIDR notation, f.e. 192.168.1.0/24
# Hosts are represented by a single IP Adress
#
# ALLOWEDNETS="127.0.0.1"

ALLOWEDNETS="192.168.0.0/24"


Reboot to commit the changes.

Main Build Client Configuration

Like we set up on the workers, we need to give the master a hostname. Two of the commands are identical:
> sudo nano /etc/hostname
> sudo hostname pluto

but we need to add the workers, in addition to the master hostname, to the hosts file:
> sudo nano /etc/hosts

Which, if your master unit is named "pluto", will look something like this:
127.0.0.1       localhost
127.0.1.1       pluto
192.168.0.106    droopy
192.168.0.71     astro
192.168.0.232    dogbert
192.168.0.9      scooby
192.168.0.100    underdog
192.168.0.139    snoopy
192.168.0.180    goofy
192.168.0.41     peabody
192.168.0.20     brian

That's it! We are now ready to run distcc.

Run distcc

Before we run distcc, we need to setup a couple of environment variables.

The first variable is handy if you are having trouble talking to workers, or would like more feedback from distcc:
> export DISTCC_VERBOSE=1

I found the extra output helpful in diagnosing issues.

The following command is necessary any time the list of client names changes. The order is important, but really only matters if you include the master in the worker list. Due to the limited resources on the Beaglebone, I chose not to allow normal building on the master.
> export DISTCC_POTENTIAL_HOSTS='astro dogbert snoopy underdog droopy scooby goofy peabody brian'

We can now call distcc, but instead of calling it directly, we are going to use the distcc-pump tool. Distcc-pump parses the "DISTCC_POTENTIAL_HOSTS" variable and automatically configures and starts the appropriate distcc services.

Most of the websites that show examples for distcc show something like this:
distcc-pump make -j12 CC="distcc"
which works, but when compiling large projects that are written in both C and C++, like Qt, that command only compiles SOME of the code on the cluster. Needless to say, this is bad and the master Beaglebone dies a quick death due to memory loss.

The workaround took me a while to figure out, but is really simple. Because distcc is smart enough to figure out which compiler to use, call this line instead:
> distcc-pump make -j12 CC=distcc CXX=distcc


Now that you have a working compiler, you can play around with the -j12 parameter to get the best results. Many distcc examples claim that this parameter could be very large, but that does not work for compiling a large project like Qt. The main choke point is the amount of RAM and the huge memory requirements for the include server.

Building Qt and Optimizations

Like I alluded to earlier, I did manage to compile Qt on the cluster, but it wasn't "clean". After a half hour of compiling, the master Beaglebone runs out of memory. It's not that big of a deal, because you can just run the distcc-pump command again, but I wanted to see if I could help it out.

To do this, I created 1 Gb of swap space on a micro SD card. This helped, but only extended the build time to an hour before the memory was full and the Beaglebone started spending most of it's time paging memory.

The ultimate solution was to use a master with more memory. I chose a Wandboard i.MX6 paired with a SATA HD, which worked well.

Here are the resultant compile times for various configurations:
Single Beaglebone                        ~19-20 hours
Beaglebone Master + 7 Beaglebone Workers ~5-6 hours
Beaglebone Master + 9 Beaglebone Workers ~5 hours
Wandboard Master + 8 Beaglebones         <4 hours

References


Monday, March 10, 2014

Qt 5.2.1 Beaglebone Binaries

Overview

So, how did I create these binaries....well I thought it would be fun to see how long it would take the Beaglebone to compile Qt. Here is a brief description of my setup.

I powered the Beaglebone with a 5v power supply and booted a Debian rootfs using TFTP and NFS (a future post will explain how to configure this) so I could utilize the large HD of my Linux host. After compiling and installing Qt, the total root filesystem usage is around 3 Gb. The actual compile took about 21 hours, which includes compiling all examples and plugins.

Configuration

I created a simple shell script to modify the Qt source, with the Beaglebone configuration, and run the Qt configuration script:
#!/bin/sh
# Create beaglebone hard float configuration file
cd qt-everywhere-opensource-src-5.2.1/qtbase/mkspecs/devices/
cp -r linux-beagleboard-g++ linux-beaglebone-g++
sed 's/softfp/hard/' <linux-beagleboard-g++/qmake.conf >linux-beaglebone-g++/qmake.conf
# Run configuration
cd ../../../
./configure -v -opensource -confirm-license -prefix /usr/local/qt-5.2 -no-largefile -no-accessibility -qt-zlib -no-gif -qt-libpng -qt-libjpeg -no-nis -no-cups -device linux-beaglebone-g++


This produced the following summary:
   Configure summary
Build type:    linux-g++ (arm, CPU features:)
Platform notes:
            - Also available for Linux: linux-kcc linux-icc linux-cxx
        
qmake vars .......... styles += mac fusion windows DEFINES += QT_NO_MTDEV QT_CFLAGS_DBUS = -I/usr/include/dbus-1.0 -I/usr/lib/arm-linux-gnueabihf/dbus-1.0/include   QT_LIBS_DBUS = -ldbus-1   QT_CFLAGS_GLIB = -pthread -I/usr/include/glib-2.0 -I/usr/lib/arm-linux-gnueabihf/glib-2.0/include   QT_LIBS_GLIB = -pthread -lgthread-2.0 -lrt -lglib-2.0   QT_CFLAGS_PULSEAUDIO = -D_REENTRANT -I/usr/include/glib-2.0 -I/usr/lib/arm-linux-gnueabihf/glib-2.0/include   QT_LIBS_PULSEAUDIO = -lpulse-mainloop-glib -lpulse -lglib-2.0   DEFINES += QT_NO_LIBUDEV QMAKE_CFLAGS_XCB =   QMAKE_LIBS_XCB = -lxcb   QMAKE_CFLAGS_DIRECTFB = -D_REENTRANT -I/usr/include/directfb   QMAKE_LIBS_DIRECTFB = -ldirectfb -lfusion -ldirect -lpthread   sql-drivers =  sql-plugins =  sqlite qmake switches ......... 
Build options:
  Configuration .......... alsa audio-backend c++11 clock-gettime clock-monotonic compile_examples concurrent dbus directfb evdev eventfd full-config getaddrinfo getifaddrs glib iconv inotify ipv6ifname large-config linuxfb medium-config minimal-config mremap neon no-gif no-harfbuzz opengl openssl pcre png posix_fallocate precompile_header pulseaudio qpa qpa reduce_exports reduce_relocations release rpath shared small-config system-freetype xcb xcb-qt xkbcommon-qt xlib zlib 
  Build parts ............ libs tools examples
  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 .......... no
  ALSA ................... yes
  CUPS ................... no
  FontConfig ............. no
  FreeType ............... system
  Iconv .................. yes
  ICU .................... no
  Image formats: 
    GIF .................. no
    JPEG ................. yes (plugin, using bundled copy)
    PNG .................. yes (in QtGui, using bundled copy)
  Glib ................... yes
  GTK theme .............. no
  Large File ............. no
  mtdev .................. no
  Networking: 
    getaddrinfo .......... yes
    getifaddrs ........... yes
    IPv6 ifname .......... yes
    OpenSSL .............. yes (loading libraries at run-time)
  NIS .................... no
  OpenGL ................. desktop
  OpenVG ................. no
  PCRE ................... yes (bundled copy)
  pkg-config ............. yes 
  PulseAudio ............. yes
  QPA backends: 
    DirectFB ............. yes
    EGLFS ................ no
    KMS .................. no
    LinuxFB .............. yes
    XCB .................. yes (bundled copy)
      MIT-SHM ............ yes
      Xcb-Xlib ........... no
      Xcursor ............ yes (loaded at runtime)
      Xfixes ............. yes (loaded at runtime)
      Xi ................. yes (loaded at runtime)
      Xi2 ................ no
      Xinerama ........... yes (loaded at runtime)
      Xrandr ............. yes (loaded at runtime)
      Xrender ............ no
      XKB ................ yes
      XShape ............. yes
      XSync .............. yes
      XVideo ............. yes
  Session management ..... yes
  SQL drivers: 
    DB2 .................. no
    InterBase ............ no
    MySQL ................ no
    OCI .................. no
    ODBC ................. no
    PostgreSQL ........... no
    SQLite 2 ............. no
    SQLite ............... yes (plugin, using bundled copy)
    TDS .................. no
  udev ................... no
  xkbcommon .............. yes (bundled copy)
  zlib ................... yes (bundled copy)
NOTE: libxkbcommon 0.2.0 (or higher) not found on the system, will use 
the bundled version from 3rd party directory.
NOTE: Qt is using double for qreal on this system. This is binary incompatible against Qt 5.1.
Configure with '-qreal float' to create a build that is binary compatible with 5.1.

If you've tried cross compiling Qt, from my other posts, you will notice a lot more modules are enabled in this build.

I've tested a few examples and they all work, but I have not tested everything (haven't been able to test touch screen stuff yet). The examples default to using X11, if you want to use the linuxfb, add '-platform linuxfb' to the command line options. For example:
> analogclock -platform linuxfb

Here are two versions of binaries, one that includes examples (78 Mb) and one that does not (36 Mb).

MD5SUM:
9395fc70f576e58b68df7d732a002abb  qt-5.2-no-examples.tgz
f698f038166c4b2f65cec40056e23db2  qt-5.2.tgz

Extract to /usr/local, as the tarball contains the qt-5.2 folder in it.

If you want to try your hand at compiling applications on the Beaglebone, these packages have a native qmake included. Don't forget to add /usr/local/qt-5.2/bin to your path.

Have fun!

Thursday, January 16, 2014

Bare Metal Qt 5.2 on BeagleBone Black Ubuntu - Part 3

Overview

With Qt 5.2 working on the BeagleBone Black, created in Part 1 and Part 2, now it is time to compile a "Hello World" application. Assumptions:
  • You are using an Ubuntu x64 host for creating Qt applications
  • You have a Linaro toolchain located under /usr/local/linaro
  • You have a BeagleBone connect to your host PC via a LAN

Downloads

No need to compile our own Qt Creator, just download it:

Video Tutorials

Derek Molloy has three excellent videos about Qt on the BeagleBone. I suggest you start with these, as it will make following these instructions easier.

Setup Toolchain Environment

Open Qt Creator
Go to Tools -> Options

Add a new Device
Click on "Devices" from the list on the left
Click the "Add..." button on the upper right
Select Generic Linux Device
Click "Start Wizard" button
Enter "BBB - Ubuntu" for the name
Enter IP, and user information.
Click "Next" button
Click "Finish" button
Verify that the test connection was successful

Add a new Compiler
Click on the "Build & Run" item from the list on the left
Click on the "Compilers" tab
Click the "Add" drop down list button and select GCC
Change the name to "Linaro GCC"
Click the "Browse..." button next to the "Compiler path" field
Enter "/usr/local/linaro/bin/" into the filename field and click "Open"
Select "arm-linux-gnueabihf-g++" and click "Open" again
Click the "Apply" button

Add a new Debugger
Click on the "Debuggers" tab
Click the "Add" button
Enter "Linaro GDB" for the name
Click the "Browse..." button next to the Path field
Select "arm-linux-gnueabihf-gdb" and click "Open"
Click the "Apply" button

Add a new Qt Version
Click on the "Qt Versions" tab
Click the "Add..." button
Navigate to "/usr/local/qt-5.2/bin/qmake"
Click the "Open" button
Click the "Apply" button

Add a new Kit
Click on the "Kits" tab
Click the "Add" button
Change name to "BBB Kit"
Ensure that the device type is "Generic Linux Device"
Ensure that the device is "BBB - Ubuntu"
Select the "Linaro GCC" compiler from the Compiler drop down list button
Select the "Linaro GDB" debugger from the Debugger drop down list button
Select the "Qt 5.2.0 (qt-5.2)" version from the "Qt Version" drop down list button
Click the "Ok" button

Create a New Console Project

Under the Welcome page, Click the "New Project" button
Select "Applications" from the list on the left
Select "Qt Console Application"
Click the "Next" button
Enter "HelloWorld" in the name field
Change the target directory, if you like
Click on the "Next" button
Review the details and then click on the "Next" button
Click on the "Finish" button

Modify Auto-Generated Project

Edit main.cpp to look like this:

#include <QCoreApplication>
#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
   cout << "Hello World!" << endl;
   return a.exec();
}

This will build locally, but we want it to auto deploy to the BeagleBone. That's coming up next...

Create Deploy Configuration

Add the following three lines to HelloWorld.pro after the "TARGET=HelloWorld" line

   target.files = HelloWorld
   target.path = /home/ubuntu
INSTALLS += target

That's it, now Qt Creator will automatically deploy the files before a debug or run.


Install GDB Server

This is required in order to debug from Qt Creator running on our host PC. This only needs to be done once. Issue this command on the Beaglebone:

> sudo apt-get install gdbserver

Now you can press the Debug icon (looks like a play arrow) in Qt Creator and it will automatically scp the binary to the BeagleBone and start a remote GDB server session.

Create a GUI Project

Under the Welcome page, Click the "New Project" button
Select "Applications" from the list on the left
Select "Qt Gui Application"

Note: This option may not show up. If Qt Creator does not see the Qt 5.2 build as supporting GUI applications,  you can choose "Qt Widgets Application", but this may give different results. The other option is to install a distro version of Qt and make Qt Creator aware of it. This will make the Gui option visible in the project creation section. Nevermind, this is a difference between Qt Creator 2.8 and 3.0. The source generated, for either option, is identical.

Click the "Next" button
Enter "HelloWorldGUI" in the name field
Change the target directory, if you like
Click on the "Next" button
Review the details and then click on the "Next" button
Click on the "Finish" button

Modify Auto-Generated Project

Perform the same .pro file changes, as the console project, to deploy the project to the Beaglebone.

Friday, January 10, 2014

Bare Metal Qt 5.2 on BeagleBone Black Ubuntu - Part 2

Overview

For the impatient, I now have a precompiled tar of Qt 5.2.1 (for installation on a Beaglebone), see my blog post for more info...

Now that we have our development environment setup from Part 1, I will now guide you through the steps to compile Qt 5.2. This guide assumes the following:
  • That Ubuntu host machine is up-to-date
  • The host machine has the necessary utilities installed
  • Contains a folder, in the home directory, with the Qt source
  • The toolchain is installed under /usr/local/, which, for this guide, is in the linaro directory.

Downloads

Download these files, if you still need to flash Ubuntu onto the BeagleBone Black:

Create Device Configuration

Before we can call the Qt configuration script, we need to create a device configuration file so Qt knows how to generate the proper makefiles. Let's start by diving deeper into the Qt source folders.

> cd                                                             
> cd qt-everywhere-opensource-src-5.2.0/qtbase/mkspecs/devices   
> ls                                                             

The directory list will reveal 17 devices that we can target with Qt, of which, one of those is linux-beagleboard-g++. Let's make a copy of that device directory and then modify the qmake.conf file for our toolchain.

> cp -r linux-beagleboard-g++ linux-beaglebone-g++               
> nano linux-beaglebone-g++/qmake.conf                           

We'll start by modifying the comment (line 2) to reflect this new file's target hardware, because good comments are important :)
# qmake configuration for the BeagleBone and BeagleBone Black boards
 Next we need to change the compiler flags. The Linaro toolchain uses hardfloat so we need to change the "-mfloat-abi=softfp" option to "-mfloat-abi=hard" on line 29.
COMPILER_FLAGS = -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=hard
Save your changes and exit nano: CTRL-O, Enter, CTRL-X.

Create Platform Configuration

We need to create one more configuration before we call the Qt configuration script. Similar to a device configuration, we need to point to our platform compiler. In this case, I use the same linaro toolchain compiler. (I tried running the make without a -xplatform defined, because I thought it was not necessary....wrong!) 

Let's start by making a copy of an existing configuration file:

> cd                                                             
> cd qt-everywhere-opensource-src-5.2.0/qtbase/mkspecs           
> cp -r linux-arm-gnueabi-g++ linux-linaro-gnueabihf-g++         

Now let's modify the qmake.conf file:

> nano linux-linaro-gnueabihf-g++/qmake.conf                     

Comments first (line 2):
# qmake configuration for building with Linaro hardfloat toolchain.
Next we need to modify all 8 lines of compiler paths to point to our Linaro toolchain. We can do this two ways:

  • By using the -device-options CROSS_COMPILE tag
  • By entering the full path
I chose the first option because I just copied the device configuration file, removed unused parts based on the linux-arm-gnueabi-g++ file (opengl, calls to device_config, etc), and modified the paths (changed ../../ to ../) to common headers. But I would recommend using the full path method because the configuration script may not enforce a "-device-option" tag for a "-xplatform" tag like it does for a "-device" tag.

So lets add the full path to qmake.conf. Change each line from this:
QMAKE_* = arm-linux-gnueabi-*
to
QMAKE_* = /usr/local/linaro/bin/arm-linux-gnueabihf-* 
In other words, leave the suffixes (gcc/g++/ar/objcopy/nm/strip) and options (cqs/-P) unchanged. As an example, the QMAKE_AR line (line 20) would become:
QMAKE_AR  = /usr/local/linaro/bin/arm-linux-gnueabihf-ar cqs
Once you have modified all 8 lines, save your changes and exit nano: CTRL-O, Enter, CTRL-X.

Configure Qt

Now we are ready to configure Qt. This is a relatively painless operation, but took me a while to discover which command line options were required. A lot of the options that were available in Qt 4 are no longer valid in Qt 5. We can ask the configuration script what options are available, but first we need to change our working directory to the build folder:

> cd                                                             
> cd qt-5.2-host                                                 
> ../qt-everywhere-opensource-src-5.2.0/configure --help         

This outputs several pages of information, which you can study later; while you are waiting for Qt to compile. But for now, let's run configure with these parameters:

> ../qt-everywhere-opensource-src-5.2.0/configure \              
   -v \                                                          
   -opensource \                                                 
   -confirm-license \                                            
   -prefix /usr/local/qt-5.2 \                                   
   -no-largefile \                                               
   -no-accessibility \                                           
   -qt-zlib \                                                    
   -no-gif \                                                     
   -qt-libpng \                                                  
   -qt-libjpeg \                                                 
   -no-nis \                                                     
   -no-cups \                                                    
   -xplatform linux-linaro-gnueabihf-g++ \                       
   -device linux-beaglebone-g++ \                                
   -device-option CROSS_COMPILE=/usr/local/linaro/bin/arm-linux-g
nueabihf-                                                        

Here is a brief description of each option

-v                         verbose output, which is helpful for problem solving
-opensource        build Qt as the opensource version
-confirm-license  automatically say "yes" to the LGPL license terms
-prefix                  the destination folder for binaries when a 'make' is performed
-no-largefile        no 4Gb file support
-no-accessibility  don't include accessibility, to save space?
-qt-zlib                 use the Qt version of zlib (instead of system)
-no-gif                 no GIF support
-qt-libpng            use the Qt version of libpng (instead of system)
-qt-libjpeg           use the Qt version of libjpeg (instead of system)
-no-nis                no Network Information Service support
-no-cups              no print support
-xplatform          defines which qmake.conf file to use for building libraries/plugins/examples
-device               defines which qmake.conf file, in the device folder, to use for building
-device-option    this is required, when -device is used, to point to the cross compiler binary

The reasoning behind why I chose these options is simple: these were the only options that worked from the  Building Qt for Embedded Linux web page., which is written for Qt 4.8.

Note: This is a work in progress, and as such the mouse, touchscreen, and GUI elements are not fully functional. Console applications seem to be working fine.

Building Qt

The configure script has compiled a host version of qmake, automatically detected what modules are available to build, determined what compiler optimizations are available,  and has created makefiles in the source folders. So now what? Well, that's easy, the configure script prints it out when it finishes:

> make -j3 

The -j3 option tells the compiler how many jobs (aka threads) to run simultaneously. Your number of CPU cores minus one is a good number for a virtual machine host. Number of cores plus one is a good number for native hosts.

My host PC has an Intel i7-3540M quad-core processor and 8 Gb of RAM. I created the VM with four cores and assigned 3 Gb of RAM. It finished the compile in about 20 to 30 minutes.

Tasks While Waiting

Since it is going to take a while, let's setup the BeagleBone Black with our embedded Ubuntu image. Follow the instructions on this site to create a card and update the BBB eMMC. It should only take a few minutes.

Once you have a working Ubuntu on the BBB, we need to remove an old version of Qt, 5.0.2

> sudo apt-get remove libqt5core5                                

This will clear up the /usr/lib/arm-linux-gnueabihf folder of the old Qt libraries.

We need a way to transfer files to the BeagleBone. This can be via SD or USB, but I prefer connecting it to my LAN and using 'scp'. You can find the IP address of the BeagleBone by issuing the following command:

> ifconfig                                                       

Under the eth0 adapter listing (or wlan0 if using WiFi) you will find the "inet addr" field. Write this down, or remember it, as this is what you use for the host name with the scp command:

> scp source_file username@host:remote_path

But that will have to wait until the build is done....

Post Build

When the build is done, Qt is ready to be installed. The following command will create the directory, specified by the -prefix target when you ran the configuration script, and fill it with binaries.

> make install                                                   

Now let's go explore the installation....

> cd /usr/local/qt-5.2                                           

Under this directory you will find eight more folders, of which a few are of interest:

  • bin - host binary of qmake, and other utilities
  • examples - target binaries for testing our build
  • lib - .so libraries for our target
  • plugins - our platform gui drivers


Copy Binaries to BeagleBone

My preferred method is to use 'scp' to copy the files over the LAN to the BeagleBone. The following commands will copy the entire Qt folder to your BeagleBone home folder:

> cd /usr/local                                                  
> scp -r qt-5.2 ubuntu@192.168.7.2:/home/ubuntu/qt-5.2           

Replace 'ubuntu' with the user account that you use on the BeagleBone. Replace '192.168.7.2' with the IP address of your BeagleBone. It will take a couple minutes, depending on your network speed. You can reduce the size, by about 1/3, if you only transfer the four folders: examples, lib, plugins, and qml.

The Qt libraries are now on the BeagleBone, but they are in the wrong directory. So, now we need to log into the BeagleBone, either via 'ssh' or through the console, and move them to the proper location:

bbb> sudo mv /home/ubuntu/qt-5.2 /usr/local                      

Test Installation

Everything should be good to go, so let's run a couple examples to verify it. First let's try a console application:

bbb> /usr/local/qt-5.2/examples/network/dnslookup www.google.com 

Now for a GUI application. I recommend calling this from a ssh session, because a local session will take over the screen and you will not be able to get it back until you reboot the BeagleBone.

bbb> /usr/local/qt-5.2/examples/gui/analogclock/analogclock      

Hmm, it doesn't work! Well, our device configuration, that we copied, sets the GUI to default to 'eglfs'. We don't have this plugin, because we didn't configure OpenGL support. So, to get around this, we need to explicitly define the platform. Add this to the previous command:

 -platform linuxfb                                               

Congratulations, you now have a working Qt 5.2 on your BeagleBone Black!

Conclusion

Part 3 shows how to configure Qt Creator for application development.

Sources

Here are some web pages that I used for inspiration.



Thursday, January 9, 2014

Bare Metal Qt 5.2 on BeagleBone Black Ubuntu - Part 1

Overview

This part will guide you through the steps to create a working cross compile platform for the Beaglebone. I will try to keep it generic enough that you could use any toolchain and target distro, but this is my target:
  • BeagleBone Black Rev A6
  • Saucy Ubuntu 13.10 with Kernel 3.8.13-bone32 (12/13/2013) installed to eMMC
  • CircuitCo LCD7 Rev A3
See Part 2 for configuring and building Qt. 

Downloads

Download these files while you read the instructions below...


Setup Generic Virtual Machine

Follow these instructions to create and setup a vanilla Ubuntu VM. If you already have a VM or are going to use your host Ubuntu install, proceed to the "Install Compiler Prerequisites" section.
  1. Install Virtual Box
  2. Create a new Virtual Machine
    1. Enter a name, such as "Ubuntu Qt Builder"
    2. Change Type to "Linux", if it hasn't automatically done so.
    3. Change Version to "Ubuntu (64 bit)"
    4. Specify memory size, at least 1.5 Gb for better compiling performance.
    5. Create a new virtual hard drive (ignore size recommendation for now)
    6. Select VDI
    7. Select Dynamically allocated
    8. Set size to at least 40 Gb (it's dynamic, so why limit yourself)
    9. Once the virtual machine is created, change the advanced settings
      1. Click the Settings button and then select "System" from the list on the left
      2. Click the "Processor" tab and change the Processors to something greater than 1
      3. Select "Display" from the list on the left
      4. Max out the video memory
      5. Select "Storage" from the list on the left
      6. Click on the empty CD drive under the Storage Tree
      7. Under the attributes section, click the CD symbol and select "Choose a Virtual CD/DVD disk file"
      8. Point it to your Ubuntu ISO.
      9. Adjust other virtual machine settings as desired.
  3. Start the virtual machine and perform the Ubuntu Install
  4. After the install completes, reboot the virtual machine. Don't forget to hit enter to "eject" the boot CD when it prompts.
  5. Let it install the 200+ updates
  6. After another reboot, install Guest Additions by clicking on the Devices menu of the running VM, and then selecting "Install Guest Additions..." (You may have to do this again after Ubuntu installs future updates)

Install Compiler Prerequisites

Since we are running a 64 bit host OS, we need to install the 32 bit libraries to run some of the build tools. We also need the Linaro headers. Follow these instructions to install both of these required packages
  1. Open a new Terminal or xterm window
  2. Type the following to install the Linaro headers and 32 bit compatibility libraries
> sudo apt-get install lsb                          
> sudo apt-get install ia32-libs                       

Extract Qt Source

Perform this step to expand the source tarball into your home directory. It will reside under the tarball directory of "qt-everywhere-opensource-src-5.2.0". This can be done in a new terminal window, while the prerequisites are being installed.

> cd                                                   
> tar -zxf qt-everywhere-opensource-src-5.2.0.tar.gz   

Now we create a couple of folders for our shadow builds. This helps keep the main source folder clean of configuration files and binaries.

> mkdir qt-5.2-host                                    
> mkdir qt-5.2-target                                  


Extract Linaro Toolchain

I chose to use the Linaro toolchain because it came highly recommended and the Ubuntu cross compile chain does not include a g++ binary, which will be required to compile Qt.

Issue these commands to extract the Linaro toolchain, change the directory name, and move it to a global location:

> tar -Jxf gcc-linaro-arm-linux-gnueabihf-4.8-2013.04-20130417_li nux.tar.xz                                                       
> mv gcc-linaro-arm-linux-gnueabihf-4.8-2013.04-20130417_linux \ 
 linaro                                                          
> sudo mv linaro /usr/local                                      
  

Conclusion

You should now have a working Ubuntu virtual machine that is:

  • Up-to-date
  • Has necessary host utilities installed
  • Contains a folder, in the home directory, with the Qt source
  • Has the Linaro toolchain installed under /usr/local/linaro


Continue on to Part 2 for the configuration and building of Qt.