【发布时间】:2021-03-23 22:40:35
【问题描述】:
所以最近,我一直试图更好地理解共享库的符号解析是如何工作的。我创建了 2 个共享对象(libfoo 和 libbar)和 1 个可执行文件(test)。考虑以下一组程序:
foo.c
#include <stdio.h>
void foo()
{
puts(__func__);
}
bar.c
#include <stdio.h>
extern void foo(void);
void bar()
{
puts(__func__);
foo();
}
test.c
#include <stdio.h>
extern void foo(void);
extern void bar(void);
int main()
{
puts(__func__);
foo();
bar();
return 0;
}
libbar 依赖于libfoo,而test 依赖于libfoo 和libbar:
gcc -c -Wall -fPIC foo.c bar.c
gcc -shared -o libfoo.so foo.o
gcc -shared -o libbar.so bar.o -L. -lfoo
现在在构建测试时,我故意不提供对 libfoo 的直接依赖:
cheshar@editsb:~/2-test $ gcc -o test test.o -L. -lbar -Wl,-rpath-link=.
/usr/bin/ld: test.o: undefined reference to symbol 'foo'
./libfoo.so: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
cheshar@editsb:~/2-test $ ldd libbar.so
linux-vdso.so.1 => (0x00007ffe27bf7000)
libfoo.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7d203e0000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7d209ac000)
正如我们所见,test 需要符号 foo 并依赖于 libbar,而 libbar 又依赖于 libfoo 并具有所需的符号。所以我的问题是为什么链接器不能解析符号?是不是应该可以扫描所有的依赖和链接来生成可执行文件?
【问题讨论】:
标签: gcc linker shared-libraries ldd