Linux动态库的查找路径
前两天写了一个动态库,然后试图编译到程序里面去运行,结果发现编译的时候通过gcc的-L参数来指定路径仅仅能让编译通过,运行时还是会出问题的。
比如下面这个例子:
main.c是主程序,sum.c中间含有一个函数add,用来执行加法,代码如下:
/*
* main.c
*/
#include <stdio.h> int add(int a, int b); int main(int argc,char *argv[])
{
printf("sum = %d\n", add(,));
return ;
}
/*
* sum.c
*/
int add(int a, int b)
{
return a + b;
}
出错结果如下图所示:

我在编译的时候通过-L指定了查找动态库的位置,结果运行的时候还是找不到我自己写的那个libsum.so这个动态库,后来去查了一下,才明白其中原委。
程序在链接动态库的时候分为2步,编译时链接和运行时链接。
1. 编译时链接
这个过程是由ld程序来执行的,所以编译时找不到动态库的位置的话,经常就会看到这种错误:

这个过程严格意义上来说并不能说是链接,因为在这里ld程序并没有真正的把库里面的函数的执行代码写到可执行文件里面,只是把一些符号还有其他的必要信息写道了可执行文件里面,供可执行文件运行时查找。
总的来说,ld在这一步里面就是做了两个事情:
1. 查找动态库中是否含有我们需要的符号(函数和全局变量),如果都能找到,则链接允许通过,生成了可执行文件。
2. 在可执行文件中写入了符号和其他必要的信息(例如符号的地址),供可执行文件运行时查找。
2. 运行时链接
这个过程是由ld-linux.so程序来执行,这个才是真正的链接。它所做的工作就是将动态库的代码映射到进程(可执行文件运行起来就是进程啦...)的虚拟地址空间中,供进程来调用。
关于链接,加载,运行的更多信息可以参看<参考文章1>(详细地址见本文最后)。
OK,明白了上面两个链接之后,我们再来看这两个链接查找动态库的目录位置,如下:
运行时,ld-linux.so查找共享库的顺序
(1)ld-linux.so.6在可执行的目标文件中被指定,可用readelf命令查看
(2)ld-linux.so.6缺省在/usr/lib和lib中搜索;当glibc安装到/usr/local下时,它查找/usr/local/lib
(3)LD_LIBRARY_PATH环境变量中所设定的路径
(4)/etc/ld.so.conf(或/usr/local/etc/ld.so.conf)中所指定的路径,由ldconfig生成二进制的ld.so.cache中
编译时,ld-linux.so查找共享库的顺序
(1)ld-linux.so.6由gcc的spec文件中所设定
(2)gcc --print-search-dirs所打印出的路径,主要是libgcc_s.so等库。可以通过GCC_EXEC_PREFIX来设定
(3)LIBRARY_PATH环境变量中所设定的路径,或编译的命令行中指定的-L/usr/local/lib
(4)binutils中的ld所设定的缺省搜索路径顺序,编译binutils时指定。(可以通过“ld --verbose | grep SEARCH”来查看)
(5)二进制程序的搜索路径顺序为PATH环境变量中所设定。一般/usr/local/bin高于/usr/bin
(6)编译时的头文件的搜索路径顺序,与library的查找顺序类似。一般/usr/local/include高于/usr/include
大家注意编译时查找的路径可以通过gcc -L参数或者LIBRARY_PATH来指定,但是运行时的查找路径却不包含gcc -L和LIBRARY_PATH环境变量指定的路径,所以这样就会出现我们刚开始所说的那个问题,编译时通过-L指定了动态库的搜索路径,编译也通过了,但是运行时却会报错,这是因为运行时查找动态库的路径还没指定,所以我们自己写的动态库就找不到了,而要解决这个问题,通过设置环境变量LD_LIBRARY_PATH或者修改/etc/ld.so.conf(记得修改完了运行ldconfi来生成ld.so.cache)就可以了。如下图所示:

