转自:http://soft.chinabyte.com/os/232/11488732_2.shtml

众所周知,Linux动 态库的默认搜索路径是/lib和/usr/lib。动态库被创建后,一般都复制到这两个目录中。当程序执行时需要某动态库,并且该动态库还未加载到内存 中,则系统会自动到这两个默认搜索路径中去查找相应的动态库文件,然后加载该文件到内存中,这样程序就可以使用该动态库中的函数,以及该动态库的其它资源 了。在Linux 中,动态库的搜索路径除了默认的搜索路径外,还可以通过以下三种方法来指定。

  方法一:在配置文件/etc/ld.so.conf中指定动态库搜索路径。

  可以通过编辑配置文件/etc/ld.so.conf来指定动态库的搜索路径,该文件中每行为一个动态库搜索路径。每次编辑完该文件后,都必须运行命令ldconfig使修改后的配置生效。我们通过例1来说明该方法。

  例1:

  我们通过以下命令用源程序pos_conf.c(见程序1)来创建动态库 libpos.so,详细创建过程请参考文[1]。

  # gcc -c pos_conf.c

  # gcc -shared -fPCI -o libpos.so pos_conf.o

  #

  #include

  void pos()

  {

  printf("/root/test/conf/lib\n");

  }

  程序1: pos_conf.c

  接着通过以下命令编译main.c(见程序2)生成目标程序pos。

  # gcc -o pos main.c -L. -lpos

  #

  void pos();

  int main()

  {

  pos();

  return 0;

  }

  程序2: main.c

  然后把库文件移动到目录/root/test/conf/lib中。

  # mkdir -p /root/test/conf/lib

  # mv libpos.so /root/test/conf/lib

  #

  最后编辑配置文件/etc/ld.so.conf,在该文件中追加一行"/root/test/conf/lib"。

  运行程序pos试试。

  # ./pos

  ./pos: error while loading shared libraries: libpos.so: cannot open shared object file: No such file or directory

  #

  出错了,系统未找到动态库libpos.so。找找原因,原来在编辑完配置文件/etc/ld.so.conf后,没有运行命令ldconfig,所以刚才的修改还未生效。我们运行ldconfig后再试试。

  # ldconfig

  # ./pos

  /root/test/conf/lib

  #

  程序pos运行成功,并且打印出正确结果。

  方法二:通过环境变量LD_LIBRARY_PATH指定动态库搜索路径。

  通过设定环境变量LD_LIBRARY_PATH也可以指定动态库搜索路径。当通过该环境变量指定多个动态库搜索路径时,路径之间用冒号":"分隔。下面通过例2来说明本方法。

  例2:

  我们通过以下命令用源程序pos_env.c(见程序3)来创建动态库libpos.so。

  # gcc -c pos_env.c

  # gcc -shared -fPCI -o libpos.so pos_env.o

  #

  #include

  void pos()

  {

  printf("/root/test/env/lib\n");

  }

  程序3: pos_env.c

  测试用的可执行文件pos可以使用例1中的得到的目标程序pos,不需要再次编译。因为pos_conf.c中的函数pos和 pos_env.c中的函数pos 函数原型一致,且动态库名相同,这就好比修改动态库pos后重新创建该库一样。这也是使用动态库的优点之一。

  然后把动态库libpos.so移动到目录/root/test/conf/lib中。

  # mkdir -p /root/test/env/lib

  # mv libpos.so /root/test/env/lib

  #

  我们可以使用export来设置该环境变量,在设置该环境变量后所有的命令中,该环境变量都有效。

  例如:

  # export LD_LIBRARY_PATH=/root/test/env/lib

  #

  但本文为了举例方便,使用另一种设置环境变量的方法,既在命令前加环境变量设置,该环境变量只对该命令有效,当该命令执行完成后,该环境变量就无效了。如下述命令:

  # LD_LIBRARY_PATH=/root/test/env/lib ./pos

  /root/test/env/lib

  #

  程序pos运行成功,并且打印的结果是"/root/test/env/lib",正是程序pos_env.c中的函数pos的运行结果。因此程序pos搜索到的动态库是/root/test/env/lib/libpos.so。

