工作问题经验整理(2)——带版本号so库文件含义和主程序链接so库机制

17 篇文章 0 订阅

一、(20190412)

1、问题描述

库的生成:项目工程 TestProj 中使用zlog开源日志库,使用两种方式编译生成so库:

  • A:使用源码中自带makefile进行编译,会产生 libzlog.a/libzlog.so/libzlog.so.1/libzlog.so.1.1(A) 四个文件;
  • B:通过zlog 中的源码文件,自己在 eclipse 中创建 生成so库 的项目工程 zlog,配置将要生成的so库的后缀为 so.1.1,配置位置无关属性,生成 libzlog.so.1.1(B) 日志库;

问题产生过程:

  • 将A步骤产生的 libzlog.so.1.1(A) 文件拷贝到 TestProj 项目工程中在lib目录下面之后,修改名字为 libzlog.so;链接工程生成 TestProj(A) 可执行程序;将 A步骤产生的 libzlog.so.1.1 文件 和 TestProj(A) 一起放到linux系统中运行,正常运行;
  • 将B步骤产生的 libzlog.so.1.1(B) 文件拷贝到 TestProj 项目工程中在lib目录下面之后,修改名字为 libzlog.so;链接工程生成 TestProj(B) 可执行程序;将 B步骤产生的 libzlog.so.1.1 文件 和 TestProj(B) 一起放到linux系统中运行,运行异常,提示找不到 libzlog.so 库文件;

相关说明:

  • 这里项目工程TestProj 中使用了 libzlog.so.1.1这种带数字版本后缀的库的原因,是因为一开始在项目工程中引入不带后缀的libzlog.so 库,TestProj运行的时候会报找不到 libzlog.so.1.1 库文件,所以后面工程直接使用了 libzlog.so.1.1 库;同时在自己编译的版本中也修改库后缀名称为 so.1.1,也是为了 兼容原来版本;
  • 将libzlog.so.1.1库文件拷贝到 项目工程TestProj 的lib目录之后需要修改库名字为 libzlog.so 这种不带后缀的原因,是因为 带后缀的库,项目工程在进行链接的时候会找不到库文件;

2、问题分析

相同项目工程TestProj ,工程目录下库名字也都改为libzlog.so,但是链接生成的TestProj(A)正常运行,TestProj(B)则运行异常;查看2个可执行程序TestProj(A) 和 TestProj(B) 的库依赖, 如下(结果作了部分敏感信息处理):

从上图可执行程序TestProj(A) 和 TestProj(B) 的zlog库依赖关系可以看出:

  1. TestProj(A)依赖的是 libzlog.so.1.1文件,所以上面 将 A步骤产生的 libzlog.so.1.1(A) 文件 和 TestProj(A) 一起放到linux系统中运行,正常运行,因为在TestProj(A)运行时可以找到一起拷贝进来的名字为libzlog.so.1.1的库;
  2. TestProj(B)依赖的是 libzlog.so文件,所以上面 将 B步骤产生的 libzlog.so.1.1(B) 文件 和 TestProj(B) 一起放到linux系统中运行,运行异常,会提示找不到 libzlog.so 库文件,因为一起拷贝进来的库的名字是libzlog.so.1.1 ;

那么问题来了,相同项目工程TestProj ,工程目录下库名字也都改为libzlog.so,为什么TestProj(A) 会链接到 libzlog.so.1.1,而TestProj(B) 会链接到  libzlog.so ??或者说,TestProj链接so动态库的内部机制是怎样(这个在后面章节讲解)??现在进一步思考,唯一的不同只有 libzlog 库的来源不同,TestProj(A) 中使用的libzlog.so是使用自带的makefile编译出来的libzlog.so.1.1(A),进一步修改名字得到;而TestProj(B) 中使用的libzlog.so是使用自己创建的zlog动态库工程编译出来的libzlog.so.1.1(B),进一步修改名字得到。

进一步,查看 libzlog.so.1.1(A) 和 libzlog.so.1.1(B) 库文件内部信息和依赖,如下:

从上图 libzlog.so.1.1(A) 和 libzlog.so.1.1(B) 库文件内部信息可以看出:

  • libzlog.so.1.1(A) 中有指定[SONAME]为Library soname: [libzlog.so.1.1];
  • 而 libzlog.so.1.1(B) 虽然库文件名称也是 so.1.1 后缀,但这个后缀是我们在创建zlog动态库工程的时候指定的编译生成动态库的后缀名称,实际并没有在库内部生成[SONAME]信息。

所以分析得到,虽然在相同项目工程TestProj ,工程目录下库名字也都改为libzlog.so,但是 来源不同的 "libzlog.so" ,其内部[SONAME]信息不同, 导致TestProj工程实际链接的依赖库名字不同,在TestProj 运行的时候,会根据链接时候的库名字也即[SONAME]信息,在linux系统指定的库目录(/lib)中查找对应名称的库文件。

3、解决方案

  •  如果使用了TestProj(A)程序,就把 libzlog.so.1.1(A) 一并拷贝进系统,正常运行;
  • 如果使用了TestProj(B)程序,就把 libzlog.so.1.1(B) 修改名字为 libzlog.so 不带后缀,正常运行。

4、进一步提出问题:链接so动态库的内部机制是怎样??

[SONAME]字段信息是什么?TestProj工程链接时是因为使用该信息作为链接库名字,且在TestProj工程实际运行的时候使用了该链接名称进行动态库so的查找么?应用程序逻辑so动态库的内部机制是怎样?so动态库带有的后缀数据版本信息 又代表什么意义?下面我们一一来解决这些问题。

 

二、应用程序链接so动态库的内部机制

1、

 

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值