soname 用于指示您的库支持的二进制 api 兼容性。
SONAME
链接器在编译时使用它来从库文件中确定实际的目标库版本。gcc -lNAME
将寻找 lib NAME
.so 链接或文件,然后捕获其 SONAME,这肯定会更具体(例如 libnuke.so 链接到包含 SONAME libnuke.so.0 的 libnuke.so.0.1.4 )。
在运行时,它将与此链接,然后设置为 ELF 动态部分NEEDED
,然后应该存在具有此名称(或指向它的链接)的库。在运行时SONAME
被忽略,所以只有链接或文件存在就足够了。
备注:SONAME 仅在链接/构建时强制执行,而不是在运行时强制执行。
可以使用“objdump -p file |grep SONAME”查看库的“SONAME”。可以使用 'objdump -p file |grep NEEDED' 看到二进制文件的 'NEEDED'。
[编辑] 警告以下是一般性评论,而不是部署在 linux 中的评论。见最后。
假设您有一个名为 libnuke.so.1.2 的库,并且您开发了一个新的 libnuke 库:
- 如果您的新库是以前的修复程序而没有更改 api,您应该保持相同的 soname,增加文件名的版本。即文件将是libnuke.so.1.2.1,但soname 仍将是libnuke.so.1.2。
- 如果你有一个新库,它只添加了新功能但没有破坏功能并且仍然与以前兼容,你想使用与以前相同的 soname 加上一个新的后缀,如 .1。即文件和soname 将是libnuke.so.1.2.1。任何与 libnuke.1.2 链接的程序仍然可以使用该程序。与 libnuke.1.2.1 链接的新程序只能与那个程序一起使用(直到新的颠覆来像 libnuke.1.2.1.1 )。
- 如果您的新库与任何 libnuke 不兼容:libnuke.so.2
- 如果您的新库与裸旧版本兼容:libnuke.so.1.3 [即仍然与 libnuke.so.1 兼容]
[编辑]完成:linux案例。
在 linux 现实生活中 SONAME 作为一种特定形式: lib[NAME][API-VERSION].so.[major-version] major-version 只是一个整数值,每次主要库更改都会增加。API-VERSION 默认为空
前 libnuke.so.0
然后真正的文件名包括次要版本和子版本,例如:libnuke.so.0.1.5
我认为不提供 soname 是一种不好的做法,因为重命名文件会改变其行为。