将程序链接到共享对象时,ld
将确保可以解析符号。这基本上保证了程序与其共享对象之间的接口(interface)是兼容的。看完Linking with dynamic library with dependencies , 我了解到 ld
将下降到链接的共享对象并尝试解析它们的符号。
当共享对象本身链接时,我的共享对象的引用不是已经检查了吗?
我可以理解在链接时找出程序是否具有启动所需的所有部分的吸引力,但是在共享对象可以单独分发的包构建的上下文中它似乎无关紧要(例如,Debian 的 lib* 包) .它在对执行构建程序不感兴趣的系统上引入了递归构建依赖项。
我可以信任构建共享对象时解决的依赖关系吗?如果是这样,在构建我的程序时使用 -unresolved-symbols=ignore-in-shared-libs 有多安全?
最佳答案
您想知道为什么程序的链接应该费心去解析源自
它链接的共享库,因为:
Aren't my shared object's references already checked when the shared objects are themselves linked?
不,他们不是,除非您在链接共享库时明确坚持,
这里我要建一个共享库
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!
这是共享库的本质,默认情况下它没有
在链接时解析其所有符号。这样,一个程序 - 哪个
通常确实需要它的所有符号解析一个链接时间 - 可以获得它的所有符号
通过与多个库链接来解决。
关于linker - ld 检查共享库中未解析的符号不是多余的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41865136/