Sunday, July 31, 2011

Compiling Qt Embedded 4.7.3

The version of Qt and tslib used in this article are:

qt-everywhere-opensource-src-4.7.3
tslib 2011.07.01 snapshot

Assume that the working directory is

/home/user

and all the required cross tool chain setting are already done. Be sure that you are using the same version of tool chain you have used for your ARM kernel. Otherwise tslib utilities won't work properly. If you don't have the following packages, get them now:

$ sudo apt-get install autoconf
$ sudo apt-get install libtool

tslib

Before you compile Qt embedded you may want compile tslib first. Fortunately it is quite straightforward. Get the most recent version of tslib via git

$ git clone https://github.com/kergoth/tslib.git

Configure it

$ cd tslib
$ ./autogen.sh
$ ./configure --prefix=$HOME/tslib_arm --host=arm-none-linux-gnueabi

Compile and install it

$ make
$ make install

Then you can find the resulting directories like:



At this point, you can test this on your device. Copy the resulting directories bin, etc, and lib with its subdirectory ts to the corresponding directories of your device, e.g.,

/usr/local/bin
/usr/local/etc
/usr/local/lib

The etc directory contains the configuration file, ts.conf. You need to edit the file and uncomment the line to load at least one input raw module, such as

module_raw input

And you set the following environment variables:

export TSLIB_TSDEVICE=/dev/input/event1
export TSLIB_CALIBFILE=/usr/local/etc/pointercal
export TSLIB_CONFFILE=/usr/local/etc/ts.conf
export TSLIB_PLUGINDIR=/usr/local/lib/ts
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0

You may also have to add the lib (/usr/local/lib) directory to your LD_LIBRARY_PATH :

export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

You want to put the above in your default profile (/etc/profile). Each device name varies depending on your kernel. For the detailed explanation about the variables, you can refer README file comes with tslib source.

Now you can run some executable files comes with the tslib, such as

ts_calibrate
ts_test

For the plugins (/usr/local/lib/ts), you can safely delete files you don't need. Usually you need:

dejitter.so
input.so
linear.so
pthres.so
variance.so

for your plugins.

Qt embedded

Download the qt embedded source and expand it on your working directory, e.g.,

/home/user/qt-everywhere-opensource-src-4.7.3

Before do anything, edit qmake.conf for your toolchain
mkspecs/qws/linux-arm-gnueabi-g++/qmake.conf
and add the following lines:

QMAKE_INCDIR = /home/user/tslib_arm/include
QMAKE_LIBDIR = /home/user/tslib_arm/lib
QMAKE_LFLAGS = -lts

The last line is important although it is not mentioned elsewhere.
Now you can run configure with basic parameters:

./configure -embedded arm -xplatform qws/linux-arm-gnueabi-g++ \
-qt-kbd-linuxinput -qt-mouse-tslib -qt-gfx-linuxfb \
-little-endian -prefix-install -depths 16,18,24 -optimized-qmake

You can add some additional parameters for your convenience:

-release -opensource -confirm-license

And you can also opt out unused components:

-no-webkit -no-cups -no-largefile -no-openssl -no-mmx -no-sse -no-sse2

For the explanation of each parameter you can find by running:

./configure -embedded -help

After the configure, you may want to edit ./src/corelib/Makefile and add librt link option:

set LFLAGS = -lrt ......

Now, you are ready to go

$ make
$ sudo make install

It will take more than 30minutes to finish. After deploying Qt to your device, you may have to copy additional libraries from your tool chain system such as:

(from arm-none-linux-gnueabi/libc/lib)
libdl*, libptread*, librt*
(from arm-none-linux-gnueabi/libc/usr/lib)
libstdc++.so*

Qt also requires some environmental variables to run. Add following line to your profile

export QTDIR=/usr/local/QtEmbedded-4.7.3-arm
export PATH=$QTDIR/bin:$PATH
export LD_LIBRARY_PATH=$QTDIR/lib:/usr/local/lib:$LD_LIBRARY_PATH
export QWS_MOUSE_PROTO="TSLIB:/dev/input/event1"
export QWS_KEYBOARD=TTY:/dev/tty1

Be sure to give -qws option for the first qt application you want to run.

If you have a warning like

Could not read calibration: "/etc/pointercal"

when you run qt application, then probably your calibration file is located elsewhere (/usr/local/etc) as in this example. So you have to set an environmental variable

export POINTERCAL_FILE=/usr/local/etc/pointercal

to override the default hard coded calibration file location.

additional information

