Search code examples
cross-compilingcompiler-optimizationglibceglibc

glibc not found when enabling compiler optimizations


I'm cross compiling a shared library (miniweb) for the beaglebone black device. When I compile without optimizations I have no problems. However, if I compile with any optimizations (ie -O3) I get the following when trying to run my program:

./myprogram: /lib/arm-linux-gnueabihf/libc.so.6: version `GLIBC_2.15' not found (required by /usr/lib/libminiweb.so)

My first question, why would enabling optimizations suddenly cause my program to be dependent on this library? Is content statically included in the library when optimizations are disabled?

How can I determine the c library version that my cross-compiler is using? I've run the following command ldd --version on both systems:

desktop:

$ ldd --version
ldd (Ubuntu EGLIBC 2.19-0ubuntu6.6) 2.19
Copyright (C) 2014 Free Software Foundation, Inc.

beaglebone:

ldd --version
ldd (Debian EGLIBC 2.13-38+deb7u1) 2.13
Copyright (C) 2011 Free Software Foundation, Inc.

Obviously the library I have is outdated, but as you can see my system reports using eglibc instead of glibc?

How could my cross-compiled library be dependent on glibc? Perhaps running ldd on my desktop is not an accurate reflection of the libraries used by my cross compiler?

How can I find which c library my cross compiler is using?


Solution

  • My first question, why would enabling optimizations suddenly cause my program to be dependent on this library?

    Your program is dependent on libc.so.6 with and without optimizations. You can verify this by running ldd ./myprogram on the target system.

    What's happening is that your program with optimization becomes dependent on later version of libc.so.6 then the one you have installed.

    Suppose a header file contains the following:

    inline int foo() { return bar() + 1; }
    

    Further suppose that your program calls foo. Without optimizations, foo will not be inlined, and your program will depend on foo.

    With optimizations, foo will be inlined, and your program will no longer depend on foo, but will depend on bar instead.

    If at static link time, you link against a library lifoobar.so which provides both foo and bar, your link will succeed with or without optimizations.

    If at dynamic link time (i.e. at runtime) a different version of libfoobar.so is used, one that provides foo but does not provide bar, then unoptimized program will run fine, but optimized program will fail with bar not found.

    That is what's happening to you, only instead of bar you are using versioned symbol some-libc-func@GLIBC_2.15, and that forces your program to depend on version GLIBC_2.15, which is what's missing from the target.

    Is content statically included in the library when optimizations are disabled?

    No.

    How can I determine the c library version that my cross-compiler is using?

    It's using libc-2.15.so or later. You should look in your cross-compiler directory.

    desktop: $ ldd --version

    What you have on your desktop is completely irrelevant. What matters is what your cross-compiler is using.

    How could my cross-compiled library be dependent on glibc?

    Your cross-compiler provides its own version of GLIBC, and your cross-compiled binary depends on that GLIBC.

    In other words, there are 3 distinct versions of GLIBC here:

    1. the one on your desktop (irrelevant)
    2. the one your cross-compiler is using to link your binary
    3. the one on your target (beaglebone) system.

    We know that (2) is at least GLIBC-2.15 from the error message, and we know that (3) is GLIBC-2.13 (which is too old).

    How can I find which c library my cross compiler is using?

    Look for it under your cross-compiler installation directory.

    You could also ask the linker print it for you:

    echo "int main() { return 0; }" | /path/to/cross-gcc -Wl,-t -xc -