共享库soname机制

soname · 浏览次数 : 15

小编点评

前言 在使用第三方库时,我们会发现它们通常会提供一组文件,如 libname.so、libname.so.x 和 libname.so.x.y.z。本文将讨论这些文件之间的关系。 1. 共享库版本号 共享库会因为修复 bug 或增加接口等原因不断更新。为了防止不向下兼容的情况,我们需要对共享库进行版本控制。可以根据更新内容的不同划分不同的版本号,包括主版本号、次版本号和发布版本号。 2. 共享库命名机制 共享库的命名规则如下: - 主版本号:xxx.soX.Y.Z - 次版本号:xxx.soX.Y - 发布版本号:xxx.soX 其中,xxx 是库名称,X、Y、Z 分别代表主版本号、次版本号和发布版本号。 3. soname 命名机制 soname(Symbolic Name)是一种用于管理共享库版本的命名机制。它采用 3 类命名方式: - realname:xxx.soX.Y.Z - soname:xxx.soX - linkname:xxx 在库文件生成时,可以使用 -Wl,-soname 参数指定 soname。在库安装或更新后,由库的维护者或系统管理员通过包管理器更新软链接的指向。 4. 总结 总之,soname 命名机制在 Linux 下的主要作用是参与两个过程: - 链接阶段:链接器根据 linkname 查找对应的.so 文件,并在生成的可执行文件中记录 so 文件指向的共享库文件的 soname。 - 加载阶段:程序运行时,动态链接器根据可执行文件中记录的 soname 查找对应的共享库文件。 通过这种方式,确保了应用程序在运行时能够找到合适的库版本,同时允许系统管理员在不影响已有应用程序的情况下更新库文件。

正文

前言

在使用第三方库时,我们会发现第三方库会提供一组文件,他们的后缀一般是.so(如libname.so),.so.x.so.x.y.z。本文讨论他们之间的关系。

共享库版本号

共享库一般会由于修复bug或增加接口等原因不断更新,有些更新是向下兼容的,有些则不是。一旦不向下兼容,那么当共享库更新后,依赖该库(旧版本)的程序将无法运行,需要重新编译。

为了避免上述情况,就要对共享库进行版本控制。根据更新内容的不同可以划分不同的版本号:

  • 主版本号(Major Version Number):主版本号表示库的重大升级,即更新的内容会导致不再与旧版本兼容(如接口变更),需要用户做出代码上的修改来适应新版本(或者仍使用旧版的共享库)。
  • 次版本号(Minor Version Number):次版本号表示库的增量升级,即更新的内容向下兼容,不会影响用户程序,但提供了额外的功能或改进。用户不需要做出代码更改仍可继续使用该库。
  • 发布版本号(Release Version Number):发布版本号表示库的一些错误的修正、性能的改进等,接口不做变化,不添加新功能。向下兼容。

不同的版本号在文件命名上就可以体现。
对于一个名为aaa的库,它的共享库文件名可能为:libaaa.so.x.y.z,其中:

  • lib:固定前缀
  • aaa:库名称
  • .so:共享库固定后缀
  • .x:主版本号
  • .y:次版本号
  • .z:发布版本号

例如libjsoncpp.so.1.7.4就代表着jsoncpp的共享库文件,版本号为1.7.4

共享库命名机制

然而若一个共享库改变了版本号并更新文件。那么对于使用旧版本共享库的用户程序来说,运行时就无法找到共享库文件了(因为名称已改变),还需要重新编译链接才可以。这就这大大增加了系统维护的复杂度和成本。

于是就诞生了soname命名机制,方便管理共享库的版本。

此机制设计了3类命名方式:

realname

  • 形如libname.so.x.y.zx,y,z分别代表主版本号,次版本号和发布版本号。
  • 一般拥有此名称的文件就是共享库的源文件
  • 在库文件生成时使用下面命令可以指定realname:
    gcc -shared -o $(realname) $(dependencies) $(flags)
    

soname

  • 形如libname.so.xx代表主版本号
  • 作用于用户程序运行时的加载阶段,动态链接器会根据用户程序编译时记录的soname查找对应的共享库文件
  • 通常是$(realname)文件的软链接,在库安装或更新后由库的维护者或系统管理员通过包管理器更新软链接的指向,一般不由单个用户手动进行软链接。
  • 在库文件生成时使用下面命令可以指定其soname
    gcc -shared -o $(realname) $(dependencies) $(flags) −Wl,−soname,$(soname)
    
  • 对于一个共享库文件,我们可以通过readelf -d命令查看其soname

linkname

  • 形如libname.so,是没有任何版本编号的文件名
  • 作用于用户程序编译阶段,链接器使用linkname来寻找对应的共享库(GCC中使用-l选项指定库,如-laaa,链接器就会去找libaaa.so),然后将共享库的soname记录在用户程序的动态链接信息中。
  • 通常是$(realname)文件或$(soname)文件的软链接,在库安装或更新后由库的维护者或系统管理员通过包管理器更新软链接的指向,一般不由单个用户手动进行软链接。

