问题描述
我了解了 。它提到使用 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
我得到如果<$ code> 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
所以我认为唯一有用的一点是在使用 readelf -d libfoo.so
命令检查时, soname
选项可以告诉您共享库的版本它。
还能做什么? soname用于指示你的库支持的二进制api兼容性。编译时使用
SONAME 通过链接器从库文件中确定实际的目标库版本。 gcc -l NAME 会查找lib NAME
.so链接或文件,然后捕获它的SONAME,这肯定会更具体(前libnuke.so链接到libnuke.so.0.1.4包含SONAME libnuke.so.0)。
在运行时它会链接到这个然后设置进入ELF动态部分 NEEDED
,那么应该存在一个带有这个名字的库(或者它的一个链接)。
运行时 SONAME
被忽略,所以只有链接或文件存在就足够了。
备注:SONAME只在链接/构建时执行,而不是在运行时执行。
$ b 可以使用'objdump -p file | grep SONAME' 。
'需要'的二进制文件可以用'objdump -p file | grep NEEDED'来看。
警告以下是一般性说法,而不是一个在linux中部署。假设你有一个libnuke.so.1.2名称的库,并且你开发了一个新的libnuke库:
$ b
b $ b
- 如果您的新库是以前没有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 [ie仍与libnuke.so.1兼容]
完成:linux case。
在linux下真实生活中的SONAME作为特定的形式:
lib [NAME] [API-VERSION] .so。[主要版本]
主要版本只是每个主要库更改时增加的一个整数值。
API-VERSION默认为空
ex libnuke.so.0
然后真实文件名包括次要版本和颠覆例如:libnuke.so.0.1.5
我认为不提供soname是一种不好的做法,因为重命名文件会改变它的行为。 / p>
I learned the "Program Library HOWTO". It mention that using soname
to manage the version like follow.
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
And I get the information that if the soname
is not set. it will be equal to libfoo.so.1.0.0 ,see the answer from here.
And I find that it also can work without soname , like following
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
So I think that the only one useful point is that the soname
option can tell you the version of the shared library when you use readelf -d libfoo.so
command to check it.
What else can it do?
soname is used to indicate what binary api compatibility your library support.
SONAME
is used at compilation time by linker to determine from the library file what actual target library version. gcc -lNAME
will seek for libNAME
.so link or file then capture its SONAME that will certainly be more specific ( ex libnuke.so links to libnuke.so.0.1.4 that contains SONAME libnuke.so.0 ).
At run time it will link with this is then set into ELF dynamic section NEEDED
, then a library with this name ( or a link to it ) should exists.At Run time SONAME
is disregarded, so only the link or the file existence is enough.
Remark: SONAME is enforced only at link/build time and not at run time.
'SONAME' of library can be seen with 'objdump -p file |grep SONAME'.'NEEDED' of binaries can be seen with 'objdump -p file |grep NEEDED'.
[EDIT] WARNING Following is a general remark, not the one deployed in linux. See at the end.
Let's assume you have a library with libnuke.so.1.2 name and you develop a new libnuke library :
- if your new library is a fix from previous without api change, you should just keep same soname, increase the version of filename. ie file will be libnuke.so.1.2.1 but soname will still be libnuke.so.1.2.
- if you have a new library that only added new function but didn't break functionality and is still compatible with previous you would like to use same soname than previous plus a new suffix like .1. ie file and soname will be libnuke.so.1.2.1. Any program linked with libnuke.1.2 will still work with that one. New programs linked with libnuke.1.2.1 will only work with that one ( until new subversion come like libnuke.1.2.1.1 ).
- if your new library is not compatible with any libnuke : libnuke.so.2
- if your new library is compatible with bare old version : libnuke.so.1.3 [ ie still compatible with libnuke.so.1 ]
[EDIT] to complete : linux case.
In linux real life SONAME as a specific form :lib[NAME][API-VERSION].so.[major-version]major-version is only one integer value that increase at each major library change.API-VERSION is empty by default
ex libnuke.so.0
Then real filename include minor versions and subversions ex : libnuke.so.0.1.5
I think that not providing a soname is a bad practice since renaming of file will change its behavior.
这篇关于什么是建立共享库的'soname'选项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!