Revisiting LTIB and Qt on i.MX51 and i.MX53

Published on December 11, 2011

Archived Notice

This article has been archived and may contain broken links, photos and out-of-date information. If you have any questions, please Contact Us.

In a previous post, we walked through the process of building Qt using the LTIB tool, but we were a bit cavalier about the steps involved.

Since that time, we've been shipping demo software based on LTIB and Qt with our Nitrogen53 and Nitrogenboards, and the lack of documentation shows.

In order to remedy that and allow our customers to replicate our results, this post will walk through the steps to build an Ubuntu-based VirtualBox image that contains LTIB and Qt. A set of future blog posts will detail the steps we've used to translate that build into our standard Qt demo package.

Since developer machines come and go, the VM image is a good way to control our build process and minimize the number of unknowns when deploying systems.

Step 1: Build the VM

We built the VirtualBox image by starting with the Ubuntu Minimal CD to try and keep things small. Our purpose is setting up a build machine, so we started with the "OpenSSH Server" profile, which allows us to fork the VM off into a second workspace and primarily access the device over SSH.

We chose the 32-bit PC (x86) distribution and used 10.04 "Lucid Lynx".

We created a single user: boundary, password boundary.

Step 2: Configure with pre-requisites

In order to simplify things, we captured the full set of Ubuntu packages included on the build machine and placed on our web-site at You can copy these by piping them into apt-get install like so:

boundary@ubuntu:~$ wget --2011-12-10 18:10:08-- Resolving Connecting to||:80... connected. HTTP request sent, awaiting response... 200 OK Length: 6093 (6.0K) [text language="/plain"][/text] Saving to: `ltib-installed-packages' 100%[======================================>] 6,093 --.-K/s in 0.04s 2011-12-10 18:10:08 (144 KB/s) - `ltib-installed-packages' saved [6093/6093] boundary@ubuntu:~$ cat ltib-installed-packages | xargs sudo apt-get install [sudo] password for boundary: Reading package lists... Done Building dependency tree Reading state information... Done adduser is already the newest version. apparmor is already the newest version. ...

Step 3: Install LTIB

In this distribution, we started with the package L2.6.35_11.09.01_ER_source_bundle.tar.gz from Freescale, and the L2.6.35_11.09.01_ER_source.tar.gz tar-ball within it.

After extracting, we installed LTIB in the normal way into /home/boundary/ltib:

boundary@ltib-qt-4:~$ sudo mkdir -p /opt/freescale/ boundary@ltib-qt-4:~$ sudo chown boundary.boundary /opt/freescale boundary@ltib-qt-4:~$ cd L2.6.35_11.09.01_ER_source/ boundary@ltib-qt-4:~/L2.6.35_11.09.01_ER_source$ ls EULA ltib.tar.gz pkgs install package_manifest.txt boundary@ltib-qt-4:~/L2.6.35_11.09.01_ER_source$ ./install You are about to install the LTIB (GNU/Linux Target Image Builder) Before installing LTIB, you must read and accept the EULA (End User License Agreement) which will be presented next. Do you want to continue ? Y|n Y FREESCALE SEMICONDUCTOR SOFTWARE LICENSE AGREEMENT IMPORTANT. Read the following Freescale Semiconductor Software License Agreement ("Agreement") completely. By selecting the "I Accept" button at the end of this page, you indicate that you accept the terms of this Agreement. You may then download the file. ... I have read and accept the EULA (yes|no): yes The LTIB files are extracted from a tar file which includes the prefix ltib. After installation you will find LTIB in: /home/boundary/L2.6.35_11.09.01_ER_source/ltib Where do you want to install LTIB ? (/home/boundary/L2.6.35_11.09.01_ER_source) /home/boundary Making target directory /home/boundary/ltib Installing LTIB to /home/boundary/ltib ltib/ ltib/hash ltib/doc/ ...

Following the LTIB directions, we also added this line to /etc/sudoers:

boundary ALL= NOPASSWD: /usr/bin/rpm, /opt/freescale/ltib/usr/bin/rpm

And edited ltib as described here.

