linker - ld 检查共享库中未解析的符号不是多余的吗?

标签 linker dependencies ld

将程序链接到共享对象时,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/

相关文章:

c++ - 如何在 C++ 中访问新主函数的参数?

memory - 了解嵌入式软件中的链接描述文件 NOLOAD 部分

c++ - 为什么 RWDBManager::database 需要共享库名?

c - ld: 找不到 lc -错误

linker - 链接器文件中输入和输出部分之间的区别?

c++ - 如何在运行时将 C++ 程序编译并链接到 DLL

android - 错误 : Program type already present: com. google.common.annotations.Beta

c# - 工厂模式可以这样使用吗?

java - 如何在 android studio 中编辑依赖项/外部库?

linux - 从静态库动态链接?