熟悉linux的都知道,linux的动态库如果有版本号的话,一般是libsample.so.x.y.z这样的名字。
x.y.z对应的就是major.minor.release(即主.次.发布)版本号
Major:大版本更新,前后都不兼容(比如移除api,又新增api)
Minor:小版本更新,一般来说是向前兼容的(即1.2.1是可以用在1.1.0的环境的)
Release:就是解决内部的问题,api没任何变化。
另外除开libsample.so.x.y.z这个文件,一般还会有两个文件
libsample.so -> libsample.so.x.y.z
libsample.so.x -> libsample.so.x.y.z
libsample.so.x.y.z
其实前两个文件都是软连接到第三个文件的。
首先来看编译连接时
简单来说:“是通过一个最容易的名字libsample.so,找到真实的文件libsample.so.x.y.z,然后取得它的运行时名字libsampe.so.x”
直接看图
编译连接过程
再来看运行加载时
简单来说“是通过运行时名字libsampe.so.x,找到链接文件ibsampe.so.x,从而定位真实文件libsample.so.x.y.z”
运行加载过程
兼容,怎么做到的?
假设运行系统目前已经有了下面三个文件:
libsample.so -->libsample.so.1.1.1
libsample.so.1 -->libsample.so.1.1.1
libsample.so.1.1.1
另外一个执行文件foo依赖ibsample.so.1 。
兼容升级:
当升级libsample.so.1.1.1为libsample.so.1.2.0时,只需要将连接重新指定
libsample.so.1 -->libsample.so.1.1.1 //修改为
libsample.so.1 -->libsample.so.1.2.0
不用重新编译foo
不兼容升级:
当升级libsample.so.1.1.1为libsample.so.2.0.0时,可以保持原来的状况不变
libsample.so.1 -->libsample.so.1.1.1
//添加新的文件
libsample.so.2 -->libsample.so.2.0.0
这样保证,
旧的foo 依赖libsample.so.1.1.1可以继续运行;
新的foo2依赖libsample.so.2.0.0也可以继续运行。
还有疑问的话,就在实际环境验证吧。