Saturday, December 05, 2009

Qt 4.6.0 on AVR32 and it’s bugs: Error: symbol `.L987' is already defined

Qt 4.6.0 is out – there is only one source archive now, “-everywhere-“, which includes the linux embedded version also. I tried to build it for the avr32 embedded system; but, a nice compiler error prohibited it.

Error: Symbol `.L987' is already defined

compiling painting/qbrush.cpp
{standard input}: Assembler messages:
{standard input}:5426: Error: symbol `.L987' is already defined
{standard input}:5544: Error: symbol `.L1012' is already defined
{standard input}:6236: Error: symbol `.L1129' is already defined
{standard input}:6353: Error: symbol `.L1154' is already defined
make: *** [.obj/release-shared-emb-avr32/qbrush.o] Fehler 1

Googling it

This error is usually based on using “inline” and “asm” statements in combination – see http://archives.devshed.com/forums/development-94/new-assembler-message-symbol-is-already-defined-1269938.html, e.g. It looks like an internal compiler error, but is usually a coding error.

“This is not a gcc bug, you cannot declare a label in an inline-asm that is going to be exposed.”

“Is there a reference of some sort? I was unable to find one with google.”
”No, just a general rule as inline-asms will be copied when inlined or cloned. What is happening here is clon(n)ing is happening so we generate two copies of that function.”

So, there is some inline method that contains assembler code – the code is duplicated b/c of the inline interpretation – and thus, the assembler labels are duplicated.

Different Compiler?

I do not think that Nokia explicitly inserted the inline+asm-combination. It is probably some gcc optimization. Unfortunately, it is not possibly to use a different compiler than the one provided by atmel in “buildroot-avr32-2.3.0” (http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4401)

Using built-in specs. Target: avr32-linux-uclibc Configured with: /avr32/buildroot-avr32-v2.3.0/toolchain_build_avr32/gcc-4.2.2/configure --prefix=/avr32/buildroot-avr32-v2.3.0/build_avr32/staging_dir --build=x86_64-pc-linux-gnu --host=x86_64-pc-linux-gnu --target=avr32-linux-uclibc --enable-languages=c,c++ --enable-__cxa_atexit --enable-target-optspace --with-gnu-ld --with-gmp=/avr32/buildroot-avr32-v2.3.0/toolchain_build_avr32/gmp --with-mpfr=/avr32/buildroot-avr32-v2.3.0/toolchain_build_avr32/mpfr --enable-shared --disable-nls --enable-threads --disable-multilib --enable-sjlj-exceptions --disable-libmudflap --disable-libssp --with-build-time-tools=/avr32/buildroot-avr32-v2.3.0/build_avr32/staging_dir//bin Thread model: posix gcc version 4.2.2-atmel.1.1.3.buildroot.1

Change Optimisation Level

So, we have to find a way to avoid the above error. If it is an optimization problem, let’s just use some other one.

goto src/gui, patch Makefile, add –O to the end of CXXFLAGS, call make .obj/release-shared-emb-avr32/qbrush.o, and it runs through – now, you can remove the –O again, and compile the rest of it.

Alternatively, remove the @ in the beginning of CXX = …, call make, get the avr32-linux-uclibc-g++ statement, and add –O there.

Using –O3 does not work – then, the inlining is done even more often, resulting in triple definitions (or rather duplicate errors about duplicate defintions).

No idea where the error stems from, but at least, Qt 4.6.0 now compiles.

package/qtopia4/qtopia4.mk

Btw … to get that far, a few more changes are necessary. Those are, in short, in package/qtopia/qtopia4.mk:

QTOPIA4_VERSION:=4.6.0
QTOPIA4_CAT:=zcat
QTOPIA4_SOURCE:=qt-everywhere-opensource-src-$(QTOPIA4_VERSION).tar.gz
QTOPIA4_TARGET_DIR:=$(BUILD_DIR)/qt-everywhere-opensource-src-$(QTOPIA4_VERSION)
and you have to remove all the mouse driver statements – I have no idea how those are configured, now … most of them compile automatically, I may still be missing the tslib driver
### Mouse drivers
# remove all of them for Qt460
ifeq ($(BR2_PACKAGE_QTOPIA4_MOUSE_PC),y)
[...]
QTOPIA4_CONFIGURE += -no-mouse-qvfb
endif

Fixing 4.5.x Colour Depths

The previous version(s), 4.5.x, had a bug concerning a code optimisation that relied on non-aligned access – OK for i386 and followers, not OK for many other systems. Some were explicitly excluded, avr32 was not. The bug triggered when converting bitmaps between 24 and 16 bit colour depth, e.g., when connecting via vnc, or when using certain display depths directly.
See http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=79740 about fixing qt_blend_argb24_on_rgb16() in qblendfunctions.cpp.
Seems that fix is in 4.6.0, at least.

PS: QtScript

I get a compile error in QtScript – some problem with pthread_getattr_np:

compiling ../3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp
../3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp: In function 'void* QTJSC::currentThreadStackBase()':
../3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp:682: error: 'pthread_getattr_np' was not declared in this scope


Interestingly, the code does take care of uclibc 0.9.xx:

#if defined(__UCLIBC__)
// versions of uClibc 0.9.28 and below do not have
// pthread_getattr_np or pthread_attr_getstack.
#if __UCLIBC_MAJOR__ == 0 && \
(__UCLIBC_MINOR__ < 9 || \
(__UCLIBC_MINOR__ == 9 && __UCLIBC_SUBLEVEL__ <= 30))
#define UCLIBC_USE_PROC_SELF_MAPS 1
#include <stdio_ext.h>
extern int *__libc_stack_end;
#endif
#endif

Oops, there are two different Collector.cpp:
3rdparty/webkit/JavaScriptCore/runtime/Collector.cpp
3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp

One does define UCLIBC_USE_PROC_SELF_MAPS etc. as a workaround for uclibc 0.9.30, the other doesn’t – another bugreport to Nokia.

Just add -no-script to the configure options, for the moment.

Just a short note - I published both problems as Qt bug reports: QTBUG-6550 and QTBUG-6551

Have fun with it …
Sebastian