我学习了“ 程序库指南 ”。它提到soname像下面这样用来管理版本。
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,
而且我发现它也可以在没有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命令检查共享库时,该选项可以告诉您共享库的版本。
readelf -d libfoo.so
它还能做什么?
soname用于指示您的库支持哪些二进制api兼容性。
SONAME链接器在编译时使用它从库文件中确定实际的目标库版本。gcc -l NAME将寻找lib NAME.so链接或文件,然后捕获其SONAME,它肯定会更加具体(例如libnuke.so链接到包含SONAME libnuke.so.0的libnuke.so.0.1.4)。
SONAME
NAME
在运行时它将与之链接,然后将其设置为ELF动态节NEEDED,然后应存在具有该名称的库(或指向它的链接)。在运行时将SONAME被忽略,因此仅链接或文件存在就足够了。
NEEDED
备注:SONAME仅在链接/构建时强制执行,而不在运行时强制执行。
库的“ SONAME”可以与“ objdump -p文件| grep SONAME”一起看到。二进制文件“ NEEDED”可以在“ objdump -p文件| grep NEEDED”中看到。
[编辑]警告以下是一般性说明,而不是Linux中部署的说明。参见最后。
假设您有一个名称为libnuke.so.1.2的库,并开发了一个新的libnuke库:
[编辑]完成:Linux情况。
在Linux现实生活中,SONAME是一种特定形式:lib [NAME] [API-VERSION] .so。[major-version] major- version仅是一个整数值,该值在每次主要库更改时都会增加。API-VERSION默认为空
前libnuke.so.0
然后,实际文件名包括次要版本和子版本,例如:libnuke.so.0.1.5
我认为不提供soname是一种不好的做法,因为重命名文件会改变其行为。