工作问题经验整理——带版本号so库文件含义和主程序链接so库机制
Posted yxtxiaotian
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了工作问题经验整理——带版本号so库文件含义和主程序链接so库机制相关的知识,希望对你有一定的参考价值。
一、(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库依赖关系可以看出:
- TestProj(A)依赖的是 libzlog.so.1.1文件,所以上面 将 A步骤产生的 libzlog.so.1.1(A) 文件 和 TestProj(A) 一起放到linux系统中运行,正常运行,因为在TestProj(A)运行时可以找到一起拷贝进来的名字为libzlog.so.1.1的库;
- 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、
以上是关于工作问题经验整理——带版本号so库文件含义和主程序链接so库机制的主要内容,如果未能解决你的问题,请参考以下文章