首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

Linux上库相关的概略介绍及动态库的搜索路径优先级

2012-08-26 
Linux下库相关的概略介绍及动态库的搜索路径优先级(本文主要针对动态连接库,内容来源网络,重新整理之,高亮

Linux下库相关的概略介绍及动态库的搜索路径优先级

(本文主要针对动态连接库,内容来源网络,重新整理之,高亮部分的请重点关注)

?

一.基本知识
  总体来说, 库可以有三种使用的形式: 静态、共享和动态. 静态库的代码在编译时就已连接到开发人员开发的应用程序中, 而共享库只是在程序开始运行时才载入. 在编译时, 只是简单地指定需要使用的库函数. 动态库则是共享库的另一种变化形式. 动态库也是在程序运行时载入, 但与共享库不同的是, 使用的库函数不是在程序运行开始, 而是在程序中的语句需要使用该函数时才载入. 动态库可以在程序运行期间释放动态库所占用的内存, 腾出空间供其它程序使用. 由于共享库和动态库并没有在程序中包括库函数的内容, 只是包含了对库函数的引用,因此代码的规模比较小.

  而Linux下的库文件分为共享库和静态库两大类, 它们两者的差别仅在程序执行时所需的代码是在运行时动态加载的, 还是在编译时静态加载的. 区分库类型最好的方法是看它们的文件后缀,通常共享库以.so(Shared Object的缩写)结尾, 静态链接库通常以.a结尾(Archive的缩写). 在终端缺省情况下, 共享库通常为绿色, 而静态库为黑色.

  已经开发的大多数库都采取共享库的方式. ELF格式的可执行文件使得共享库能够比较容易地实现, 当然使用旧的a.out模式也可以实现库的共享. Linux系统中目前可执行文件的标准格式为ELF(Executable and Linkable Format)格式(可点击查看此定义).

  .a的是为了支持较老的a.out格式的可执行文件.
  .so的是支持elf格式的可执行文件的库.

  ? .a是静态库文件, 可以用ar 命令生成.
  .so是动态库文件, 编译时加上指定的选项即可生成.

?

二.命名规则
????? GNU库的使用必须遵守Library GNU Public License(LGPL许可协议). 该协议与GNU许可协议略有不同, 开发人员可以免费使用GNU库进行软件开发, 但必须保证向用户提供所用的库函数的源代码.

  系统中可用的库都存放在/usr/lib和/lib目录中. 库文件名由前缀lib和库名以及后缀组成. 根据库的类型不同, 后缀名也不一样.
  共享库的后缀名由.so和版本号组成, 静态库的后缀名为.a.

 ? libname.so.major.minor.patchlevel

 ? name : 可以是任何字符串, 用来唯一标识某个库. 该字符串可以是一个单字、几个字符、甚至一个字母.
 ? major : 主版本号
 ? minor : 次版本号
 ? patchlevel : 补丁版本

?

三.库操作 (具体操作本文不详述)
 ? ldd(Library Dependency Display) : 显示一个executable program对库的依赖关系 .
?
 ? ldconfig - configure dynamic linker run-time bindings : 他的作用就是为了让动态链接库被系统所认识及共享 .
 ? 默认搜寻/lib/usr/lib 以及动态库配置文件/etc/ld.so.conf 内所列的目录, 创建出动态装入程序(ld.so)所需的连接和缓存文件(/etc/ld.so.cache)
—————————————————————————————————————
 ? 关于 ld.so 此处多说几句
 ? 共享库装载器&动态连接器 : 当程序被调用的时候, Linux 共享库装载器也自动被调用. By the way , ‘共享库装载器’这个名词的定义不知正确否. 但无论是什么 , 它的作用是保证程序所需要的所有适当版本的库都被调入内存. 而可能的共享库装载器的名字就是 ld.so 或者是 ld-linux.so(取决于 Linux libc 的版本)
—————————————————————————————————————

四.动态库的搜索路径优先级

 ? Section 3 提到*.so被寻在/lib、/usr/lib 以及/etc/ld.so.conf 内所列的目录中 , 这就涉及到优先搜索哪个路径文件夹的问题. 于是 , 解渴先 :
 ? 动态链接器ld.so按照下面的顺序来搜索需要的动态共享库:

 ? 1.ELF可执行文件中动态段中DT_RPATH所指定的路径. 这实际上是通过一种不算很常用, 却比较实用的方法所设置的: 编译目标代码时, 可以对gcc加入链接参数“-Wl,-rpath”指定动态库搜索路径;
 ? 2.环境变量LD_LIBRARY_PATH 指定的动态库搜索路径;
 ? 3./etc/ld.so.cache中所缓存的动态库路径(如果支持ld.so.cache的话) . 这可以通过修改配置文件/etc/ld.so.conf中指定的动态库搜索路径来改变;
 ? 4.默认的动态库搜索路径/lib;
 ? 5.默认的动态库搜索路径/usr/lib.
????
 ? Comment : 在嵌入式Linux系统的实际应用中, 1和2被经常使用, 也有一些相对简单的的嵌入式系统会采用4或5的路径来规范动态库. 3在嵌入式系统中使用的比较少, 因为有很多系统根本就不支持ld.so.cache.

 ? if(!you care about how i get this result){
 ?  ?  ? echo The End . BYEBYE!
 ? }
 ? else
 ?  ?  ?

在上述5种或者更多的路径下,分别编译出libenvpos.o(注意要同名啊).

 ?  ?   # gcc -c pos_env.c
 ?  ?  ?  ?????????? # gcc -shared -fPCI -o libenvpos.so pos_env.o
 ?  ?  ?  ?????????? #

 ? ?  ?  ? ?????????? #include
??  ?  ?  ??????  ? ?? void pos()
??  ?  ?  ???????  ? ? {
  ?  ?  ?? ?????????? ??????? printf(”/yourURL/lib\n”);
 ?  ?    ? ??????????? }
 ?  ?  ?  ? program: pos_env.c
—————————————————————————————————————
 ?  ?  ? # gcc -o pos main.c -L. -lenvpos

 ?  ?  ? #

 ?  ?  ?  ?  ? void pos();
 ?  ?  ? ????????? int main()
 ?  ?  ? ????????? {
? ?  ?  ? ????????????? pos();
 ?  ?  ? ?????????????? return 0;
 ?  ?  ? ????????? }
—————————————————————————————————————

 ?  ?  ?? 执行./pos 看输出结果 , 输出一个结果后就到结果指向的目录下删除*.so之 . 一次这样顺序的搞定也就知道搜索的优先级了 .
—————————————————————————————————————

热点排行