共享库

从文件结构上讲,共享库和共享对象没什么区别,Linux下共享库就是普通的ELF共享对象。由于共享对象可以被各个程序之间共享,所以它也就成为了库的很好的存在形式,很多库的开发者都以共享对象的形式让程序来使用。

共享库的版本

共享库的兼容

我们知道,共享库是在不断更新的。但是这种更新也会导致接口的更改和删除。这个时候,就可能导致依赖共享库的程序无法正常运行。

一般来说,共享库的更新是有两种的:

兼容更新。所有的更新只是在原有的共享库基础上添加一些内容。

不兼容更新。更新会改变原有的接口。

注意!我在这里写到的接口是指ABI而不是API。

导致ABI改变的行为

一般改变C语言的ABI有四种主要的行为:

导出函数的行为发生改变。也就是说调用这个函数以后产生的结果和以前的不一样,对函数的执行逻辑进行了改变

导出函数被删除。

导出数据的结构发生变化,比如共享库定义的结构体变量的结构发生改变,即对导出函数的返回值,参数列表的删除或者名称的修改。

导出函数的接口发生变化。如函数返回值、参数被更改。

当然还有其他行为:

比如说不通版本的编译器、操作系统和硬件平台等。

如何保持ABI兼容

对于C++,ABI问题会更加的严重,因为有虚函数表,模板实例化,多重继承等问题。

但是,一般来说,按照以下的规则编写C++共享库基本就可以保持ABI兼容。

不要在接口中使用虚函数,万不得已要使用虚函数时,不要随意删除、添加或在子类中添加新的实现函数。

不要改变类中任何成员变量的位置和类型。

不要删除非内嵌的public或protected成员函数。

不要将非内嵌的成员函数改成内嵌成员函数。

不要改变成员函数的访问权限。

不要在接口中使用模板

不要改变接口的任何部分干脆不要使用C++作为共享库接口。

共享库版本命名

Linux规定共享库的文件名规则必须如下:

libname.so.x.y.z

后面跟的三个数字组成了版本号。

“x”表示主版本号。

主版本号表示库的重大升级,不同主版本号的库之间是不兼容的。

“y”表示次版本号。

次版本号表示库的增量升级,即增加了一些新的符号接口,且保持原来的符号不变。在主版本号相同的情况下,高的次版本号向后兼容低的次版本号的库。

“z”表示发布版本号。

发布版本号表示库的一些错误的修正、性能的改进等,并不添加任何新的接口,也不对某个接口进行更改。相同主版本号、次版本号的共享库,不同发布版本号之间完全兼容。

程序如何获取依赖共享库信息

我们假定程序中有一个它所依赖的共享库列表,其中每一项对于于它所依赖的一个共享库。

SO-NAME

对于Linux来说,普遍会采用一个叫SO-NAME的命名机制来记录共享库的依赖关系。每个共享库都有一个对应的SO-NAME。

SO-NAME即共享库的文件名只保留主版本号。

如 libfoo.so.2.1.6 的SO-NAME就是 libfoo.so.2

显然,我们可以得出SO-NAME相同的两个共享库,次版本号大的兼容次版本号小的。

SO-NAME的优势

SO-NAME其实是一个软链接。实际上这个软链接会指向目录中主版本号相同、次版本号和发布版本号最新的共享库。

所以它的优势在于:

不用更改程序,直接更改软链接。

总之,SO-NAME表示一个库的接口,接口不想后兼容,SO-NAME就会发生变化。

链接名

当我们在编译器使用共享库的时候,我们会使用更简洁的方式。

比如需要链接一个libXXX.so.2.6.1,就只需要在shell脚本中输入-lXXX就行

共享库的系统路径

FHS规定,一个系统中主要有两个存放共享库的位置:

/lib ,这个位置主要存放系统最关键和基础的共享库

/usr/lib 这个目录下主要保存的是一些非系统运行时所需要的关键性的共享库

/usr/local/lib,这个目录用来存放一些跟操作系统本身并不十分相关的库。

FHS,一个大多数开源操作系统都遵循的标准

共享库的查找过程

在linux中,动态链接的ELF可执行文件在启动时会同时启动动态链接器/lib/ld-linux.so.X,程序所依赖的共享对象全部由动态链接器负责装载和初始化。

任何一个动态链接的模块所依赖的模块路径保存在dynamic段中,由DT_NEED类型的项表示。动态链接器对于模块的查找有一定的规则:

如果DT-NEED里面保存的是绝对路径,那么动态链接器就会按照这个路径去查找。如果是相对路径,那么动态链接器就会在/lib、/usr/lib和由/etc/ld.so.conf配置文件指定的目录中查找共享库。

但是!

每次都去找这个目录是否是太过笨逼?

所以Linux中引入了一个叫ldconfig的小程序,它会把共享库目录下的各个共享库创建、删除或更新相应的SO-NAME,这样每个共享库的SO-NAME就能够指向正确的文件共享库;并且这个程序还会将这些SO-NAME收集起来,集中存放到/etc/ld.so.cache文件,并建立一个SO-NAME的缓存。

