将程序与共享对象链接时,ld
将确保可以解析符号。这基本上确保了程序与其共享对象之间的接口是兼容的。阅读Linking with dynamic library with dependencies后,我了解到ld
将下降到链接的共享对象并尝试解析其符号。
当共享对象本身已关联时,我的共享对象的引用是否已经过检查?
我能理解在链接时找出一个程序是否具有启动所需的所有部分的吸引力,但是在构建共享对象可以单独分发的包的上下文中它似乎无关紧要(Debian' s例如,lib *包。它引入了对执行构建程序不感兴趣的系统的递归构建依赖性。
我可以信任构建共享对象时解析的依赖项吗?如果是这样,在构建程序时使用-unresolved-symbols = ignore-in-shared-libs有多安全?
答案 0 :(得分:7)
你想知道为什么一个程序的链接应该费心去解决源自的符号 与之链接的共享库,因为:
当共享对象本身已链接时,是否已检查我的共享对象的引用?
不,他们不是,除非您在链接共享库时明确坚持,
在这里,我将构建一个共享库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 强>
#include <stdio.h>
void 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 默认情况下它不 在链接时解析所有符号。这样一个程序 - 哪个 通常 需要将其所有符号解析为链接时间 - 可以获取其所有符号 通过与多个库链接解决。
答案 1 :(得分:2)
我的共享对象的引用是否已经过检查 当共享对象本身被链接?
好吧,共享库可能已与-Wl,--allow-shlib-undefined
或虚拟依赖项链接,因此检查它们仍然有意义。
我可以信任构建共享对象时解析的依赖项吗?
明显不是,当前链接环境和用于链接原始shlib的环境可能不同。
如果是这样,使用-unresolved-symbols = ignore-in-shared-libs是多么安全 在构建我的程序时?
在这种情况下,你可能会错过潜在的错误(或者更确切地说它们延迟到运行时仍然很糟糕)。想象一下这样一种情况:共享对象所需的一些符号来自可执行文件本身,或来自可执行文件链接的其中一个库(但是不是是由缺少符号的shlib)。 / p>
修改强>
虽然上面的说法是正确的,但迈克金汉的答案在可执行链接期间为库中的符号解析提供了更强有力的论据。