`

三种方法——Linux动态库(.so)搜索路径

 
阅读更多

 

众所周知,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指定动态库搜索路径时,都可指定多个动态库搜索路径,其搜索的先后顺序是按指定路径的先后顺序搜索的。对此本文不再举例说明,有兴趣的读者可以参照本文的方法验证。

 

参考地址:http://www.ylmf.net/linux/tips/2011011120909_2.html

分享到:
评论

相关推荐

    libfreetype.so.6

    《深入理解Linux动态库:libfreetype.so.6详解》 在Linux操作系统中,动态链接库(Dynamic Link Library,简称动态库)是系统提供的一种共享资源,它们包含了一组可重用的函数和数据,可供多个应用程序共享,极大地...

    libtiff.so.5.2.0

    《Linux系统下的libtiff组件详解——以libtiff.so.5.2.0与libtiffxx.so.5.2.0为例》 在Linux操作系统中,动态链接库是程序运行的重要组成部分,它们提供了共享代码的方式,节省了内存资源并简化了软件更新。libtiff...

    libstdc++.so.5.zip

    在Linux操作系统中,动态链接库(Dynamic Link Library,简称DLL或SO库)是程序运行时必不可少的一部分,它们提供了一种方式来共享代码和数据,使得多个程序可以同时使用相同的函数和变量,从而节省内存并提高效率。...

    libcrypto.so.6 &libcrypto.so.0.9.8b

    本文将深入探讨两个重要的动态链接库——`libcrypto.so.6`和`libcrypto.so.0.9.8b`,它们是OpenSSL库的关键组件,广泛应用于各种操作系统和软件项目。 首先,`libcrypto.so`是一个与加密操作相关的动态链接库,它是...

    Jmeter ServerAgent Arm架构 libsigar-aarch64-linux.so

    然后,将`libsigar-aarch64-linux.so`复制到ServerAgent的运行目录,或者将其路径添加到系统的动态库搜索路径中(通常通过修改`/etc/ld.so.conf`并执行`ldconfig`命令来完成)。接着,启动或重启ServerAgent,它就能...

    libmysqlclient.so.18.rar

    这里我们关注的是MySQL数据库系统所依赖的动态链接库文件——`libmysqlclient.so.*`。这两个文件,`libmysqlclient.so.15`和`libmysqlclient.so.18`,是针对不同版本的Linux发行版(如CentOS 7.7和Red Hat 6.5)而...

    libstdc++.so.6.zip

    在Linux环境中,当一个C++程序运行时,如果它依赖于libstdc++.so.6,系统会在默认的库路径(如/lib64或/usr/lib64)中寻找该库。如果找不到相应的版本,系统可能会报错,如"GLIBCXX_3.4.x not found",此时就需要...

    Linux动态库的制作和路径安装

    动态库*.so在linux下用c和c++编程时经常需要使用。  1、动态库的编译  下面通过一个例子来介绍如何生成一个动态库。这里有一个头文件:so_test.h,三个.c文件:test_a.c、test_b.c、test_c.c,我们将这几个文件...

    使用c语言编写动态链接库(linux下.so文件,windows下dll文件),使用python调用c语言接口。.zip

    本示例涉及到的是使用C语言创建动态链接库,并在不同的操作系统环境下——Linux(生成`.so`文件)和Windows(生成`.dll`文件)——进行实现。之后,我们还将讨论如何通过Python语言调用这些C语言编写的接口。这一...

    Linux静态库和动态库

    **Linux库的分类**:Linux下的库主要分为两大类——静态库与动态库,它们的核心区别在于代码的加载时机。静态库在编译阶段即与目标程序结合,而动态库则是在程序运行时动态加载。 #### 静态库与动态库的生成与使用 ...

    qt5、qt6支持中文输入库libfcitxplatforminputcontextplugin.so

    为了在Ubuntu20上使用这些库,开发者或用户需要将它们放置在正确的位置,通常是在系统的动态库路径下,或者在应用的运行环境中指定。同时,系统需要已经安装了Fcitx输入法环境。安装完成后,Qt应用程序就可以自动...

    NetBeans的远程Linux C开发实践(远程调试)——包含了远程链接动态库静态库的方法.docx

    本文将详细介绍如何利用 NetBeans 在 Windows 平台上进行远程 Linux C 的开发与调试,并特别关注远程链接动态库和静态库的方法。 #### 二、配置 NetBeans 远程开发环境 1. **基本配置**: - **操作系统**:...

    在Linux中创建静态库和动态库

    由于动态库是在程序运行时加载的,因此需要确保动态库文件始终存在于指定的路径中或在系统动态链接器的搜索路径中。 #### 结论 通过以上步骤,我们成功地创建了静态库 `libmyhello.a` 和动态库 `libmyhello.so`,...

    libQt5SerialPort.tar.gz

    本文将深入探讨"libQt5SerialPort.tar.gz"这个压缩包,它包含了ARM9 Linux版本的QTSerialport.so动态链接库,以及相关版本的共享库文件。 首先,我们关注标题中的"libQt5SerialPort.tar.gz",这是一个压缩文件,...

    motion需要用到的动态库

    在Linux环境下,动态库通常以`.so`(Shared Object)为扩展名,例如`libc.so.6`就是C语言运行时库的一个版本。 当我们进行软件移植,比如将motion项目从一个环境迁移到另一个时,可能会遇到依赖问题。"motion需要...

    动态库的创建和使用——静态加载

    ### 动态库的创建与使用——静态加载 #### 一、基础知识介绍 **动态链接库**(Dynamic Link Library,简称DLL,在Unix/Linux系统中称为**共享对象**或**共享库**,通常以`.so`扩展名命名)是一种可被多个程序同时...

    linux-x86-64.zip

    在代码中,如果要利用`libtesseract.so`进行OCR操作,开发者需要包含相应的头文件,使用`#include <tesseract/baseapi.h>`等,并链接到这个动态库。在C++代码中,可以创建`TessBaseAPI`对象,初始化Tesseract,加载...

    libsigar-aarch64-linux.rar

    针对这一情况,"libsigar-aarch64-linux.rar"压缩包提供了专为aarch64 Linux平台编译的libsigar动态链接库——libsigar-aarch64-linux.so,解决了libsigar在64位ARM架构上的兼容性问题。 libsigar-aarch64-linux.so...

    node-v14.17.0-linux-x64.tar.gz

    3. `lib`:存放Node.js的动态链接库文件,如`node.so`,这是Node.js的运行时库。 4. `share`:通常包含文档、locale(本地化)信息等共享资源。 5. `doc`:可能包含Node.js的官方文档。 6. `LICENSE`:包含了软件的...

    理解linux下动态链接库延迟绑定.rar_lib_linux

    在Linux操作系统中,动态链接库(Dynamic Linking Libraries,简称DLLs或动态库)是程序运行时共享代码和数据的一种机制。动态库可以减少内存占用,因为多个程序可以共享同一库的实例,同时也能方便地更新和维护系统...

Global site tag (gtag.js) - Google Analytics