参考文献

[1] 俞甲子 石凡 潘爱明.程序员的自我修养.电子工业出版社,2009.4.

linux 共享库目录,Linux共享库相关推荐

  1. 【Android NDK 开发】NDK 交叉编译 ( NDK 函数库目录 | Linux 交叉编译环境搭建 | 指定头文件目录 | 指定函数库目录 | 编译 Android 命令行可执行文件 )

    文章目录 I . NDK platforms 目录下的 函数库 II . Ubuntu 配置 NDK 交叉编译环境 III . 同时指定编译的头文件和库文件 IV . 指定编译的头文件 V . 指定编 ...

  2. linux smb配置目录,linux基础---smb配置

    一.samba简介 1.概述: 对于windows的网上邻居来讲,共享文件的方式用的是SMB和CIFS协议以及NETBIOS协议Linux/Unix之间用的是NFS协议.但是Linux和Windows ...

  3. linux挂载wondiws目录,linux cifs自动挂载windows硬盘或文件夹

    1.在要挂载的windows系统中找到需要挂载的硬盘或者文件夹,把它设置为共享 例如:在D盘下建立文件夹shared,设为共享 2.在linux系统/mnt目录下创建一个文件夹 #mkdir /mnt ...

  4. linux 源码 目录,Linux系统主要目录及kernel源代码目录

    1.在安装Linux后,先要了解清楚系统主要目录到底是干什么用的,避免以后再操作上的失误等.下面,就对Linux主要目录做一下简要说明:/boot:系统启动相关的文件,如内核.initrd,以及gru ...

  5. linux php 上级目录,Linux目录架构详解_php

    linux和Windows操作系统的显著区别之一就是目录架构的不同.Linux操作系统的目录架构遵循文件系统层级结构标准.不知你是否使用ls命令浏览过Linux的根目录"/",亲爱 ...

  6. linux 锁定用户目录,Linux vfpd锁定用户目录

    在linux ftp配置中,为了防止用户cd 到其他目录,需要锁定用户的根目录. Step1:修改配置文件 [root@ess ~]# vi /etc/vsftpd/vsftpd.conf #chro ...

  7. linux的lib目录,Linux 目录结构:/lib 分析

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 我们在之前的文章中已经分析了其他重要系统目录,比如 /bin./boot./dev. /etc 等.可以根据自己的兴趣进 ...

  8. linux 网卡配置目录,Linux目录结构以及网卡配置

    一.Linux下的目录结构 /bin 存放二进制命令 /boot系统引导程序 /dev设备,硬盘 /etc系统应用的配置文件 /home普通用户家目录 /lib库文件 /lib64 64位的库文件 / ...

  9. linux++tar打包目录,linux中tar命令打包目录与排除目录打包linux操作系统 -电脑资料...

    本文章来给各位朋友详细介绍关于linux中tar命令打包目录与排除目录打包有需要了解tar命令的使用方法的朋友可进行参考参考, 打包压缩目录很简单如下代码如下复制代码 tar -czf small.t ...

最新文章

  1. 居然是Firefox没有抛弃我们
  2. Qt for Android获取手机序列号/手机型号/手机制造商
  3. 结对开发四------求一维无头数组最大子数组的和
  4. 【原创】请不要对Boost Format使用Byte作为参数
  5. 十步让 WebForm项目 变为 Mvc项目
  6. [bzoj4568][Scoi2016]幸运数字
  7. button小手设置 css的cursor
  8. selenium动态网页爬虫复习
  9. linux 启动网络服务,Linux下网络启动服务器安装和配置方法(pxe+tftp+dhcpd)
  10. Docker系列(八)Docker的CS模式、守护进程的配置和操作
  11. Python: hashlib库、sha256、md5
  12. tf hub bigGan 猫变狗
  13. 软件测试的测试方法及测试流程
  14. nmap 扫描常见端口——命令
  15. jsp案例分析(二)-聊天室-2-逆向建模
  16. 计算机键盘使用大写用什么键,操作方法:如何解决Win10系统键盘的大小写切换键(大写锁定)的问题?...
  17. 金融知识图谱的现状与展望
  18. 框架里面的标签采集不到怎么办_怎么做微信生态的全数据采集和打通?
  19. steps_per_epoch=2000,epochs=100之间的区别
  20. 201771010101 白玛次仁 《2018面向对象程序设计(Java)》第九周学习总结

热门文章

  1. Linux redhat ICE环境安装
  2. 楷体任务用Ant来构建你的项目
  3. 个人自学ccna的资料+工大瑞普模拟器
  4. 我的log4net使用手册(转自 http://blog.csdn.net/lyjcn/archive/2009/08/11/4432833.aspx)
  5. VS2003使用后的一点心得
  6. 飞鸽传书:webbrowser 本生是一个控件
  7. 你当初是如何走上编程之路的?
  8. Python开发工程师常见的面试题及答案分享,记得收藏哈!
  9. 50条大牛C++编程开发学习建议
  10. php用什么电脑,我要学php了买一台什么配置的电脑最好?