2010-09-18

Solve 'undefined reference to' problem

To learn how to use scratchbox2 for cross-compilation, I attempted to repeat the steps in the wiki [2]. Everything works fine, until I tested the example 'More complicated example: with libraries'. The example failed to link to library ACE:

max@dev1:~/work/arena/sheeva_debian/source$ sb2 gcc -lACE test.o -o test
/home/max/work/arena/sheeva_debian/debian_rootfs/lib/libdl.so.2: undefined reference to `_dl_tls_get_addr_soft@GLIBC_PRIVATE

The reason is inconsistent version of dynamical libraries installed in  scratchbox system. The scratchbox system has following settings
I checked the library dependency as followings:
1) Since the '-lACE' is used, so we check the dependency of libACE by

max@dev1:~/work/arena/sheeva_debian/source$ sb2 -eR ldd /usr/lib/libACE.so
    librt.so.1 => /lib/librt.so.1 (0x4819f000)
    libdl.so.2 => /lib/libdl.so.2 (0x481ae000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x481ba000)
    libm.so.6 => /lib/libm.so.6 (0x48295000)
    libc.so.6 => /lib/libc.so.6 (0x48342000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x48469000)
    libpthread.so.0 => /lib/libpthread.so.0 (0x4847d000)
    /lib/ld-linux.so.3 (0x40071000)

2) According to the error messages, libdl.so has a undefined reference, therefore, I continue to check the dependency of libdl.so.2

max@dev1:~/work/arena/sheeva_debian/source$ sb2 -eR ldd /lib/libdl.so.2
    libc.so.6 => /lib/libc.so.6 (0x4807f000)
    /lib/ld-linux.so.3 (0x40071000)

3) Obviously, libc.so.6 is a symbolic link to the real library /lib/libc.so.6. You can also check the 'undefined reference' reported in link error by

 max@dev1:~/work/arena/sheeva_debian/source$ sb2 -eR readelf -s /lib/libdl.so.2 | grep -i _dl_tls_get_addr_soft@GLIBC_PRIVATE
    10: 00000000   164 FUNC    GLOBAL DEFAULT  UND _dl_tls_get_addr_soft@GLIBC_PRIVATE (6)


It seems that two libraries is involved:

  • /usr/lib/libACE.so 
  • /lib/libdl.so.2

According to statement in [1]:

When you link a shared library against other shared libraries (e.g. link libwx_baseu-2.8.so against libstdc++.so), the linker records versioned symbols used by libwx_baseu and provided by libstdc++.
If at runtime you use a different copy of libstdc++ (one which doesn't provide the same versioned symbol(s)), you get a (dynamic) liking error and the program doesn't run at all (this is preferable to a "mystery" crash later on).
The reason is these two libraries are inconsistent. The solution: reinstall the packages that contains the two libraries.


After checking the in www.debian.org, I found the involved packages in lenny.
Let's reinstall it by
> sb2 -eR apt-get install --reinstall libace-dev libc6-dev

The example is successfully linked.

References:
[1] http://stackoverflow.com/questions/2643738/elf-linking-why-do-i-get-undefined-references-in-so-files
[2] http://www.plugcomputer.org/plugwiki/index.php/Scratchbox2_based_cross_compiling

No comments:

Post a Comment