用于构建共享库的“soname”选项有什么用?

2024-03-27

我学到了“程序库指南 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(使用前将#替换为@)

用于构建共享库的“soname”选项有什么用? 的相关文章

  • 为什么我的 sed 命令在使用变量时失败?

    使用 bash 我尝试插入日期变量并搜索该日期的日志文件 然后将输出发送到文件 如果我像这样对日期进行硬编码 它会起作用 sed n Nov 22 2010 p file gt log file 但如果我这样做就会失败 date Nov 2
  • Eclipse CDT 内置包含目录

    Under Eclipse CDT gt Project Settings gt C C General gt Paths and Symbols gt Includes gt GNU C 有一个包含路径的列表 有些是粗体的并且是特定于项目
  • Docker 无法写入使用 -v 挂载的目录,除非它有 777 权限

    我正在使用docker solr https github com makuk66 docker solr使用 docker 生成图像 我需要在其中安装一个目录 这是我使用 v flag 问题是容器需要写入我已安装到其中的目录 但似乎没有权
  • 来自外部 .diff 文件的交互式补丁

    Linux 是否有命令或程序允许交互式地修补源代码 在屏幕上打印每个块并在将其应用到文件之前等待确认 就像是git add p 但是从另一个 diff 文件中进行更改 您始终可以在 shell ruby python 中编写脚本 逐行读取该
  • __get_cpuid 的可移植性如何?

    我在用着 get cpuid 获取有关的信息x86 and x86 64我的程序运行的处理器 在 Linux 和 Mac OS 上使用 GCC 似乎可以在不包含任何头文件的情况下编译和运行 但是它的可移植性如何 它可以与其他编译器一起使用吗
  • Linux命令:如何仅“查找”文本文件?

    经过几次谷歌搜索后 我得出的结论是 find my folder type f exec grep l needle text exec file grep text 这非常不方便 并且会输出不需要的文本 例如 mime 类型信息 还有更好
  • gcc 不会编译和运行 MySQL C 库

    include
  • 如何从 ext2/ext3 文件系统上的稀疏文件中删除一些块

    当您写入稀疏文件时 ext2 ext3 文件系统会自动分配块 但是当我不再需要其中的某些块时 我发现没有办法做到这一点 感觉就像使用 malloc 而不使用 free 是否可以 释放 稀疏文件的某些块 如果是的话 怎么样 不要告诉我将其复制
  • clrscr() 不工作,getch() 工作。为什么?

    我正在做一个小C请求密钥并执行 switch 语句中的某些代码的程序 include
  • 使用 i386 arch 而不是 x86_64 在 OSX 上构建 libFLAC

    我正在尝试构建 libFLAC 以在我的项目中使用 但是当涉及到链接时 GCC 会忽略该库 因为它说它不是为当前体系结构 i386 构建的 当我以 64 位编译程序时 它正确链接了库 这意味着该库是针对 x86 64 架构编译的 不幸的是
  • 缺少 /var/lib/mysql/mysql.sock 文件

    我正在尝试访问 mysql 当我运行 mysql 命令时 我得到以下信息 root ip 10 229 65 166 tpdatabase 1 8 0 28356 mysql 错误 2002 HY000 无法连接到 通过socket本地My
  • 如何使用AWK从文件中连续输出行

    我有一个多行文件 我想连续输出文件的某些行 比如第一次 从第1行打印到第5行 下次 打印第2行到第6行 依此类推 我发现 AWK 是一个非常有用的函数 我尝试自己编写代码 但它什么也没输出 以下是我的代码 bin bash for n in
  • 使用 gcc 在 C 中实现类型安全的可变参数

    很多时候 我希望函数接收可变数量的参数 例如以 NULL 结尾 define push stack t stack push VARARG NULL func push stack t stack char s va list args v
  • 如何向正在运行的 Linux 进程发送 Ctrl-Break?

    我正在调试在 Sun 的 JDK 1 4 2 18 上运行的应用程序中的内存泄漏 该版本似乎支持命令行参数 XX HeapDumpOnCtrlBreak 这可能会导致 JVM 在遇到控制中断时转储堆 如何将其发送到 Linux 机器上的后台
  • 专门逐行调试

    我有一个用 Pascal 编写的脚本 我会以这种方式调试它 在每一行停止 转储内存中所有变量的值 然后转到下一行 是否可以使用 gdb 或其他 Linux 开源工具来完成此操作 使用选项编译文件 g fpc gpc g file pas R
  • Shell 脚本对文件进行计数,然后删除最旧的文件

    我是 shell 脚本新手 所以我需要一些帮助 我有一个充满备份的目录 如果我有超过 10 个备份文件 我想删除最旧的文件 以便仅留下 10 个最新的备份文件 到目前为止 我知道如何计算文件数 这看起来很简单 但是如果计数超过 10 我该如
  • 从 TestContainer 访问 Podman REST API

    我使用 Maven 3 和 Podman 1 8 0 开发一个 Java 应用程序 据我了解 Podman 提供了与 Docker 兼容的 REST API Java集成测试使用TestContainer框架 TestContainer 无
  • 如何获取Linux中进程或端口的网络带宽使用情况

    我想获取每个进程的网络带宽使用情况 我找了很多这方面的资料 比如iftop nethogs http nethogs sourceforge net Linux进程浏览器 http sourceforge net projects proc
  • 系统调用:sys_exit()、SYS_exit 和 exit() 之间的区别

    SYS exit sys exit 和 exit 之间有什么区别 我的理解是 Linux内核提供了系统调用 这些调用在man 2 syscalls 这些系统调用的包装函数由glibc它们的名称与系统调用大多相似 我的问题 在man 2 sy
  • Linux 中如何确定哪个进程正在使用某个端口

    我目前正在其默认端口上运行 RethinkDB 因为如果我将浏览器指向localhost 8080我看到 RethinkDB Web 界面 我想关闭 RethinkDB 并使用以下命令在另一个端口上重新打开它 port offset争论 然

随机推荐