Changes introduced in gcc 4.5 with respect to link

2019-04-24 11:13发布

问题:

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:

  1. no compile-time warning or error,
  2. no linking time warning or error and
  3. 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:

  1. no compile-time warning or error,
  2. no linking time warning or error but
  3. 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).

回答1:

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


回答2:

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)



回答3:

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.