Rockbox

Tasklist

FS#12427 - win32 cc does not compile (undefined reference 'lcd_blit_yuv')

Attached to Project: Rockbox
Opened by Andree Buschmann (Buschel) - Sunday, 04 December 2011, 10:11 GMT
Last edited by Rafaël Carré (funman) - Friday, 09 December 2011, 20:56 GMT
Task Type Bugs
Category Build environment
Status Closed
Assigned To No-one
Operating System All players
Severity High
Priority Normal
Reported Version Daily build (which?)
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 0
Private No

Details

The sim for iPod nano2G (win32 cc under Ubuntu) does not compile for me with current svn (r31136). I get "undefined reference to '_lcd_blit_yuv'".

The attached patch solves this issue for the sim build but results in a build error for the target.

Some more details:
i586-mingw32msvc-gcc 4.2.1-sjlj (402)
i586-mingw32msvc-ld 2.20
This task depends upon

Closed by  Rafaël Carré (funman)
Friday, 09 December 2011, 20:56 GMT
Reason for closing:  Fixed
Additional comments about closing:  r31193
Comment by Andree Buschmann (Buschel) - Sunday, 04 December 2011, 18:14 GMT
We had a similar problem with a 'weak' declaration of "codec_main". This needed to be fixed with r29789.
Comment by Boris Gjenero (dreamlayers) - Sunday, 04 December 2011, 20:27 GMT
I have the same problem using cross compiling from Cygwin, using:
i686-w64-mingw32-gcc 4.5.3 (405)
i686-w64-mingw32-ld 2.21.53.20110828

A simple little test case reproduces the problem, and linking succeeds if there's a prototype with __attribute__((weak)). Such a prototype adds a ".weak _f" to the assembler file using the symbol. Here are the resulting changes that nm finds in the object file:
> 00000000 A .weak._f._main
< U _f
> w _f
Here's the relevant part of nm output for the object file which contains the weak symbol:
00000000 T .weak._f.
w _f

This bug report provides some info: http://sourceware.org/bugzilla/show_bug.cgi?id=9687
Comment by Rafaël Carré (funman) - Sunday, 04 December 2011, 21:08 GMT
Using weakref instead of weak seems to work for me (on zip too)

info gcc:

`weakref'
`weakref ("TARGET")'
The `weakref' attribute marks a declaration as a weak reference.
Without arguments, it should be accompanied by an `alias' attribute
naming the target symbol. Optionally, the TARGET may be given as
an argument to `weakref' itself. In either case, `weakref'
implicitly marks the declaration as `weak'. Without a TARGET,
given as an argument to `weakref' or to `alias', `weakref' is
equivalent to `weak'.

It's equivalent to weak since we don't specify TARGET, but works around a bug on mingw target it seems
Comment by Boris Gjenero (dreamlayers) - Sunday, 04 December 2011, 23:28 GMT
In Cygwin, at the function definition, using weakref instead of weak does not help. I tried in both win32_weak_symbol_test.zip and a r31138 video iPod sim build.
Comment by Boris Gjenero (dreamlayers) - Friday, 09 December 2011, 01:22 GMT
I just installed TDM-GCC 4.6.1 and tested it with win32_weak_symbol_test.zip. Without changes, the results are the same as before. If I change the weak to weakref, I get the following warning, but linking succeeds:
b.c:1:31: warning: 'weakref' attribute ignored because function is defined [-Wattributes]
It works, because f() in b.c is not weak, because the weakref attribute is ignored.. If there is another f(), then I get a "multiple definition of `f'" error.

I expect this would allow Rockbox to compile, because there is only one lcd_blit_yuv() in the simulator. However, I wouldn't call it a solution. Maybe just remove the weak on WIN32 or CONFIG_PLATFORM & PLATFORM_SDL?
Comment by Rafaël Carré (funman) - Friday, 09 December 2011, 02:00 GMT
Using "weakref" was just a workaround, since it should have the same meaning than weak.

Does it work if you put weakref attribute only in a declaration, and then define the function without the attribute?

AFAIU "weak" should work, both on ELF and on Windows targets.
It should work in the sense that if there's only 1 definition, the one in libfirmware.a (lcd-16bit-common.o) is taken
And it should work that if there's 2 definitions, the one in firmware/target/XXX.o is taken

However thinking again about it, I'm not sure that using weak works as intended.
gcc might want to use the version in lcd-16bit-common.o instead, right? Nothing can guarantee us that the asm version is preferred to the C version.

In the end I think we should just add a #define HAVE_OPTIMIZED_LCD_BLIT_YUV if we can't get 'weak' (or weakref) to work


Also I am curious why it works with my compiler:

% i686-w64-mingw32-gcc -v
Using built-in specs.
COLLECT_GCC=i686-w64-mingw32-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-w64-mingw32/4.6/lto-wrapper
Target: i686-w64-mingw32
Configured with: ../../src/configure --build=x86_64-linux-gnu --prefix=/usr --includedir='/usr/include' --mandir='/usr/share/man' --infodir='/usr/share/info' --sysconfdir=/etc --localstatedir=/var --libexecdir='/usr/lib/gcc-mingw-w64' --disable-maintainer-mode --disable-dependency-tracking --prefix=/usr --enable-shared --enable-static --disable-multilib --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --libdir=/usr/lib --enable-libstdcxx-time=yes --with-tune=generic --enable-version-specific-runtime-libs --enable-threads=win32 --enable-fully-dynamic-string --enable-sjlj-exceptions --enable-languages=c,c++,fortran,ada --enable-lto --with-plugin-ld --target=i686-w64-mingw32 --with-gxx-include-dir=/usr/include/c++/4.6 --with-as=/usr/bin/i686-w64-mingw32-as --with-ld=/usr/bin/i686-w64-mingw32-ld
Thread model: win32
gcc version 4.6.2 (GCC)
Comment by Boris Gjenero (dreamlayers) - Friday, 09 December 2011, 02:21 GMT
> Does it work if you put weakref attribute only in a declaration, and then define the function without the attribute?

I get the same results with:
void f(void) __attribute__((weakref));
void f(void)
{
}

> Also I am curious why it works with my compiler:

Are you sure you're not getting "warning: 'weakref' attribute ignored because function is defined"? Maybe the warning is disabled by default and you need to add -Wattributes to see it? Try defining another lcd_blit_yuv() someplace and see if you get a multiple definition error.

I was testing with the following. Cygwin was not in the path, so I must have been using only TDM-GCC 4.6.1 binaries.

COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=c:/mingw32/bin/../libexec/gcc/mingw32/4.6.1/lto-wrapper.exe
Target: mingw32
Configured with: ../../src/gcc-4.6.1/configure --build=mingw32 --enable-languages=c,c++,ada,fortran,objc,obj-c++ --enable-threads=win32 --enable-libgomp --enable-lto --enable-fully-dynamic-string --enable-libstdcxx-debug --enable-version-specific-runtime-libs --with-gnu-ld --disable-nls --disable-win32-registry --disable-symvers --disable-werror --prefix=/mingw32tdm --with-local-prefix=/mingw32tdm --enable-cxx-flags='-fno-function-sections -fno-data-sections' --with-pkgversion=tdm-1 --enable-sjlj-exceptions --with-bugurl=http://tdm-gcc.tdragon.net/bugs
Thread model: win32
gcc version 4.6.1 (tdm-1)
Comment by Rafaël Carré (funman) - Friday, 09 December 2011, 02:25 GMT
Of course I didn't pay attention and I get this warning too.

One mystery solved, we have identical results now.

Loading...