方法三:在编译目标代码时指定该程序的动态库搜索路径。

  还可以在编译目标代码时指定程序的动态库搜索路径。这是通过gcc 的参数"-Wl,-rpath,"指定(如例3所示)。当指定多个动态库搜索路径时,路径之间用冒号":"分隔。

  例3:

  我们通过以下命令用源程序pos.c(见程序4)来创建动态库libpos.so。

  # gcc -c pos.c

  # gcc -shared -fPCI -o libpos.so pos.o

  #

  #include

  void pos()

  {

  printf("./\n");

  }

  程序4: pos.c

  因为我们需要在编译目标代码时指定可执行文件的动态库搜索路径,所以需要用gcc命令重新编译源程序main.c(见程序2)来生成可执行文件pos。

  # gcc -o pos main.c -L. -lpos -Wl,-rpath,./

  #

  再运行程序pos试试。

  # ./pos

  ./

  #

  程序pos运行成功,输出的结果正是pos.c中的函数pos的运行结果。因此程序pos搜索到的动态库是./libpos.so。

  以上介绍了三种指定动态库搜索路径的方法,加上默认的动态库搜索路径/lib和/usr/lib,共五种动态库的搜索路径,那么它们搜索的先后顺序是什么呢?

  在介绍上述三种方法时,分别创建了动态库./libpos.so、 /root/test/env/lib/libpos.so和/root/test/conf/lib/libpos.so。我们再用源程序 pos_lib.c(见程序5)来创建动态库/lib/libpos.so,用源程序pos_usrlib.c(见程序6)来创建动态库/usr/lib /libpos.so。

  #include

  void pos()

  {

  printf("/lib\n");

  }

  程序5: pos_lib.c

  #include

  void pos()

  {

  printf("/usr/lib\n");

  }

  程序6: pos_usrlib.c

  这样我们得到五个动态库libpos.so,这些动态库的名字相同,且都包含相同函数原型的公用函数pos。但存储的 位置不同和公用函数pos 打印的结果不同。每个动态库中的公用函数pos都输出该动态库所存放的位置。这样我们可以通过执行例3中的可执行文件pos得到的结果不同获知其搜索到了 哪个动态库,从而获得第1个动态库搜索顺序,然后删除该动态库,再执行程序pos,获得第2个动态库搜索路径,再删除第2个被搜索到的动态库,如此往复, 将可得到Linux搜索动态库的先后顺序。程序pos执行的输出结果和搜索到的动态库的对应关系如表1所示:

  程序pos输出结果使用的动态库对应的动态库搜索路径指定方式

  ././libpos.so编译目标代码时指定的动态库搜索路径

  /root/test/env/lib/root/test/env/lib/libpos.so环境变量LD_LIBRARY_PATH指定的动态库搜索路径

  /root/test/conf/lib/root/test/conf/lib/libpos.so配置文件/etc/ld.so.conf中指定的动态库搜索路径

  /lib/lib/libpos.so默认的动态库搜索路径/lib

  /usr/lib/usr/lib/libpos.so默认的动态库搜索路径/usr/lib

  表1: 程序pos输出结果和动态库的对应关系

  创建各个动态库,并放置在相应的目录中。测试环境就准备好了。执行程序pos,并在该命令行中设置环境变量LD_LIBRARY_PATH。

  # LD_LIBRARY_PATH=/root/test/env/lib ./pos

  ./

  #

  根据程序pos的输出结果可知,最先搜索的是编译目标代码时指定的动态库搜索路径。然后我们把动态库./libpos.so删除了,再运行上述命令试试。

  # rm libpos.so

  rm: remove regular file `libpos.so'? y

  # LD_LIBRARY_PATH=/root/test/env/lib ./pos

  /root/test/env/lib

  #

  根据程序pos的输出结果可知,第2个动态库搜索的路径是环境变量LD_LIBRARY_PATH指定的。我们再把/root/test/env/lib/libpos.so删除,运行上述命令。

  # rm /root/test/env/lib/libpos.so

  rm: remove regular file `/root/test/env/lib/libpos.so'? y

  # LD_LIBRARY_PATH=/root/test/env/lib ./pos

  /root/test/conf/lib

  #

  第3个动态库的搜索路径是配置文件/etc/ld.so.conf指定的路径。删除动态库/root/test/conf/lib/libpos.so后再运行上述命令。

  # rm /root/test/conf/lib/libpos.so

  rm: remove regular file `/root/test/conf/lib/libpos.so'? y

  # LD_LIBRARY_PATH=/root/test/env/lib ./pos

  /lib

  #

  第4个动态库的搜索路径是默认搜索路径/lib。我们再删除动态库/lib/libpos.so,运行上述命令。

  # rm /lib/libpos.so

  rm: remove regular file `/lib/libpos.so'? y

  # LD_LIBRARY_PATH=/root/test/env/lib ./pos

  /usr/lib

  #

  最后的动态库搜索路径是默认搜索路径/usr/lib。

  综合以上结果可知,动态库的搜索路径搜索的先后顺序是:

  1.编译目标代码时指定的动态库搜索路径;

  2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;

  3.配置文件/etc/ld.so.conf中指定的动态库搜索路径;

  4.默认的动态库搜索路径/lib;

  5.默认的动态库搜索路径/usr/lib。

  在上述1、2、3指定动态库搜索路径时,都可指定多个动态库搜索路径,其搜索的先后顺序是按指定路径的先后顺序搜索的。对此本文不再举例说明,有兴趣的读者可以参照本文的方法验证。

