Linux共享库使用共享库的未定义符号

两个共享库liba.so和libb.so. liba.so使用libb.so. 所有的c文件都是用-fPIC编译的。 链接使用共享。 当我们在liba.so上调用dlopen时,它在libb.so中找不到符号…我们得到“未定义符号”错误。 我们可以直接liblo.so没有错误。 我们知道liba正在查找libb,因为我们没有find文件未find的错误。 当我们删除libb.so时,我们得到一个没有find文件的错误。 我们试过了 – 没有运气。

有任何想法吗????

哦耶。 gcc 4.1.2

更新:在链接liba时使用rpath,因此可以findlibb。

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的末尾?

Solutions Collecting From Web of "Linux共享库使用共享库的未定义符号"

您可以轻松地检查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

另一种方法是在liba.so设置rpath – 它基本上是对其路径进行硬编码,所以当二进制文件启动时,动态链接器将知道在哪里搜索共享库。

如果未设置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是你的实际库,具有sonamelibb.so.1 。 您通常会拥有以下文件结构:

 libb.so -> libb.so.1 libb.so.1 -> libb.so.1.0 libb.so.1.0 

其中libb.solibb.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被设置,而不是libb.so ,则从属库的soname

这就是为什么你需要符号链接libb.so.1 ,指向实际的库。

如果你使用ld.so.confldconfig ,它将会创建一个soname名字的符号链接,指向库文件,如果这个符号链接丢失的话。

你可以看到ld-linux手册页来获取更多有用的信息。


如果找到了这个库,但是其中一些符号丢失,请尝试使用libb.so构建libb.so -Wl,--no-undefined选项

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

如果你错过了定义符号,它会给你一个错误。

不要忘记,链接所有的objs和库来生成可执行文件时,libs命令(all -lxxx参数)是很重要的(至少在gcc中)。

简短的例子:

LIBS = -L。 -ltest1 -ltest2

OBJS = code1.o code2.o

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

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

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

惯于