I have a project that produces a shared library which is linked against another, also shared, library.
When I compile and link it with gcc 4.4, everything works:
- no compile-time warning or error,
- no linking time warning or error and
ldd libmyproject.so
correctly reports the dependency with the other shared library.
When I compile and link it with gcc 4.5, on the other hand (with the exact same flags), I have the following symptoms:
- no compile-time warning or error,
- no linking time warning or error but
- the library is not correctly linked against the other shared lib: this manifest itself when I run
ldd
and don't see the connection, and also when I try to use it: while it works with gcc 4.4, it crashes at run-time with gcc 4.5 with a "symbol not found" error (of course from the other lib).
I looked at the release notes and my intuition is that it has something to do with the new link-time optimization, but I could not understand them in enough details.
Did anyone encounter a similar situation and/or has any advice to offer?
(Note that results with 4.6 are in appearance identical to 4.5).
To summarize Mat's answer from GCC 4.5 vs 4.4 linking with dependencies and the discussion in the comments, you need to link with:
--copy-dt-needed-entries and --no-as-needed
You can debug your dynamically linked application with LD_DEBUG environment variable. This is an option of ld-linux.so.2
; ldd is a script to set such option too. All options are described at http://linux.die.net/man/8/ld-linux man page.
How to use LD_DEBUG (in bash; the easiest way):
$ LD_DEBUG=all ./your_program
This will turn on debugging of ld-linux.so.2 - the run-time dynamic linker. It will print a lot of debugging to stdout or stderr and you will be able to
- 1) compare output of "
LD_DEBUG=all ./your_program_4.4
" and "LD_DEBUG=all ./your_program_4.5
"
- 2) see the last symbols trying to be resolved and locate buggy symbol.
Also, you should give us more information:
- 0) What is your OS and cpu type? (show us output of
uname -a
) What is the version of libc? (run in bash for a in /lib*/libc.so.*;do echo $a; $a; done
)
- 1) What are compiling flags of your library itself?
- 2) What is exact error when you try to run the application?
- 3) Last lines from output of LD_DEBUG can contain valuable information
UPDATE: Good and exact answer is here: GCC 4.5 vs 4.4 linking with dependencies (by Mat)
Make sure you specify your shared libraries after your object (or source) files on the linker command line.
This is the way you had to do it with static libraries back in the old days. It appears to be beneficial again with recent versions of GCC. As far as I can tell, if it scans a shared library that doesn't supply any useful symbols, it ignores the whole library, which optimizes the number of shared libraries loaded at run-time, but demands that the -libname
options appear after the object files.