我学到了“程序库指南 http://tldp.org/HOWTO/Program-Library-HOWTO/”。它提到使用soname
像下面这样管理版本。
gcc -shared -fPIC -Wl,-soname,libfoo.so.1 -o libfoo.so.1.0.0 foo.c
ln -s libfoo.so.1.0.0 libfoo.so.1
ln -s libfoo.so.1 libfoo.so
我得到的信息是,如果soname
未设置。它将等于 libfoo.so.1.0.0 ,请参阅来自的答案here https://stackoverflow.com/questions/4071962/how-does-linker-find-shared-library-without-soname.
我发现它也可以在没有 soname 的情况下工作,如下所示
gcc -shared -fPIC -o libfoo.so.1.0.0 foo.c
ln -s libfoo.so.1.0.0 libfoo.so.1
ln -s libfoo.so.1 libfoo.so
所以我认为唯一有用的一点是soname
选项可以告诉你使用时共享库的版本readelf -d libfoo.so
命令来检查它。
它还能做什么?
soname 用于指示您的库支持的二进制 api 兼容性。
SONAME
链接器在编译时使用它来从库文件中确定实际的目标库版本。海湾合作委员会-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”查看“需要”的二进制文件。
[编辑] 警告以下是一般性评论,不是在 Linux 中部署的评论。见最后。
假设您有一个名为 libnuke.so.1.2 的库,并且您开发了一个新的 libnuke 库:
- 如果你的新库是对以前的库的修复,没有更改 api,你应该保留相同的 soname,增加文件名的版本。 ie 文件将为 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[名称][API 版本].so.[主要版本]
Major-version 只是一个整数值,每次主要库更改时该值都会增加。
API-VERSION 默认为空
前 libnuke.so.0
然后真实的文件名包括次要版本和子版本,例如:libnuke.so.0.1.5
我认为不提供 soname 是一种不好的做法,因为重命名文件会改变其行为。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)