动态库连接依赖问题

学习 专栏收录该内容
3 篇文章 0 订阅

最近在编译工程时遇到一些,动态库链接依赖的问题,现总结出来,以作备忘。


1、自己编写的动态库依赖系统库(如pthread库),可执行程序链接自己的库后找不到系统库(pthread)中的函数:

自己动态库的编译命令如下:

(1)g++ -fPIC -g -O0 -Wall -I//usr/include   -L//usr/lib -L//lib  -lpthread -lrt -shared -o libhmlpmanager_service.so hmlp_IF.o hmlp_device.o hmlp_manager.o hmlp_noticeData.o hmlp_package.o hmlp_socket.o -L  ../../../../mw/hmlp/build/lib -lcommon 

可执行程序编译命令如下:

(2)g++ -g -O0 -Wall -I//usr/include -o ../../mw/hmlp/build/bin/Hmlp_client -L//usr/lib -L//lib   -L../../mw/hmlp/build/lib -lhmlptest -lhmlpmanager_service -lcommon 

编译可执行程序时报错:../../mw/hmlp/build/lib/libhmlpmanager_service.so: undefined reference to `pthread_create'


在动态库编译过程中明明已经添加了pthread库,并且动态库也编译成功了,为什么在使用动态库的时候会报找不到 `pthread_create'的错误呢?

使用ldd命令查看编译的动态库对其他库的依赖:

(3)ldd libhmlpmanager_service.so 
linux-gate.so.1 =>  (0xb7784000)
libstdc++.so.6 => /usr/lib/i386-linux-gnu/libstdc++.so.6 (0xb7677000)
libgcc_s.so.1 => /lib/i386-linux-gnu/libgcc_s.so.1 (0xb7659000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb74ad000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xb7481000)
/lib/ld-linux.so.2 (0xb7785000)

发现里面没有pthread库。


将上面(1)中的编译命令改为:g++ -fPIC -g -O0 -Wall -I//usr/include  -shared -o libhmlpmanager_service.so hmlp_IF.o hmlp_device.o hmlp_manager.o hmlp_noticeData.o hmlp_package.o hmlp_socket.o -L  ../../../../mw/hmlp/build/lib -lcommon  -L//usr/lib -L//lib  -lpthread -lrt

即红色字体部分移到后面,再次进行编译,竟然编译通过了!

原来在(1)中指明了依赖的pthread库的地址,在编译libhmlpmanager_service.so库时使用到的pthread函数都可以在pthread中找到,所以并不报错,但是pthread库中的类容并没有编译进libhmlpmanager_service.so库中(ldd命令查看结果可以证明),所以在编译可执行程序的链接过程中,找不到libhmlpmanager_service.so库中所要使用的pthread中的函数。

将(1)中的编译命令进行修改后,将pthread的类容也编译进了libhmlpmanager_service.so中,所以就不会报错,此时使用ldd得到的结果如下:

ldd libhmlpmanager_service.so 
linux-gate.so.1 =>  (0xb77ae000)
libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 (0xb776b000)
libstdc++.so.6 => /usr/lib/i386-linux-gnu/libstdc++.so.6 (0xb7686000)
libgcc_s.so.1 => /lib/i386-linux-gnu/libgcc_s.so.1 (0xb7667000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb74bc000)
/lib/ld-linux.so.2 (0xb77af000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xb7490000)


2、自己编写的动态库A依赖自己编写的动态库B,可执行程序C依赖动态库A:

在编译A时使用:-L $(动态库B的路径) lB,指明连接的动态库B,编译OK

在编译C时使用:-L $(动态库A的路径) lA,指明连接的动态库A,编译NG,报错找不到动态库B中的函数;

使用ldd查看动态库A的依赖时,动态库B的后面没有地址,而是not found


原来,因为-L选项指定的路径只在编译时有效,编译出来的动态库A不知道-L选项后面的值,当然找不到。

既然找到了原因那么如何解决呢?解决方法是通过-Wl,rpath=<your_lib_dir>,使得编译出的库记住链接库的位置。

-Wl选项告诉编译器将后面的参数传递给链接器





  • 0
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值