两个共享库liba.so和libb.so. liba.so使用libb.so.所有c文件都使用-fPIC编译。链接使用-shared。当我们在liba.so上调用dlopen时,它无法在libb.so中找到符号...我们得到“未定义符号”错误。我们可以dlopen libb.so没有错误。我们知道liba正在寻找libb,因为我们没有找到找不到文件的错误。删除libb.so时,我们收到文件未找到错误。我们试过 - 但没有运气。
任何想法????
哦,是的。 gcc 4.1.2更新:我们在链接liba时使用rpath,因此它可以找到libb。
ldd liba.so返回:
linux-gate.so.1 => (0xffffe000)
libb.so => ./libb.so (0xf6ef9000) <-------- LIBB
libutil.so.1 => /lib/libutil.so.1 (0xf6ef5000)
libdl.so.2 => /lib/libdl.so.2 (0xf6ef1000)
libm.so.6 => /lib/libm.so.6 (0xf6ec9000)
libpthread.so.0 => /lib/libpthread.so.0 (0xf6eb1000)
librt.so.1 => /lib/librt.so.1 (0xf6ea8000)
libc.so.6 => /lib/libc.so.6 (0xf6d62000)
/lib/ld-linux.so.2 (0x007d0000)
在libb ???
的末尾没有。#是很有意义的答案 0 :(得分:18)
您可以使用libb.so
命令轻松查看预期ldd
的位置:
$ ldd liba.so
linux-gate.so.1 => (0xb77b0000)
libb.so.1 => not found
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb75b6000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7572000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb742b000)
/lib/ld-linux.so.2 (0xb77b1000)
如果是not found
,则应将libb.so
的路径添加到/etc/ld.so.conf
或shell变量LD_LIBRARY_PATH
。
另一种方法是在rpath
本身设置liba.so
- 它基本上是对其路径进行硬编码,因此当启动二进制文件时,动态链接器会知道在哪里搜索共享库。
如果未设置rpath
,则首先搜索LD_LIBRARY_PATH
,然后搜索/etc/ld.so.conf
(或/etc/ld.so.conf.d/)中提到的路径。添加到ls.so.conf
后,请不要忘记执行/sbin/ldconfig
动态链接器按其soname
(如果已设置)搜索依赖共享库 - 如果未设置soname
(例如,使用-Wl,-soname,libb.so.1),则将按图书馆的名称进行搜索。
示例:libb.so.1.0
是您的实际库,具有soname
- libb.so.1
。您通常会有以下文件结构:
libb.so -> libb.so.1
libb.so.1 -> libb.so.1.0
libb.so.1.0
其中libb.so
和libb.so.1
是符号链接。
在构建某些应用程序或其他库时,您通常会链接到libb.so
,具体取决于libb.so
。
gcc -shared -Wl,-soname,liba.so.1 -o liba.so.1.2 -L/libb/path -lb
当应用程序启动时(或执行dlopen - 您的情况) - 动态链接器将搜索名称为libb.so.1
的文件 - 依赖库的soname
,如果soname
已设置,而不是libb.so
。
这就是为什么你需要那个指向实际库的符号链接libb.so.1
。
如果您使用ld.so.conf
和ldconfig
,则会创建带有soname
名称的符号链接,指向库文件,如果缺少此符号链接。
您可以查看ld-linux手册页以获取更多有用信息。
<小时/> 如果找到了库但缺少某些符号,请尝试使用
libb.so
选项构建-Wl,--no-undefined
gcc -shared -Wl,-soname,libb.so.1 -Wl,--no-undefined -o libb.so.1.2
如果你错过定义某个符号,它会给你一个错误。
答案 1 :(得分:0)
当链接所有objs&amp;时,不要忘记libs顺序(所有-lxxx参数)都很重要(至少在gcc中)。用于生成可执行文件的库。
简短的例子:
LIBS = -L。 -ltest1 -ltest2
OBJS = code1.o code2.o
gcc $(LIBS)$(OBJS)-o mysoft
在某些情况下会失败,而
gcc $(OBJS)-o mysoft $(LIBS)
不会