Cross-compiling QT/embedded
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).