将程序与共享对象链接时,ld
将确保可以解析符号.这基本上确保了程序与其共享对象之间的接口是兼容的.在阅读了带有依赖关系的动态库的链接后 ,我了解到ld
它将下降到链接的共享对象并尝试解析它们的符号.
当共享对象本身链接时,是否已经检查了我的共享对象的引用?
我可以理解在链接时找出一个程序是否具有启动所需的所有部分的吸引力,但是在包构建的上下文中它似乎是无关紧要的,其中共享对象可以单独分发(例如Debian的lib*包) .它引入了对执行构建程序不感兴趣的系统的递归构建依赖性.
在构建共享对象时,我可以信任解析的依赖项吗?如果是这样,在构建程序时使用-unresolved-symbols = ignore-in-shared-libs有多安全?
您想知道为什么程序的链接应该来解决源自它所链接的共享库的符号,因为:
当共享对象本身链接时,是否已经检查了我的共享对象的引用?
不,他们不是,除非你在链接共享库时明确坚持,
在这里,我将构建一个共享库libfoo.so
:
foo.c的
extern void bar(); void foo(void) { bar(); }
常规编译和链接:
$ gcc -fPIC -c foo.c $ gcc -shared -o libfoo.so foo.o
没问题,并且bar
未定义:
$ nm --undefined-only libfoo.so | grep bar U bar
我需要坚持让链接器反对:
$ gcc --shared -o libfoo.so foo.o -Wl,--no-undefined foo.o: In function `foo': foo.c:(.text+0xa): undefined reference to `bar'
当然:
main.c中
extern void foo(void); int main(void) { foo(); return 0; }
它不会让我链接libfoo
到一个程序:
$ gcc -c main.c $ gcc -o prog main.o -L. -lfoo ./libfoo.so: undefined reference to `bar'
除非我也在bar
同一个联系中解决:
bar.c
#includevoid bar(void) { puts("Hello world!"); }
也许从另一个共享库中获取它:
gcc -fPIC -c bar.c $ gcc -shared -o libbar.so bar.o $ gcc -o prog main.o -L. -lfoo -lbar
然后一切都很好.
$ export LD_LIBRARY_PATH=.; ./prog Hello world!
这是的essense它的共享库中没有默认必须具备全部的符号在链接时间解决的.这样,一个程序 -这通常不会需要它的所有符号解析的链接时间-可以得到它的所有与被链接解析的符号不止一个图书馆.