no_sudo_check => 0, # fc9 work-around

Step 4: Run LTIB

In the earlier posts on bringing up LTIB, I described running ltib -m config to configure the toolchain and packages for LTIB. In other words, I described an interactive process.

For production use, it's better to simply save and restore the configuration file produced by the U/I.

The LTIB configuration used in this VirtualBox build is available here. In order to restore it, use the ltib --selecttype option as shown below.

boundary@ubuntu:~$ wget --2011-12-10 19:44:54-- Resolving Connecting to||:80... connected. HTTP request sent, awaiting response... 200 OK Length: 1675 (1.6K) [text language="/plain"][/text] Saving to: `ltib_11.03.config.3' 100%[======================================>] 1,675 --.-K/s in 0s 2011-12-10 19:44:54 (173 GB/s) - `ltib_11.03.config.3' saved [1675/1675] boundary@ubuntu:~$ cd ltib && ./ltib --selectype

LTIB configuration screenshot

After running selectype, LTIB will run for a while. Go get a cup of coffee and check in with it periodically.

Note that SSH is up and running now, and if you configure the VM with a bridged network adapter, you can run ifconfig eth0 in the virtual machine to find its' IP address and use SSH to access it. Because you can run this in a console window on your development machine, Cut and Paste and screen scraping becomes much easier. Once things are configured and I know the IP address of the VM, I typically stash the VM console window on an unused Workspace on my Ubuntu development machine.

If everything proceeds as planned, your LTIB build will complete with this happy banner:

Started: Sun Dec 11 11:42:07 2011 Ended: Sun Dec 11 11:42:21 2011 Elapsed: 14 seconds Build Succeeded

The output of the build is placed in /home/boundary/ltib/rootfs. The size is fairly
large, but can be trimmed down later (a topic that deserves more than one blog post of its own).

boundary@ltib-qt:~$ du -hs /home/boundary/ltib/rootfs 663M /home/boundary/ltib/rootfs

Step 5: Set up symlink for Qt

If you've looked at the other post on building Qt, or if you've taken a look at the qmake.conf file, you should notice that the include and linker specs are specified using the path /tftpboot/ltib. This is done primarily to avoid having references to home directories and to allow multiple instances of LTIB to be placed on a development machine.

To set this up, you should simply create a /tftpboot directory and a symlink from /tftpboot/ltib to the LTIB root filesystem. In this post, that directory is /home/boundary/ltib/rootfs.

boundary@ltib-qt:~$ sudo mkdir /tftpboot boundary@ltib-qt:~$ sudo ln -sf /home/boundary/ltib/rootfs /tftpboot/ltib

Step 6: Configure Qt

Now that LTIB is installed, you can move on to configuring Qt.

To make things easy and reproducible, we placed some configuration files in this zip file. It consists of a configuration shell script (do_config_qt-4.7.1) and the LTIB configuration directory mkspecs/linux-mxc-g++/.

You can grab it and the Qt sources themselves using wget.

boundary@ltib-qt:~$ wget --2011-12-11 11:51:59-- Resolving, Connecting to||:80... connected. HTTP request sent, awaiting response... 200 OK Length: 211768512 (202M) [application/octet-stream] Saving to: `qt-everywhere-opensource-src-4.7.1.tar.gz' 2% [ ] 4,239,502 416K/s eta 8m 45s boundary@ltib-qt:~$ tar zxvf qt-everywhere-opensource-src-4.7.1.tar.gz qt-everywhere-opensource-src-4.7.1/ qt-everywhere-opensource-src-4.7.1/qmake/ qt-everywhere-opensource-src-4.7.1/qmake/property.cpp qt-everywhere-opensource-src-4.7.1/qmake/meta.h qt-everywhere-opensource-src-4.7.1/qmake/Makefile.win32-g++ ... boundary@ltib-qt:~$ cd qt-everywhere-opensource-src-4.7.1 boundary@ltib-qt:~/qt-everywhere-opensource-src-4.7.1$ wget --2011-12-11 12:01:46-- Resolving Connecting to||:80... connected. HTTP request sent, awaiting response... 200 OK Length: 3324 (3.2K) [application/zip] Saving to: `' 100%[======================================>] 3,324 --.-K/s in 0.001s 2011-12-11 12:01:47 (3.45 MB/s) - `' saved [3324/3324] boundary@ltib-qt:~/qt-everywhere-opensource-src-4.7.1$ unzip Archive: inflating: do_config_qt-4.7.1 creating: mkspecs/linux-mxc-g++/ inflating: mkspecs/linux-mxc-g++/qplatformdefs.h inflating: mkspecs/linux-mxc-g++/qmake.conf

