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.



22 comments:

  1. Hello thanks for your tutorial. I got this error when trying to make install qt (after compilation)


    make[4]: Nothing to be done for `install'.
    make[4]: Leaving directory `/home/aprado/work/qt-everywhere-opensource-src-5.2.0/qtconnectivity/examples/bluetooth/bttennis'
    cd scanner/ && ( test -e Makefile || /home/aprado/work/qt-everywhere-opensource-src-5.2.0/qtbase/bin/qmake /home/aprado/work/qt-everywhere-opensource-src-5.2.0/qtconnectivity/examples/bluetooth/scanner/scanner.pro -o Makefile ) && make -f Makefile install
    Project ERROR: Unknown module(s) in QT: quick
    make[3]: *** [sub-scanner-install_subtargets] Error 3
    make[3]: Leaving directory `/home/aprado/work/qt-everywhere-opensource-src-5.2.0/qtconnectivity/examples/bluetooth'
    make[2]: *** [sub-bluetooth-install_subtargets] Error 2
    make[2]: Leaving directory `/home/aprado/work/qt-everywhere-opensource-src-5.2.0/qtconnectivity/examples'
    make[1]: *** [sub-examples-install_subtargets] Error 2
    make[1]: Leaving directory `/home/aprado/work/qt-everywhere-opensource-src-5.2.0/qtconnectivity'
    make: *** [module-qtconnectivity-install_subtargets] Error 2

    ReplyDelete
    Replies
    1. I got the same problem so I did "sudo make install" and it worked.

      Delete
    2. I've reran the command "sudo make install" and still getting this error.

      Delete
  2. I just ignored this error and it seems to work ok. I am still working out the kinks.....

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Thank you, I have just tested Qt Build on my beaglebone black. It works very well.

    ReplyDelete
  5. Thank you for your tutorial, unfortunately when i launch configure i get :

    -device linux-beaglebone-g++: invalid command-line switch

    but i can't find how solve this (i'm using ubuntu to cross compile).

    Thank you

    ReplyDelete
  6. Are you using Qt 5.2.0?

    You could try to put the whole command line into a file and see if that helps.

    nano config.sh

    #!/bin/bash
    ../qt-everywhere-opensource-src-5.2.0/configure -v -opensource ...

    CTRL-O, Enter, CTRL-X
    > chmod +x config.sh
    > ./config.sh

    ReplyDelete
  7. Yes, i tried Qt 5.2.0 and i tried also to put the whole command line in a file ... but it doesn't works with the same error.
    I have to say that when i performed:
    > sudo apt-get install lsb
    this has installed some qt4 modules, is it right ?
    > sudo apt-get install ia32-libs
    this has not installed anything because libs was already included in some installed packages

    and when i tried to perform configure from qt5-2-host dir i got some errors so i had to launch configure from qt-everywhere.. folder but i think it shouldn't be important.

    I don't know what i can do because it seems not to accept -device option and i tried to dowload qt5 beta 1 and rc 1 version with no luck (always same error).
    There must be some problems in my environment that i can't understand.
    I don't know if this can be important but i have succesfully built QT 4 embedded
    before but with another toolchain.


    Thank you

    ReplyDelete
  8. You did create the linux-beaglebone-g++ file, right?

    Could you try running "configure" from your root directory. Don't do "./configure" or "./qt-everywhere/configure". I want to see if another configure is in your path.

    ReplyDelete
  9. Maybe it was true yesterday (really i didn't think about it) but now trying again from the beginning the configure process has started . Thank you very much for your precious help.

    ReplyDelete
  10. Hi
    Nice post. Most of the times i never spend a most of the time on any posts. But i really like you post and i read your post. Thank you for sharing and keep posting a more post on new topicsdave burke

    ReplyDelete
    Replies
    1. Thanks for the compliment! I tried to give the "why", for each task, instead of just giving a bland list of commands to type into a console.

      I should be getting back to Qt development soon, I had to fight some hardware issues with the BB-View 7.

      Delete
  11. Hi Louis,

    I've used the last image from git repo with 4D system 4DCape-43T touch display .
    The boot shows the lxde desktop but from a ssh session if I run the "analogclock -platform linuxfb" the CLI seems to be ok while on the display nothing appears.

    Any idea ?

    ReplyDelete
    Replies
    1. maybe people will be intersting : I remove the autoconnecting desktop manager by :
      "sudo update-rc.d lightdm disable" and on reboot it's ok.
      Well, the analog clock is still displayed after CTRL-C anyway. so now to find out to remove the app from the screen in ssh session.

      DL

      Delete
  12. Thanks for this great tutorial, it has been incredibly helpful.

    I needed to avoid the -platform execution argument because my app wasn't running on the BBB from Qt Creator because of the eglfs plugin wasn't present. When editing the linux-beaglebone-g++/qmake.conf file there is a line for QT_QPA_DEFAULT_PLATFORM which is set to 'eglfs'. When I set it to 'linuxfb' I don't get the error about eglfs not found without having to set the '-platform linuxfb'. I do get 'Failed to open tty Permission denied' and others but that's for more debugging later.

    David

    ReplyDelete
  13. Hey Louis (or anyone),

    Thanks for the great tutorial. I successfully used this to get my BBB working with Qt5.2. Unfortunately, I need Qt Quick 2 and Qt Quick Controls for my application, so I will need OpenGL. I've been having a lot of difficulty trying to get it to work.

    When configuring the build I keep getting this error: "The OpenGL ES 2.0 functionality test failed!". I tried mounting the SD card with the BBB image which has the OpenGL libs on it and setting the sysroot to this path and setting the QMAKE OpenGL vars to the /usr/include and /usr/lib paths. But no luck, still the same error.

    I know you mentioned that you were going to write up something about getting OpenGL working, but I haven't been able to find anything. Any chance you could point me in the right direction?

    Thanks,
    Jay

    ReplyDelete
  14. Hello Louis,
    Thanks for this tutorial. It's really helpful

    I followed the steps with QtSource 5.3.1, QtCreator 3.1.1 and Ubuntu 14.04 for the Beaglebone Black.

    When I try to run the analogclock example I receive this message:
    /usr/local/qt-5.3/examples/gui/analogclock/analogclock -platform linuxfb
    /usr/local/qt-5.3/examples/gui/analogclock/analogclock: /usr/lib/arm-linux-gnueabihf/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /usr/local/qt-5.3/lib/libQt5Core.so.5)

    Can you help me?

    Thanks in advance
    Ricardo

    ReplyDelete
    Replies
    1. It may be that you need to install gcc and/or other c libraries on the BBB, or you could have targeted a different gcc version if you cross compiled.

      Delete
  15. Hi,

    First of all thank you for a very extensive and useful tutorial. I really liked the "how" part in your tutorial.

    I have followed the steps are mentioned in the tutorial and was successful in installing qt5 in my ubuntu machine and then transferring it to BBB. I also installed qt creator version 3.0.0 which is based on Qt 5.2.0 GCC 4.6.1 64 bit.
    The linaro toolchain is the latest one.

    Now, when I am adding the kit with compiler and debugger I have a problem. When I am selecting my version of qt5 which I just installed it is giving this error.

    "No compiler can produce code for this Qt version. Please define one or more compilers."

    Kind of stuck here can't find any useful information on internet. May be someone here can help. I will be really thankful.

    Regards,
    Naqqash

    ReplyDelete
  16. Thanks a lot! Worked perfectly on bbb with ubuntu 14.04.

    ReplyDelete
  17. Thanks!! Works great on BBB with Machinekit debian. I don't know what to do about missing GL stuff though.

    ReplyDelete