Sam*_*uel 48 linux gcc shared-libraries
我学会了" 程序库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
Run Code Online (Sandbox Code Playgroud)
我得到的信息是,如果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
Run Code Online (Sandbox Code Playgroud)
所以我认为唯一有用的一点是,soname
当您使用readelf -d libfoo.so
命令检查时,该选项可以告诉您共享库的版本.
它还能做什么?
phi*_*rdy 49
soname用于指示您的库支持的二进制api兼容性.
SONAME
链接器在编译时使用它来从库文件中确定实际的目标库版本.gcc -l NAME
将寻找lib NAME
.so链接或文件然后捕获它肯定会更具体的SONAME(ex 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库:
[编辑]完成:linux案例.
在linux现实生活中SONAME作为一种特定形式:lib [NAME] [API-VERSION] .so.[major-version] major-version只有一个整数值,在每个主要库变化时都会增加.默认情况下,API-VERSION为空
ex libnuke.so.0
然后真正的文件名包括次要版本和颠覆ex:libnuke.so.0.1.5
我认为不提供soname是一种不好的做法,因为重命名文件会改变它的行为.
您在命名传统 libname.{a}.{b}.{c} 时创建了一个名为 libx.1.0.0 的动态库
{a} stand for primary version, should changes when APIs changes(which making things incompatible).
{b} stand for sub version, should changes by adding APIs.
{c} stand for mirror version, should changes by bug fixing or optimizing
Run Code Online (Sandbox Code Playgroud)
现在您要发布 libx.1.2.0,并且您需要声明 libx.1.2.0 与 libx.1.0.0 兼容,因为只需添加函数并且人们的可执行文件不会崩溃,只需像过去一样链接它:
将 libx.1.0.0 和 libx.1.2.0 设置为具有相同的 soname,例如 libx.1
这就是 soname 所做的。
这是一个支持Johann Klasek's answer的例子。
简而言之,运行时需要 SONAME。在编译时,只需要链接器名称或真实名称(例如g++ main.cpp -L. -ladd
或g++ main.cpp -L. -l:libadd.so.1.1
)。链接器名称和真实名称的定义遵循Program Library HOWTO: 3. 共享库。
源树:
??? add.cpp
??? add.h
??? main.cpp
??? Makefile
Run Code Online (Sandbox Code Playgroud)
生成文件:
SOURCE_FILE=add.cpp
# main.cpp includes `add.h`, whose implementation is `add.cpp`
MAIN_FILE=main.cpp
SONAME=libadd.so.1
REAL_NAME=libadd.so.1.1
LINKER_NAME=libadd.so
OUTPUT_FILE=a.out
all:
g++ -shared -fPIC -Wl,-soname,${SONAME} -o ${REAL_NAME} ${SOURCE_FILE}
ln -s ${REAL_NAME} ${LINKER_NAME}
g++ main.cpp -I. -L. -ladd -o ${OUTPUT_FILE}
# Same as `ldconfig -n .`, creates a symbolic link
ln -s ${REAL_NAME} ${SONAME}
#./a.out: error while loading shared libraries: libadd.so.1: cannot open
# shared object file: No such file or directory
LD_LIBRARY_PATH=. ./${OUTPUT_FILE}
clean:
rm ${SONAME} ${REAL_NAME} ${LINKER_NAME} ${OUTPUT_FILE}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
35354 次 |
最近记录: |