Linux下共享链接库 (1)
来源:互联网 发布:网络水军群 编辑:程序博客网 时间:2024/05/29 17:05
共享链接库当应用程序启动时被加载。当一个共享链接库被成功安装后,所有的应用程序从此以后都会自动使用新的共享库。实际上它要比这个更灵活更复杂,因为Linux采用了如下方法允许你:
更新库但是仍然支持应用程序使用老的,不向后兼容的版本;
当执行应用程序时可以覆盖指定的库甚至是库中特定的函数;
就算应用程序正在运行并使用已经存在的库,仍然可以做以上的事情。
为了让共享链接库支持这些特性,我们必须遵循一些惯例和规范。首先你需要明白库的各种名字,特别是soname和realname。你也必须知道这些库应该被放在文件系统中的什么地方。
每一个共享链接库都有一个特别的名字soname。soname由前缀lib,库名,扩展名.so,然后是.和一个版本号组成。版本号会随着接口的变化而递增。最底层的C库是一个例外,因为它不是以lib打头。全限定的soname会以它所在的目录作为前缀。在一个运行的系统中全限定的soname只是realname的符号链接。
每个共享链接库都有一个realname,它是包含真正库代码文件的名字。Realname是由soname后跟一个.,次版本号,另一个.,和发布版本号组成。最后的.和发布版本号是可选的。次版本号和发布版本号支持配置控制,以此让你知道现在安装的库是什么版本。
另外,还有个名字用于编译器请求链接库,我们可以称之为linkernam。它只是soname去掉版本号。
管理动态链接库的关键就是区分这些名字。在应用程序中,当它们内部列出自己需要的共享链接库时,只要列出soname即可。恰恰相反,当你创建一个共享链接库时,你只需要创建一个给定名字的库即可(可以附带更具体的版本信息)。当安装库的一个新版本时,你把它安装在某个特定的文件夹然后运行程序ldconfig。Ldconfig会检测已经存在的文件并创建soname符号连接到realname,同时也会建立缓存文件/etc/ld.so.cache。
Ldconfig并不会建立linkname。典型地这应该在库安装的时候完成,linkername只是简单地作为最新的soname或者realname的符号链接。我本推荐linkername应该是soname的符号链接,因为在大多数场合如果你更新库,你总是希望在链接时自动使用它。我问过H.J.Lu为什么ldconfig不自动建立linkername。他的解释基本上是你可能想要使用最新的版本运行代码,但是要用老版本来开发。所以,ldconfig不会假设你到底需要把应用程序链接到什么版本,所以,安装程序要明确修改符号链接来更新链接器用什么版本的库。
因此,/usr/lib/libreadline.so.3是一个全限定的soname,ldconfig会设置符号链接到某个realname比如/usr/lib/libreadline.so.3.0。也会有一个linkername,/usr/lib/libreadline.so,一个指向/usr/lib/libreadline.so.3的符号链接。
共享链接库必须被放在文件系统的某个地方。大多数开源软件都倾向于遵循GNU标准。GNU标准推荐当发布源代码时把所有库默认安装在/usr/local/lib下,所有的命令安装在/usr/local/bin下。它也定义了一些关于如何覆盖这些默认设置和调用安装例程的约定。
但是FilesystemHierarchyStandard(FHS)也讨论了应该在发布时将库安装在什么目录下。根据FHS规范,大部分库都应该安装在目录/usr/lib,但是启动时所需要的库必须在目录/lib,非系统库应该在目录/usr/local/lib。
这两份文档的规定并不冲突:GNU规范推荐的默认目录是针对源代码的开发人员,而FHS推荐的默认目录是对发布者而言的。注意,如果你的库调用了一些程序,并且这些程序只能被库调用,那么你应该把这些程序放在/usr/local/libexec目录下(对于发布时的/usr/libexec目录)。
在GNU基于glibc的系统中,包含所有的Linux操作系统,启动ELF二进制可执行文件都会导致程序加载器被自动加载并执行。在Linux下,加载器是/lib/ld-linux.so.X(X是版本好)。它会依次找到并加载所有其他应用程序用到的共享链接库。
所以的搜索目录在文件/ect/ld.so.conf中指定。很多RedHat衍生的Linux发行版在该文件中并不包含目录/usr/local/lib。
如果你只是想覆盖库中的一些方法,但是保持库的其他部分不变,你可以在文件/etc/ld.so.preload中输入该库的名字。这个方法典型用于紧急的patch。发行版在发布时通常不会包含这样的文件。
在程序启动时搜索所有的目录会很低效,所以缓存会被用到。ldconfig默认会读取文件/etc/ld.so.conf,建立合适的符号链接到动态链接目录,接着会写缓存到文件/etc/ld.so.cache,然后这些动态链接库就可以被其他程序调用了。这大大加速了访问链接库的时间。
- Linux下共享链接库 (1)
- Linux下共享链接库 (2)
- Linux下共享库
- linux下共享库
- 【Linux笔记】linux系统下链接可执行文件时,linker如何查找共享库
- Linux环境下共享库(动态链接库)的简要介绍(如何创建共享库)
- Linux共享链接库错误的解决
- linux共享链接库初学--JNI编程
- Linux下共享库的隐式和显式链接
- Linux下的动态共享链接库的分析与使用
- linux下添加共享库
- Linux下静态链接库
- Linux下动态链接库
- centos 下编译和调用共享链接库
- ubuntu下的动态链接共享库路径配置
- 共享库链接详解
- 共享库链接详解
- 链接和共享库
- qwr werwer werfwe
- udhcp源码详解(二)
- 让Team Exploer 自动登录TFS
- 如何在Turbo C中输入中文?
- StringExample.java
- Linux下共享链接库 (1)
- 如何在linux内核中读写文件
- 程序员最好懂行业,懂了行业就不一样了
- vi使用技巧
- int main(int argc,char* argv[])详解
- 驳"少壮不努力,老大搞IT"
- 将excel数据导入SqlServer数据库
- SMBIOS介绍(1):概述
- 80386 寄存器