Linux操作系统中共享库(so)介绍

本文主要介绍Linux操作系统中共享库(shared object,即so)的相关知识。

本文主要从共享库的版本控制角度来讲述。

1 概述

本文会以curl共享库libcurl为例,来展开讲述。

首先在此说明,so有三个名称,分别如下:

  • realname: so的真实名称,如“libcurl.so.4.5.0”;
  • soname: so的软链接名称,如“libcurl.so.4”;
  • linkername: 编译过程中使用的so的名称,如curl。

2 realname

realname是so的真实名称,如编译安装curl软件后,生成的“/usr/local/lib/libcurl.so.4.5.0”。

realname在文件名中带有版本号信息,如“libcurl.so.4.5.0”的“4.5.0”。

3 soname

从版本控制的脚本来看,如果一个可执行程序直接连接到so的realname,那么当该so升级的时候,so的版本号发生了变化,那么就必须重新编译生成该可执行程序,这显然是不好的版本管理方式。为了解决此问题,出现了so的soname。soname实际上是realname的一个软链接,我们可以通过“readelf -d”命令查看so的soname,如下:

soname一般会保留so的大版本号,如“libcurl.so.4”。

在编译生成程序(可执行程序及共享库)时,我们通常都是连接的soname,这样当被依赖的so升级时,由于soname并没有变化,只需要将soname指向新的realname,即可实现被依赖的so的升级了,这样就实现了so的版本控制。

4 linkername

linkername是编译代码时的连接阶段使用的so的名字,实际上linkername也是指向realname的。

一般在程序编译时,我们会通过“-l”选项为其指定需要连接的so的名字(或是使用“CMakeLists.txt”时,为其指定的so的名字),样式类似:

-lcurl

或对应“CMakeLists.txt”中的“target_link_libraries(目标程序 ... curl ...)”,这里的curl就是so的linkername。

5 三个名称之间的关系

在编译生成程序时使用linkername进行连接的,而这个linkername实际上是指向realname的,但是在后续的使用过程中,程序其实是使用soname来找到被依赖的realname的,那么这三者是如何在编译、使用过程中连接起来的呢?

原来在编译生成realname时,已经为其指定了对应的soname(如前文所述,可通过“readelf -d”来查询),这样以soname作为桥梁,即可将so的三个名称联系起来。

结合程序的编译、生成、运行过程,描述so的三个名称关系如下:

  1. 程序编译时,用到了依赖库的so的linkername,即curl。由于linkername指向realname,所以程序实际上连接到了realname;
  2. 程序从realname处获取到运行时需要用到的soname,即libcurl.so.4;
  3. 编译生成程序;
  4. 程序运行时,调用soname,而soname实际上又指向了realname,所以程序实际上是调用的 realname。

上述几个步骤可以使用下图来表述:

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liitdar

赠人玫瑰,手有余香,君与吾共勉

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值