参考文章:
3. readelf命令
Linux动态库的查找路径的更多相关文章
- Linux动态库(.so)搜索路径
主要内容: 1.Linux动态库.so搜索路径 编译目标代码时指定的动态库搜索路径: 环境变量LD_LIBRARY_PATH指定的动态库搜索路径: 配置文件/etc/ld.so.conf中指定的动态库 ...
- LINUX动态库(.SO)搜索路径(目录)设置方法
LINUX动态库(.SO)搜索路径(目录)设置方法 [root@VM_0_11_centos ld.so.conf.d]# cat /etc/ld.so.confinclude ld.so.conf. ...
- linux动态库默认搜索路径设置的三种方法
众所周知, Linux 动态库的默认搜索路径是 /lib 和 /usr/lib .动态库被创建后,一般都复制到这两个目录中.当程序执行时需要某动态库, 并且该动态库还未加载到内存中,则系统会自动到这两 ...
- Linux动态库的搜索路径
下面是目录结构: pengdl@localhost:~$ tree test/test/├── fun.c├── Fun.h└── t1 └── main.c 1 directory, 3 fi ...
- linux 动态库加载路径修改
1.在 /etc/ld.so.conf 文件中添加搜索路径,重启或者 ldconfig 生效: 2.在 /etc/ld.so.conf.d 目录下添加 *.conf 文件,其中可以添加搜索路径,重启获 ...
- linux动态库加载路径修改
1.在 /etc/ld.so.conf 文件中添加搜索路径,重启或者 ldconfig 生效: 2.在 /etc/ld.so.conf.d 目录下添加 *.conf 文件,其中可以添加搜索路径,重启获 ...
- 【转载】Linux动态库搜索路径的技巧
转自:http://soft.chinabyte.com/os/232/11488732_2.shtml 众所周知,Linux动 态库的默认搜索路径是/lib和/usr/lib.动态库被创建后,一般都 ...
- Linux动态库搜索路径的技巧
众所周知,Linux动态库的默认搜索路径是/lib和/usr/lib.动态库被创建后,一般都复制到这两个目录中.当程序执行时需要某动态库,并且该动态库还未加载到内存中,则系统会自动到这两个默认搜索路径 ...
- linux动态库加载时搜索路径
摘自http://gotowqj.iteye.com/blog/1926613 对动态库的实际应用还不太熟悉的读者可能曾经遇到过类似“error while loading shared librar ...
随机推荐
- C#EasyHook例子C# Hook 指定进程C#注入指定进程 z
http://bbs.msdn5.com/thread-75-1-1.html http://pan.baidu.com/s/1pJDgHcR
- 原密码忘了,重置MAC开机密码
如果登陆密码忘了,或者你接手了一台前任同事的MAC,而他设了密码没告诉你,你可以这样: 1.重启MAC,然后在启动时按下:CMD+S 2.进入命令行格式后输入:fsck -y (file system ...
- jquery判断自己是父节点的第几个子节点
<div> <span>内容</span> <span>内容</span> <span>内容</span> < ...
- compass项目监控文件报 /usr/bin/env 找不到文件
1 找到ruby执行文件目录 $ wherris ruby ruby: /usr/lib/ruby /home/rudy/.rbenv/shims/ruby 2 设置软链接 sudo ln -s /h ...
- 微信JSSDK上传多张图片
之前是使用for循环实现的,但是安卓手机没有问题,苹果手机只能上传最后一张图片. 好在有高手在前面趟路,实用的循环调用.苹果是没有,安卓不清楚.以下内容转自:http://leo108.com/pid ...
- java异常处理机制Exception
Exception是一个整体的异常,子类NullPointerException.StringIndexOutOfBoundsException 异常处理语句 try{ 可能发生异常的代码片段 }ca ...
- java记录在线人数小案例
文件目录: web.xml: <?xml version="1.0" encoding="UTF-8"?> <web-app version= ...
- CodeForces 602E【概率DP】【树状数组优化】
题意:有n个人进行m次比赛,每次比赛有一个排名,最后的排名是把所有排名都加起来然后找到比自己的分数绝对小的人数加一就是最终排名. 给了其中一个人的所有比赛的名次.求这个人最终排名的期望. 思路: 渣渣 ...
- C# 位域[flags] 转
C# 位域[flags] .NET中的枚举我们一般有两种用法,一是表示唯一的元素序列,例如一周里的各天:还有就是用来表示多种复合的状态.这个时候一般需要为枚举加上[Flags]特性标记为位域,例如: ...
- 如何为 Drupal 7 网站添加悬浮的反馈按钮?
最近有客户咨询我们要怎么为 Drupal 网站添加悬浮按钮,方便访客能够链接到反馈表单页面.很幸运,使用 Feedback Simple 模块可以很容易实现. 在这篇短教程中,我将和大家分享如何添加链 ...