Why does the order in which libraries are linked sometimes cause errors in GCC?
Why does the order in which libraries are linked sometimes cause errors in GCC
gcclinker
Related Topic
- Why doesn’t GCC optimize a*a*a*a*a*a to (a*a*a)*(a*a*a)
- C++ – Why is the program slow when looping over exactly 8192 elements
- Linux – Why does the C preprocessor interpret the word “linux” as the constant “1”
- C++ – Why does GCC generate 15-20% faster code if I optimize for size instead of speed
- R – Drupal: retrieve data from multiple node types in views 2
- Why does GCC use multiplication by a strange number in implementing integer division
Best Answer
(See the history on this answer to get the more elaborate text, but I now think it's easier for the reader to see real command lines).
Common files shared by all below commands
Linking to static libraries
The linker searches from left to right, and notes unresolved symbols as it goes. If a library resolves the symbol, it takes the object files of that library to resolve the symbol (b.o out of libb.a in this case).
Dependencies of static libraries against each other work the same - the library that needs symbols must be first, then the library that resolves the symbol.
If a static library depends on another library, but the other library again depends on the former library, there is a cycle. You can resolve this by enclosing the cyclically dependent libraries by
-(
and-)
, such as-( -la -lb -)
(you may need to escape the parens, such as-\(
and-\)
). The linker then searches those enclosed lib multiple times to ensure cycling dependencies are resolved. Alternatively, you can specify the libraries multiple times, so each is before one another:-la -lb -la
.Linking to dynamic libraries
It's the same here - the libraries must follow the object files of the program. The difference here compared with static libraries is that you need not care about the dependencies of the libraries against each other, because dynamic libraries sort out their dependencies themselves.
Some recent distributions apparently default to using the
--as-needed
linker flag, which enforces that the program's object files come before the dynamic libraries. If that flag is passed, the linker will not link to libraries that are not actually needed by the executable (and it detects this from left to right). My recent archlinux distribution doesn't use this flag by default, so it didn't give an error for not following the correct order.It is not correct to omit the dependency of
b.so
againstd.so
when creating the former. You will be required to specify the library when linkinga
then, buta
doesn't really need the integerb
itself, so it should not be made to care aboutb
's own dependencies.Here is an example of the implications if you miss specifying the dependencies for
libb.so
If you now look into what dependencies the binary has, you note the binary itself depends also on
libd
, not justlibb
as it should. The binary will need to be relinked iflibb
later depends on another library, if you do it this way. And if someone else loadslibb
usingdlopen
at runtime (think of loading plugins dynamically), the call will fail as well. So the"right"
really should be awrong
as well.