This question is related to the way libraries are looked up during compilation and dynamic linking.
Consider this small project:
- project
- liba
- a.hpp
- a.cpp
- libb
- b.hpp
- b.cpp
- main.cpp
- liba
a.hpp:
int AAA();
a.cpp:
#include <b.hpp>
int AAA()
{
return BBB();
}
b.hpp:
int BBB();
b.cpp:
int BBB()
{
return 3;
}
main.cpp:
#include "liba/a.hpp"
#include "libb/b.hpp"
int main()
{
AAA();
BBB();
}
libb is comp开发者_开发问答iled with:
cd libb; g++ -shared -o libb.so b.cpp
liba is compiled with:
cd liba; g++ -I../libb/ -L../libb/ -lb -shared -o liba.so -Wl,-rpath /full/path/to/project/libb/ a.cpp
and main is compiled with:
g++ -Lliba -la -Wl,-rpath /full/path/to/project/liba/ main.cpp
The compilation finishes without error, but when executing a.out, libb.so can't be found.
ldd outputs:
ldd ./a.out
linux-gate.so.1 => (0xffffe000)
liba.so => /full/path/to/project/liba/liba.so (0xb780a000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb76ba000)
libm.so.6 => /lib/libm.so.6 (0xb7692000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7672000)
libc.so.6 => /lib/libc.so.6 (0xb750f000)
libb.so => not found
libb.so => /full/path/to/project/libb/libb.so (0xb750c000)
/lib/ld-linux.so.2 (0xb780e000)
Note, that libb.so occurs twice. One time, the dynamic linker is not able to find the library and one time it is. I assume, that in the second case it uses the rpath embedded in liba.so.
Of course, there are multiple ways to fix that problem (e.g. LD_LIBRARY_PATH, embed the correct rpath when compiling main.cpp...), but I'm more interested in why the compilation of main.cpp works, while the dynamic linking doesn't.
So far I assumed that the same procedure was used for searching the needed libraries. Is there something I'm missing, or some hidden magic I don't know of? :)
(Tested on a SLED11 box with gcc 4.3.4.)
There's no hidden magic but you've basically promised the compiler that you're going to tell the loader, at run-time, where to find the functions but you haven't. The BBB called from AAA knows how to get there but the BBB called from main does not.
精彩评论