Qt embedded uses /tmp as its temporary data storage. To change this, use

#define QT_PRIVATE_QWS 1
#define QT_QWS_TEMP_DIR "/usr/local/tmp

when you compile Qt.

Tuesday, July 19, 2011

Cross Compiling MTD Utils

Cross-compiling MTD utils is tricky and eLinux wiki article is out-dated. So you may need some tweaks. As of this writing, we will use the most recent versions of :
  • mtd-utils - Jul. 4 2011 snapshot
  • e2fsprogs-1.41.14
  • lzo-2.05
  • zlib-1.2.5
As in the eLinux wiki, we take

/home/user/mtd

as build directory and

/home/user/mtd/install

as target path. First, you want extract all sources under /home/user/mtd, so your build directory looks like


zlib

Go to the source directory and execute configuration utility

~/mtd$ cd zlib-1.2.5
~/mtd/zlib-1.2.5$ ./configure --prefix=/usr

prefix option here is required if you want /usr as your target root for resulting output, otherwise /usr/local will be the target directory like most cases. We have chosen to use /usr. It is yours to decide. Before building anything you have to edit the Makefile.

CROSS = arm-none-linux-gnueabi-
CC = $(CROSS)gcc
LDSHARED = $(CROSS)gcc -shared ...
CPP = $(CROSS)gcc -E
AR = $(CROSS)ar rc
RANLIB = $(CROSS)ranlib

Then you are ready to go

~/mtd/zlib-1.2.5$ make
~/mtd/zlib-1.2.5$ make install DESTDIR=/home/user/mtd/install


lzo

lzo is cross build friendly. So it is straightforward to do.

~/mtd/lzo-2.05$ ./configure --host=arm-none-linux-gnueabi --prefix=/usr
~/mtd/lzo-2.05$ make
~/mtd/lzo-2.05$ make install DESTDIR=/home/user/mtd/install


e2fsprogs

Building e2fsprogs is same with lzo

~/mtd/e2fsprogs-1.41.14$ ./configure --host=arm-none-linux-gnueabi --prefix=/usr
~/mtd/e2fsprogs-1.41.14$ make
~/mtd/e2fsprogs-1.41.14$ make install DESTDIR=/home/user/mtd/install

But for some reason, you have to copy following two files to the target directory

~/mtd/e2fsprogs-1.41.14$ mkdir ../install/usr/include/uuid
~/mtd/e2fsprogs-1.41.14$ cp lib/uuid/uuid.h ../install/usr/include/uuid
~/mtd/e2fsprogs-1.41.14$ cp lib/libuuid.a ../install/usr/lib

Note that the target directories for the above cp operation are related to your choice of --prefix option before. If you have chosen not to change the default directory, then you have to do like:

~/mtd/e2fsprogs-1.41.14$ mkdir ../install/usr/local/include/uuid
~/mtd/e2fsprogs-1.41.14$ cp lib/uuid/uuid.h ../install/usr/local/include/uuid
~/mtd/e2fsprogs-1.41.14$ cp lib/libuuid.a ../install/usr/local/lib


mtd-utils

First, You have to edit Makefile and add following at the top of the file

INSTALLDIR = /home/user/mtd/install/usr
ZLIBCPPFLAGS = -I$(INSTALLDIR)/include
LZOCPPFLAGS = -I$(INSTALLDIR)/include
ZLIBLDFLAGS = -L$(INSTALLDIR)/lib
LZOLDFLAGS = -L$(INSTALLDIR)/lib
WITHOUT_XATTR = 1
CROSS = arm-none-linux-gnueabi-
LDFLAGS += $(ZLIBLDFLAGS) $(LZOLDFLAGS)

Again note that INSTALLDIR corresponds to --prefix option before. If you have chosen not to change the target, then your INSTALLDIR here should be

INSTALLDIR = /home/user/mtd/install/usr/local

Edit common.mk and change the CFLAGS,

CFLAGS ?= -O2 -g $(ZLIBCPPFLAGS) $(LZOCPPFLAGS)

and replace the BUILDDIR

ifndef BUILDDIR
#ifeq ($(origin CROSS),undefined)
# BUILDDIR := $(CURDIR)
#else
## Remove the trailing slash to make the directory name
# BUILDDIR := $(CURDIR)/$(CROSS:-=)
#endif
BUILDDIR := $(CURDIR)
endif

Now, you are ready to build mtd-utils

~/mtd/mtd-utils$ make
~/mtd/mtd-utils$ make install DESTDIR=/home/user/mtd/install

You can find some of precompiled files here.