If you take a look at the file do_config_qt-4.7.1, you'll see that it sets a few environment variables, so you'll want to run it with the source or dot operator:

boundary@ltib-qt:~/qt-everywhere-opensource-src-4.7.1$ . ./do_config_qt-4.7.1 Determining system architecture... (Linux:2.6.32-36-generic:i686) 32-bit Intel 80x86 (i386) 'arm' is supported 'i386' is supported System architecture: 'arm' Host architecture: 'i386' You have asked to use pkg-config and are cross-compiling. Please make sure you have a correctly set-up pkg-config environment! ... lots of spew here... Qt is now configured for building. Just run 'make'. Once everything is built, you must run 'make install'. Qt will be installed into /usr/local/Trolltech/Qt-4.7.1/

Step 7: Build and install Qt

Compared with the steps above, this step is really easy:

boundary@ltib-qt:~/qt-everywhere-opensource-src-4.7.1$ make cd src/tools/bootstrap/ && make -f Makefile make[1]: Entering directory `/home/boundary/qt-everywhere-opensource-src-4.7.1/src/tools/bootstrap' ... make[3]: Leaving directory `/home/boundary/qt-everywhere-opensource-src-4.7.1/demos/spectrum/app' make[2]: Leaving directory `/home/boundary/qt-everywhere-opensource-src-4.7.1/demos/spectrum' make[1]: Leaving directory `/home/boundary/qt-everywhere-opensource-src-4.7.1/demos' boundary@ltib-qt:~/qt-everywhere-opensource-src-4.7.1$ sudo make INSTALL_ROOT=~/ltib/rootfs/ install [sudo] password for boundary: cd src/tools/bootstrap/ && make -f Makefile install make[1]: Entering directory `/home/boundary/qt-everywhere-opensource-src-4.7.1/src/tools/bootstrap' ... cp -f -r /home/boundary/qt-everywhere-opensource-src-4.7.1/mkspecs/wincewm60standard-msvc2008 /home/boundary/ltib/rootfs//usr/local/Trolltech/Qt-4.7.1//mkspecs/ cp -f -r /home/boundary/qt-everywhere-opensource-src-4.7.1/mkspecs/wincewm65professional-msvc2005 /home/boundary/ltib/rootfs//usr/local/Trolltech/Qt-4.7.1//mkspecs/ cp -f -r /home/boundary/qt-everywhere-opensource-src-4.7.1/mkspecs/wincewm65professional-msvc2008 /home/boundary/ltib/rootfs//usr/local/Trolltech/Qt-4.7.1//mkspecs/ boundary@ltib-qt:~/qt-everywhere-opensource-src-4.7.1$

As shown above, this configuration installed Qt libraries into /home/boundary/ltib/rootfs, and
specifically, into the usr/local/ tree within it.

If you've followed this post to this point, congratulations! You now have a usable build of
Linux and Qt. I'll follow up in future posts with how you can create a production-ready distribution
based on this core.

Wrapping it up

This VirtualBox image is available here.

You can use it in a number of different ways:

  1. You can install the nfs-kernel-server package, export it and boot a Nitrogen53 directly to the VM image.
  2. You can grab the /opt/freescale and /home/boundary/ltib directories and use them to compile and link your applications.
  3. You can use it as a quick-start to cross-compilation without going through all of these steps yourself if you're evaluating a Nitrogen or Nitrogen53 board.
  4. You can use it for comparison with your own build.

The last of these is really the intent of this post.