Cross-compiling QT/embedded

From Nuclear Physics Group Documentation Pages
Jump to navigationJump to search

QT/Embedded for the TS-7290

It has been a major pain to get a proper version of QT/embedded working on the TS-7290. The blog at automon was quite helpful.

Yes, you want TSLIB, otherwise the cursor does not follow where you touch the screen.

Warnings and Hints for EABI

I also build a gcc-4.3.4, however, when using this to compile the Qt/embedded 4.6, it gave an internal compiler error (segfault), when using the options: -mcpu=ep9312 -mfpu=maverick -mfloat-abi=softfp. Without these options the code generated will report "illegal instruction". One solution is to use the option -mfloat-abi=soft instead, but then you don't get to use the FPU at all!

The proper solution is to get a patched gcc-4.3.4 and a patched binutils. For info on speedups, see: [1] and [2]
I wrote my procedure for doing this at EABI on Maverick Crunch. This will give a correctly compiled and running (e.g. some examples were tested and they worked) version of true EABI enable Qt/embedded.

Please note "true EABI" is still a misnomer, since glibc is not compiled to use the FPU, so a lot of code still goes into soft FPU mode!


Prerequisites

You first need a decent (i.e. correctly build) cross compiler. For OABI I used binutils-2.18 with gcc 4.1.2. For EABI I used binutils-2.20 and gcc-4.3.2 (same version as the Lenny eabi uses).

OABI

To make binutils, get the source, untar it, create a "build-arm-linux-gnu" subdirectory and execute:

../configure --target=arm-linux-gnu --prefix=/net/home/maurik/cross-compile/arm-linux-gnu --with-sysroot=/net/home/maurik/cross-compile/arm-linux-gnu --with-local-prefix=/net/home/maurik/cross-compile/arm-linux-gnu --disable-nls --with-gcc --with-gnu-as --with-gnu-ld
make
make install

To make your compiler, get the sources, untar, create "build-arm-linux-gnu" subdir and execute:

 ../configure --target=arm-linux-gnu --prefix=/net/home/maurik/cross-compile/arm-linux-gnu --with-sysroot=/net/home/maurik/cross-compile/arm-linux-gnu --with-local-prefix=/net/home/maurik/cross-compile/arm-linux-gnu --disable-nls --enable-threads=posix --enable-symvers=gnu --enable-__cxa_atexit --enable-shared --enable-c99 --enable-long-long --enable-languages=c,c++
make 
make install

