soname用于指示您的库支持哪些二进制API兼容性。
SONAME
在编译时由链接器使用,从库文件中确定实际目标库版本。gcc -lNAME
将寻找libNAME
.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是一种不良做法,因为重命名文件将改变其行为。
libx.so
的文件,并使用SONAMElibx.so.1
编译和链接,直到您在Android上运行它时才会出错。因为Android始终期望文件名以.so
结尾,如果SONAME是带版本号的,则加载该库将失败。 如果这是一个开源库,您可以修改构建文件,否则rpl可能是您唯一的选择。 - vesperto