总结

总的来说,对于Linux下的用户程序,soname命名机制主要参与了以下两个过程:

链接阶段:链接器按照搜索路径优先级,根据linkname去找对应的.so文件,如果找到了就会在生成的可执行文件中记录.so文件指向的共享库文件的soname;如果没有找到就会去找静态库文件选择静态链接。

加载阶段:程序运行时,动态链接器按照搜索路径优先级,根据可执行文件中记录的soname去找对应的*.so.x文件,如果找到了就会加载其指向的共享库;没找到就报错。

这样的处理确保了应用程序在运行时能够找到合适的库版本,同时允许系统管理员在不影响已有应用程序的情况下更新库文件。

参考文章

1.Linux下动态链接库文件的realname、soname和linkname
2.Program Library HOWTO-Shared Libraries
3.Shared objects: sonames, real names, and link names
4.Linux 共享库的 soname 命名机制

与共享库soname机制相似的内容:

共享库soname机制

目录前言共享库版本号共享库命名机制realnamesonamelinkname总结参考文章 前言 在使用第三方库时,我们会发现第三方库会提供一组文件,他们的后缀一般是.so(如libname.so),.so.x和.so.x.y.z。本文讨论他们之间的关系。 共享库版本号 共享库一般会由于修复bug或

Linux动态库

制作动态库(也称为共享库)是将可重用的代码和函数打包成单独的库,可以在多个程序中共享使用。在Linux上制作动态库涉及以下步骤: 编写源代码: 编写你的代码,并确保它们可以编译为动态库。通常,你需要将代码拆分成多个文件,每个文件对应一个模块或功能。 编译源代码: 使用合适的编译器(如gcc)将源代码

[转帖]Linux中关于库

库 1.库文件2.库的分类3.静态库和共享库的区别 1.库文件 库是一组预先编译好的方法的集合. /lib 根目录下的库文件 /usr/lib Linux系统存储库的位置一般存放在/lib 和/usr/lib(64位系统/usr/lib64) 库的头文件放在/usr/include 2.库的分类 静

[转帖]Linux下的两个环境变量:LIBRARY_PATH和LD_LIBRARY_PATH使用

1.LIBRARY_PATH和LD_LIBRARY_PATH是Linux下的两个环境变量,二者的含义和作用分别如下: LIBRARY_PATH环境变量用于在程序编译期间查找动态链接库时指定查找共享库的路径,例如,指定gcc编译需要用到的动态链接库的目录。设置方法如下(其中,LIBDIR1和LIBDI

为什么要使用微服务架构?

一、传统的单体架构 1、什么是单体架构? 单体架构(Monolithic Architecture)是一种传统的软件架构模式,将整个应用程序作为一个单一的、统一的单元进行开发、部署和扩展。在单体架构中,所有的功能模块都被打包在一起,共享同一个代码库和数据库。 2、单体架构的缺点 复杂性高 一个大型的

DLR 的扩展库 Dynamitey

.NET 在 CLR 对动态语言或者脚本语言的支持是通过DLR 完成的, Miguel de Icaza对 DLR 的特点概括如下:一个针对动态语言的共享式类型系统; 一个共享的 AST,可以被语言开发人员用来创建新的动态语言; 针对编译器开发人员的辅助 / 工具类; 一个通用的宿主接口,从而可以将

Python并行运算——threading库详解(持续更新)

0. 写在前面:进程和线程 博文参考: Python的并行(持续更新)_python 并行-CSDN博客 《Python并行编程 中文版》 一些相关概念请见上一篇博文。 1. 在Python中使用线程 1.1 多线程简介 线程是独立的处理流程,可以和系统的其他线程并行或并发地执行。 多线程可以共享数

[转帖]在 virt-manager 的主机和客户机之间共享文件夹

https://linux.cn/article-15470-1.html 在本指南中,你将学习如何在 virt-manager 的 KVM、QEMU 和 libvirt 的主机和客户机之间共享文件夹。 virt-manager 应用或软件包使用 libvirt 库来提供虚拟机管理服务。它有一个桌面

1.13 导出表劫持ShellCode加载

在`Windows`操作系统中,动态链接库`DLL`是一种可重用的代码库,它允许多个程序共享同一份代码,从而节省系统资源。在程序运行时,如果需要使用某个库中的函数或变量,就会通过链接库来实现。而在`Windows`系统中,两个最基础的链接库就是`Ntdll.dll`和`Kernel32.dll`。Ntdll.dll是Windows系统内核提供的一个非常重要的动态链接库,包含了大量的系统核心函数,如

[转帖]ldconfig命令使用说明

https://www.cnblogs.com/apink/p/16930163.html ldconfig是一个动态链接库管理命令,命令的用途,主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式如前介绍,