动态库的动态链接(error while loading shared libraries,cannot open shared object file)

$ gcc main.c -g -L. -lstack -o main
$ ./main
./main:error while loading shared libraries: libstack.so:cannot open
shared object file: No such file or directory

linux下编译可执行文件时,经常需要使用到其他的第三方的动态库,通常我们使用-L指定动态库路径,-l指定动态库名字,这样编译没有问题,由于指定了-L.选项,编译器可以在相应目录下找到.so,而运行时却说找不到.so。那么运行时在哪些路径下找动态库呢?首先用ldd命令查看可执行文件依赖于哪些动态库:

$ ldd main
linux-gate.so.1 => (0xb7f5c000)
libstack.so => not found
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7dcf000)
/lib/ld-linux.so.2 (0xf7f42000)

ldd模拟执行一遍main,在运行过程中做动态链接,从而得知这个程序依赖于哪些动态库,这些动态库在什么路径下。gcc 调用ld做链接时用-dynamic-linker /lib/ld-linux.so.2 选项指定动态连接器的路径,动态连接器它也像其他动态库一样加载到进程的地址空间中。而另外一个选项-lc说明了需要链接libc库,却没有指出libc库的完整路径,-lstack就是这样,动态库的路径需要运行时由动态连接器/lib/ld-linux.so.2去查找

设置动态链接器搜索动态库的路径

上面的例子中,动态连接器找到的路径是:/lib/tls/i685/cmov/.libc.so.6,而libstack的路径没有找到,无法完成链接。那么动态链接器会到哪些目录下搜索动态库呢?从ld.so(8)可以查到动态库路径的搜索顺序:

1. 首先在环境变量LD\_LIBRARY\_PATH保存的路径中查找。
2. 然后从缓存文件/etc/ld.so.cache中查找。这个缓存文件是由ldconfig命令读取配置文件/etc/ld.so.conf生成的,这个后面会详细解释。
3. 如果上述步骤都找不到,则到默认的系统库文件目录中查找,先是/usr/lib
   然后是/lib。

一、修改环境变量法

$ LD_LIBRARY_PATH = /home/akaedu/testdir ./main

这个方法只适合在开发调试中临时用一下,设置环境变量法通常是不推荐的。

二、修改配置文件法
这是最常用的方法。把libstack.so所在的目录的绝对路径(比如/home/akaedu/somedir)添加到配置文件/etc/lib.so.conf(该文件中每个路径占一行),然后运行ldconfig:

$ sodu ldconfig -v

ldconfig命令可以生成/etc/ld.so.cache缓存文件,动态连接器就从这个缓存文件中搜索动态库。

三、文件拷贝法
把libstack.so拷到/usr/lib或/lib目录,这样可以确保动态链接器能找到这个动态库。

四、写死路径法

$ gcc main.c -g -L. -lstack -o main -W1 -rpath, /home/akaedu/somedir

注意选项-W1, -rpath, /home/akaedu/somedir, -W1 表示gcc传给链接器的选项。这种方法不推荐,把搜索路径写死在可执行文件中是一种硬代码的做法。

转自:http://akaedu.github.io/post/09/9.3.html
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值