背景
当在看/lib下的一些文件时候,我们发现几乎都是三个动态库文件,为啥?
分析
当我发布一个动态库的时候,比如版本是maj.min.patch(10.2.1)的格式,当我改了小版本的号的时候(10.3.1),如果厂家A用的是我写的库,他需要做什么?
- maj大版本修改,厂家A需要修改他的CmakeList.txt, 因为之前是-libA.so.10.2.1, 现在需要改成-libA.so.10.3.1
- 打的小补丁,休休小bug, 按道理说厂家A不用重新编译
如何解决
- 为了厂家A不需要修改任何编译选项,所以最好有一个没有版本的名字,那就叫做A.so吧。那么我就整个A.so软链接到A.so.10.3.1就可以了。理论上这个就完事了,很简单.
- min版本,或者小补丁不需要A重新编译咋办? 我们知道实际在编译链接过程的时候,连接器会读取A.so.10.3.1的一个字段soname的值,并且把这个值拷贝到可执行文件中的soname字段里,所以当实际执行的时候,可执行文件会查找soname这个文件在不在,假如我们没有指定soname这个值,那么厂家A生成的可执行文件里的soname就是A.so.10.2.1, 所以执行的时候还是找这个名字,可想而知版本号一变化就会失败,因此需要一个通用的名字,那么就起名字为A.so.10,实际不管我在发布A.so.10.2.1还是A.so.10.3.1的时候,都指定soname为A.so.10, 那么厂家A在生成自己的可执行文件的时候就会把A.so.10拷贝到可执行文件里面,所以每次执行的时候都会找A.so.10这个文件在不在。
疑问
其实soname设置为A.so也是可以的,这样的话,如果我更新为11的大版本后,理论上厂家A还是可以运行可执行文件,但是我版本变动太大,A在实际生产中会报错,为了把风险控制在可执行文件启动前,所以可执行文件的soname最好有版本号,这样程序会启动失败,提醒你却是版本10的so