【转载】Linux动态库搜索路径的技巧的更多相关文章

  1. Linux动态库搜索路径的技巧

    众所周知,Linux动态库的默认搜索路径是/lib和/usr/lib.动态库被创建后,一般都复制到这两个目录中.当程序执行时需要某动态库,并且该动态库还未加载到内存中,则系统会自动到这两个默认搜索路径 ...

  2. Linux 静态库与动态库搜索路径设置详解

    转载:http://blog.chinaunix.net/uid-29025972-id-3855495.html 1. 连接和运行时库文件搜索路径的设置 库文件在连接(静态库和共享库)和运行(仅限于 ...

  3. Linux 静态库与动态库搜索路径设置详解【转】

    原文地址:http://blog.chinaunix.net/uid-29025972-id-3855495.html 1. 连接和运行时库文件搜索路径的设置 库文件在连接(静态库和共享库)和运行(仅 ...

  4. GDB动态库搜索路径

    当GDB无法显示so动态库的信息或者显示信息有误时,通常是由于库搜索路径错误导致的,可使用set sysroot.set solib-absolute-prefix.set solib-search- ...

  5. linux添加动态库搜索路径

    在有时运行程序出现动态库找不着的问题,而明明装了的.这时候可能是没有将相应的路径添加到系统中去. 具体说:cd /etc/ld.so.conf.d/ 可以发现里面有一堆*.conf的文件 我们要做的就 ...

  6. Windows平台LoadLibrary加载动态库搜索路径的问题

    一.背景 在给Adobe Premiere/After Effects等后期制作软件开发第三方插件的时候,我们总希望插件依赖的动态库能够脱离插件的位置,单独存储到另外一个地方.这样一方面可以与其他程序 ...

  7. linux动态库默认搜索路径设置的三种方法

    众所周知, Linux 动态库的默认搜索路径是 /lib 和 /usr/lib .动态库被创建后,一般都复制到这两个目录中.当程序执行时需要某动态库, 并且该动态库还未加载到内存中,则系统会自动到这两 ...

  8. linux动态库加载时搜索路径

    摘自http://gotowqj.iteye.com/blog/1926613 对动态库的实际应用还不太熟悉的读者可能曾经遇到过类似“error while loading shared librar ...

  9. Linux动态库(.so)搜索路径

    主要内容: 1.Linux动态库.so搜索路径 编译目标代码时指定的动态库搜索路径: 环境变量LD_LIBRARY_PATH指定的动态库搜索路径: 配置文件/etc/ld.so.conf中指定的动态库 ...

随机推荐

  1. linux nc (NetCat) 命令详解

    原文:http://www.huanxiangwu.com/477/linux-nc-netcat 一.版本通常的Linux发行版中都带有NetCat(简称nc),甚至在拯救模式光盘中也由busybo ...

  2. centos 6.4 /var/log/secure 不记录日志的問題

    先确保日志服务开启:不妨重启下日志服务:由于目前RHEL 6/centos 6已经使用rsyslog替换了syslog.,所以不要在找/etc/syslog.conf了:重启命令:/etc/init. ...

  3. go语言实现一个简单的登录注册web小程序

    最近学习golang也有一段时间了,基础差不多学了个大概,因为本人是java程序员,所以对web更感兴趣.根据<go web编程>中的例子改编一个更简单的例子,供新手参考,废话不多说,上菜 ...

  4. OpenCV相机标定和姿态更新

    原帖地址: http://blog.csdn.net/aptx704610875/article/details/48914043 http://blog.csdn.net/aptx704610875 ...

  5. checkbox的三种状态处理

    checkbox只有两种值:选中(checked)或未选中(unchecked).它可以有任何值,但是表单提交时checkbox的值只能是checked或unchecked.它的默认值是uncheck ...

  6. Jmeter属性和变量

    一.Jmeter中的属性: 1.JMeter属性统一定义在jmeter.properties文件中,我们可以在该文件中添加自定义的属性 2.JMeter属性在测试脚本的任何地方都是可见的(全局),通常 ...

  7. CSS计数器的趣味时光

    CSS计数器是“啊太好了,竟不知道CSS可以做这啊”这类非常有趣的众多特性之一.简言之,用CSS使你持续某增加某个量,而无需JavaScript. 简单计数器 我们从这个简单的分页示例开始: 你见到的 ...

  8. 北京地铁月度消费总金额计算(Python版)

    最近业余时间在学习Python,这是那天坐地铁时突发奇想,想看看我这一个月的地铁费共多少钱,所以简单的构思了下思路,就直接开写了,没想到用Python来实现还挺简单的. 设计思路: 每次乘车正常消费7 ...

  9. adding validation annotators to model classes 在linq to EntityFrame的Model中添加前台验证validation annotators

    The same solution can be applied for LINQ to SQL. The snippet the article shows for using the Metada ...

  10. Java对象生命周期

    [TOC] 1. 创建阶段(Created) 为对象分配存储空间 开始构造对象 从父类到子类对static成员进行初始化 父类成员变量按照顺序初始化,递归调用父类的构造方法 子类成员变量按照顺序初始化 ...