NOTE: YOU MUST MAKE THESE ON AN i386 TYPE MACHINE. On the x86_64 you get a different puppy which may not work. (didn't for me....)

EABI

To make binutils, get the source (2.20), untar it, patch it (see EABI on Maverick Crunch), create a "build-arm-linux-gnu" subdirectory and execute:

../configure --target=arm-linux-gnueabi --prefix=/net/home/maurik/cross-compile/arm-linux-gnueabi --with-sysroot=/net/home/maurik/cross-compile/arm-linux-gnueabi --with-local-prefix=/net/home/maurik/cross-compile/arm-linux-gnueabi --with-gcc --with-gnu-as --with-gnu-ld
make
make install

To make your compiler, get the sources (4.3.4 from Gnu), untar. patch (see EABI on Maverick Crunch), create "build-arm-linux-gnu" subdir and execute:

../configure --target=arm-linux-gnueabi --prefix=/net/home/maurik/cross-compile/arm-linux-gnueabi --with-sysroot=/net/home/maurik/cross-compile/arm-linux-gnueabi --with-local-prefix=/net/home/maurik/cross-compile/arm-linux-gnueabi --enable-shared --enable-threads=posix --enable-nls --without-included-gettext --enable-clocale=gnu --enable-symvers=gnu --enable-languages=c,c++ --enable-shared --enable-c99 --with-system-zlib --enable-mpfr --disable-libssp
make 
make install

NOTE: YOU MUST MAKE THESE ON AN i386 TYPE MACHINE. On the x86_64 you get a different puppy which may not work. (didn't for me). However, the cross compiler executed fine on the x86_64 systems.

Other prereq's

You also need to make a copy of the ARM boards system libraries and include files. For either OABI or EABI, boot your board and create a tar file of the system:

 cd /
 tar czf /net/home/maurik/tmp/arm_libs.tgz  /usr/lib /usr/include /lib

You can exclude the /lib/modules and other junk, but why bother. Expand this tar file in the appropriate sysroot (/net/home/maurik/cross-compile/arm-linux-gnueabi)

Now: very important you need to fix up all the links in .../usr/lib that point to /lib and instead should point to ../../lib

TSLIB

Get the TSLIB from SVN: (svn co svn://svn.berlios.de/tslib/trunk/tslib tslib ) or get it from http://prdownload.berlios.de/tslib/tslib-1.0.tar.bz2

You need a patch, since the TS board does not give pressure info: http://projects.linuxtogo.org/pipermail/openembedded-commits/2009-July/029934.html (I hand edited this in, instead of using the patch.)

Now run:

 ./autogen.sh
 ./configure CC=arm-linux-gcc CXX=arm-linux-g++ PLUGIN_DIR=/net/home/maurik/cross-compile/arm-linux-gnu/usr/local/plugin -prefix=/net/home/maurik/cross-compile/arm-linux-gnu/usr/local -host=arm-linux
 OR
 ./configure CC=arm-linux-gcc CXX=arm-linux-g++ PLUGIN_DIR=/net/home/maurik/cross-compile/arm-linux-gnueabi/plugin -prefix=/net/home/maurik/cross-compile/arm-linux-gnueabi/ -host=arm-linux
 make
 make install

And on the arm board, in the tslib directory run

  ./configure
  make 
  make install
  export TSLIB_CONFFILE=/usr/local/etc/ts.conf
  export TSLIB_CALIBFILE=/etc/pointercal
  export TSLIB_CONSOLEDEVICE=none
  export TSLIB_TSEVENTTYPE=H3600
  export TSLIB_FBDEVICE=/dev/fb0
  export TSLIB_TSDEVICE=/dev/input/event0
  export TSLIB_PLUGINDIR=/usr/local/lib/ts

Then run /usr/local/bin/ts_calib, and follow directions. Presto!

Building the Qt/embedded

Now comes the tough stuff. I got the QT 4.5.2 and the QT 4.6.1 embedded distributions. They both work on OABI. Instructions here are for 4.6

Modifications required

Here is a patch file of my modification of the QT 4.6.0 sources: [3] This includes the modified mkspec files.

Color Fix

First, the colors will be all wrong unless we force them to the correct configuration. Edit the file src/gui/embedded/qscreenlinuxfb_qws.cpp and before the line that says

grayscale = vinfo.grayscale;

add the following lines:

 diff qscreenlinuxfb_qws.cpp  qscreenlinuxfb_qws.cpp.~1~ 
 321,323d320
 <     // HACK Force the green length to 6:
 <     vinfo.green.length=6;

Startup Fix

Got an "segmentation violation" on startup? You have two choices, one is to add -debug to the config and get a slow build. The other is to edit the file src/gui/embedded/qscreenlinuxfb_qws.cpp and avoid the call to useOffscreen():

taro:embedded> diff qscreenlinuxfb_qws.cpp qscreenlinuxfb_qws.cpp.~2~ 
427c427
<     canaccel = false; // useOffscreen();
---
>     canaccel = useOffscreen();


mkspec changes

For the OABI, the mkspec/qws/linux-arm-g++/qmake.conf file reads:

#
# qmake configuration for building with arm-linux-g++
#
include(../../common/g++.conf)
include(../../common/linux.conf)
include(../../common/qws.conf)
# modifications to g++.conf
QMAKE_CC                = arm-linux-gnu-gcc
QMAKE_CXX               = arm-linux-gnu-g++
QMAKE_LINK              = arm-linux-gnu-g++
QMAKE_LINK_SHLIB        = arm-linux-gnu-g++
# modifications to linux.conf
QMAKE_AR                = arm-linux-gnu-ar cqs
QMAKE_OBJCOPY           = arm-linux-gnu-objcopy
QMAKE_STRIP             = arm-linux-gnu-strip
# For tslib
QMAKE_INCDIR += /net/home/maurik/cross-compile/arm-linux-gnu/usr/local/include
QMAKE_LIBDIR += /net/home/maurik/cross-compile/arm-linux-gnu/usr/local/lib 
QMAKE_LIBS += -lts
load(qt_config)

and for EABI it reads:

# 
# qmake configuration for building with arm-linux-gnug++ 
#
include(../../common/g++.conf)
include(../../common/linux.conf)
include(../../common/qws.conf)
# modifications to g++.conf 
QMAKE_CFLAGS		+= -mcpu=ep9312 -mfpu=maverick -mfloat-abi=soft 
QMAKE_CXXFLAGS		+= -mcpu=ep9312 -mfpu=maverick -mfloat-abi=soft
#QMAKE_LDFLAGS		+= -m32
QMAKE_CC                = arm-linux-gnueabi-gcc 
QMAKE_CXX               = arm-linux-gnueabi-g++
QMAKE_LINK              = arm-linux-gnueabi-g++
QMAKE_LINK_SHLIB        = arm-linux-gnueabi-g++
# modifications to linux.conf
QMAKE_AR                = arm-linux-gnueabi-ar cqs
QMAKE_OBJCOPY           = arm-linux-gnueabi-objcopy
QMAKE_STRIP             = arm-linux-gnueabi-strip

QMAKE_INCDIR += /net/home/maurik/cross-compile/arm-linux-gnu/usr/local/include
QMAKE_LIBDIR += /net/home/maurik/cross-compile/arm-linux-gnu/usr/local/lib 

QMAKE_LIBS         +=  -lts  -ldl -lz
QMAKE_LIBS_THREAD   = -lpthread -ldl -lrt -lz

load(qt_config)

Building Qt

First, if you want a separate build directory, put it in "parralel" of the qt-everywhere-xxx directory (at the same level) rather than below it, which gives errors.

OABI

tar xzf qt-everywhere-opensource-src-4.6.0.tar.gz
mkdir build-qt-arm-linux-gnu-4.6
cd build-qt-arm-linux-gnu-4.6
export PATH=/net/home/maurik/cross-compile/arm-linux-gnu/bin:$PATH
../qt-everywhere-opensource-src-4.6.0/configure -opensource -confirm-license -embedded arm -platform linux-g++-32 -xplatform qws/linux-arm-g++ -no-qvfb -depths all -prefix /net/home/maurik/cross-compile/arm-linux-gnu/usr/local/Qt4.6 -no-webkit -no-script -no-javascript-jit -no-scripttools -qt-mouse-tslib -no-rpath
make -j 6
make install

If you are lucky. That is it!

EABI

mkdir build-qt-arm-linux-gnueabi-4.6
cd  build-qt-arm-linux-gnueabi-4.6
export PATH=/net/home/maurik/cross-compile/arm-linux-gnueabi/bin:$PATH

Now, with a stock 4.3.2 or 4.3.4 compiler, you run configure this way:

 ../qt-everywhere-opensource-src-4.6.0/configure -opensource -confirm-license -embedded arm -platform linux-g++-32 -xplatform qws/linux-arm-eabi-g++ -no-qvfb -depths all -prefix /net/home/maurik/cross-compile/arm-linux-gnueabi/usr/local/Qt4.6 -no-webkit -no-script -no-javascript-jit -no-scripttools -qt-mouse-tslib -no-rpath

With the modified, FPU enabled 4.3.4 compiler, you execute:

../qt-everywhere-opensource-src-4.6.1/configure -opensource -confirm-license -embedded arm -platform linux-g++-32 -xplatform qws/linux-arm-eabi-crunch-g++ -no-qvfb -depths all -prefix /net/home/maurik/cross-compile/arm-linux-gnueabi/usr/local/Qt4.6 -no-webkit -no-script -no-javascript-jit -no-scripttools -qt-mouse-tslib -no-neon -no-rpath

Note the main difference is in the -xplatform you specify. You also need the -no-neon switch (since 4.6.1), since otherwise Qt will include "-mfpu=neon" and you get illegal instructions (VFP) in our code. You then build and install with:

make -j 6
make install

I tested the EABI, FPU enabled version, and the demos and examples seem to run fine.

Testing

Set the LD_LIBRARY_PATH to the Qt libraries, and set:

export QTDIR=<path to /usr/local/Qt4.6>
export QWS_MOUSE_PROTO="tslib"
export TSLIB_CONFFILE=/usr/local/etc/ts.conf
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONSOLEDEVICE=none
export TSLIB_TSEVENTTYPE=H3600
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_PLUGINDIR=/usr/local/lib/ts

Then run one of the examples:

 $QTDIR/examples/widgets/analogclock/analogclock -qws

You may get an error if you don't have write permissions to /dev/fb0, or /dev/tty0. You could also get a an error about now owning the Qt data directory (when you are root and access over nfs with root_squash on).