gcc static library linking vs dynamic linking

15,240

Solution 1

Why is it giving error when linked statically with libcunit.a

The problem is that your libcunit.a was built on an ancient Linux system, and depends on symbols which have been removed from libc (these symbols were used in glibc-2.2, and were removed from glibc-2.3 over 10 years ago). More exactly, these symbols have been hidden. They are made available for dynamic linking to old binaries (such as libcunit.so) but no new code can statically link to them (you can't create a new executable or shared library that references them).

You can observe this like so:

readelf -Ws /lib/x86_64-linux-gnu/libc.so.6 | egrep '\W__ctype_b\W'
   769: 00000000003b9130     8 OBJECT  GLOBAL DEFAULT   31 __ctype_b@GLIBC_2.2.5

readelf -Ws /usr/lib/x86_64-linux-gnu/libc.a | egrep '\W__ctype_b\W'
# no output

Solution 2

Didn't notice that the libcunit.a is actually found in your case and the problem with linakge is rather in the CUnit library itself. Employed Russian is absolutely right, and he's not talking about precompiled binary here. We understand that you've built it yourself. However, CUinit itself seems to be relying on the symbol from glibc which is not available for static linking anymore. As a result you have only 2 options:

  1. File a report to the developers of CUnit about this and ask them to fix it;
  2. Use dynamic linking.

Nevertheless, my recommendation about your style of static linkage still applies. -L. is in general bad practice. CUnit is a 3rd party library and should not be placed into the directory containing source files of your project. It should be rather installed in the same way as the dynamic version, i.e. like you have libcunit.so in /usr/local/lib. If you'd supply prefix to Autotools on the configure stage of CUnit, then Autotools would install everything properly. So if you want to link statically with CUnit, consider doing it in the following form:

gcc -o test test.c -L/usr/local/lib -Wl,-Bstatic -lcunit -Wl,-Bdynamic -labc -lyz
Share:
15,240
bala1486
Author by

bala1486

Updated on June 05, 2022

Comments

  • bala1486
    bala1486 almost 2 years

    My build environment is CentOS 5. I have a third party library called libcunit. I installed it with autotools and it generates both libcunit.a and libcunit.so. I have my own application that links with a bunch of shared libraries. libcunit.a is in the current directory and libcunit.so and other shared libraries are in /usr/local/lib/. When I compile like:

    gcc -o test test.c -L. libcunit.a -L/usr/local/lib -labc -lyz
    

    I get a linkage error:

    libcunit.a(Util.o): In function `CU_trim_left':
    Util.c:(.text+0x346): undefined reference to `__ctype_b'
    libcunit.a(Util.o): In function `CU_trim_right':
    Util.c:(.text+0x3fd): undefined reference to `__ctype_b'
    

    But when I compile with .so like:

    gcc -o test test.c -L/usr/local/lib -lcunit -labc -lyz
    

    it compiles fine and runs fine too.

    Why is it giving error when linked statically with libcunit.a?