16

两个共享库 liba.so 和 libb.so。liba.so 使用 libb.so。所有 c 文件都使用 -fPIC 编译。链接使用-shared。当我们在 liba.so 上调用 dlopen 时,它无法在 libb.so 中找到符号……我们得到“未定义符号”错误。我们可以 dlopen libb.so 没有错误。我们知道 liba 正在查找 libb,因为我们没有收到文件未找到错误。删除 libb.so 时出现文件未找到错误。我们尝试了 -lutil 并没有运气。

有任何想法吗????

哦耶。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末尾没有.#是否有意义???

4

2 回答 2

26

您可以使用命令轻松检查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没有设置,它会先搜索,然后搜索(或/etc/ld.so.conf.d/)LD_LIBRARY_PATH中提到的路径。/etc/ld.so.conf添加后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

wherelibb.solibb.so.1are 符号链接。

在构建某些应用程序或其他库时,您通常会链接到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.

这就是为什么你需要那个 symlink libb.so.1,指向实际的库。

如果您使用ld.so.confand ldconfig,它将创建带有soname' 名称的符号链接,指向库文件,如果此符号链接丢失。

您可以查看ld-linux手册页以获取更多有用信息。


如果找到库但缺少某些符号,请尝试libb.so使用-Wl,--no-undefined选项构建

gcc -shared -Wl,-soname,libb.so.1 -Wl,--no-undefined -o libb.so.1.2

如果您错过定义某些符号,它应该会给您一个错误。

于 2010-06-07T17:24:40.927 回答
3

在链接所有 objs 和库以生成可执行文件时,不要忘记 libs 顺序(所有 -lxxx 参数)很重要(至少在 gcc 中)。

简短的例子:

LIBS=-L。-ltest1 -ltest2

OBJS=code1.o code2.o

gcc $(LIBS) $(OBJS) -o mysoft

在某些情况下可能会失败,而

gcc $(OBJS) -o mysoft $(LIBS)

惯于

于 2015-04-21T14:31:14.870 回答