linux 动态库版本库管理及静态库

 一、库命名

        我们在linux下使用一些库时,会发现其后面带有一些数字,例如:libc.so.1 。形如lib*.so.x.y.z是有一套命名规则(*表示你给so的名字),x表示major version ,y表示minor version  z表示release version ,引入这套规则的目的是保证程序的更新,兼容等,

       linux共有的so有三种名字:     (1)real name:其命名规则为lib*.so.x.y.z,在它的开头,包含有soname信息。程序运行时真正调用的so,也就是里面是真正含有代码的,

                                                       (2)soname(short for shared object name):其命名规则为lib*.so.x,应用程序在链接时,所找到的库,它的信息是写在real name,在链接时,从realname中读取出soname,写入应用程序中,应程序再通过soname找到real name

                                                        (3)link name:其命名规则为lib*.so就是我们在链接时,所使用的名字,比如 -lc ,这样,编译器就会去寻找libc.so.x.y.z ,如果有多个,编译器去寻找最新的。当然,用户也可以直接指定全名,比如,/**/**/**/lib*.so.1.1.2,这个linkname其实是一个虚拟的,如果存在realname soname,那这个linkname其实是不存在的。既然这样,linkname作用是什么,linkname使得用户不用去记住那些数字编号了,直接利用前面的名字就可以找到所使用的so。 

  *************上面这段红色是字是前端时间写的,开始以为名字为linkname的文件其实可以不用存在,后面发现似乎有错误,编译器其实是根据linkname去找到realname,然后提取出soname的。


二、关于动态库

        下面我们自己编译一些so来试试看:我使用cmake来管理工程,当然也可以直接使用gcc,为了方便理解。操作中两者我都会采用

    ######动态库的生成及使用

  (1) cmake版

project(test_version)
cmake_minimum_required(VERSION 2.6)
set(CMAKE_C_FLAGS "-fPIC")
set(CMAKE_BUILD_TYPE Release ON)
add_library(test_version  SHARED so.c)
SET_TARGET_PROPERTIES(test_version PROPERTIES VERSION 1.2.3 SOVERSION 1)
#realname版本号为1.2.3

我们可以看到生成的动态库情况如下:


大家可以通过readelf -d **.so.**查看相关情况


      下面来调用生成的动态库,这里我们调用的就是libtest_version.so

<span style="font-size: 14px;">project(test)
cmake_minimum_required(VERSION 2.6)
include_directories(/home/JunYao/workspace/test_so_version/test/)
ADD_EXECUTABLE(test test.c)
TARGET_LINK_LIBRARIES(test </span><span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-size:12px;">/home/guagua/workspace/useless/test_so_version/so_version/build/libtest_version.so</span></span><span style="font-size: 14px; font-family: Arial, Helvetica, sans-serif;">)</span>

最后生成test可执行文件,我们 ldd test 看一下,编译器将soname读入test,:


找不到动态库,为啥,因为,链接器和装载器并不共享动态库的路劲,解决这种问题有三类方法

     (i) 将相应的动态库拷贝到/lib  或 /usr/lib 目录下

      (ii)添加LD_LIBRARY  并指定相应动态库路径

       (iii)更新 /etc/ld.so.conf.d/ ***.conf  在里面添加相应的动态库路径


 (1) gcc版

  gcc -shared -Wl,-soname,libtest_version.so.0 -o libtest_version.so.0.0.0 so.o

-soname,libtest_version.so.0表示指定器soname的名字,不过这个so不会自动生成,可以利用ldconfig来生成,并且linkname也需要手动生成


**************************************************************************这块有点迷惑*********************************************************

利用gcc来编译测试程序:

 gcc test.c -L /home/guagua/workspace/useless/test_so_version/so_version/build/ -ltest_version -o test  链接的还是刚刚利用cmake生成的动态库,链接没有问题,但是有意思的事情发生了:

  

找不到动态库,为啥,因为,gcc链接器和装载器并不共享动态库的路劲,解决这种问题有三类方法

     (i) 将相应的动态库拷贝到/lib  或 /usr/lib 目录下

      (ii)添加LD_LIBRARY  并指定相应动态库路径

       (iii)更新 /etc/ld.so.conf.d/ ***.conf  在里面添加相应的动态库路径

那为何刚刚用cmake可以呢,在用cmake的时候,上面的三个方法我都没有使用。我们来看下生成的两个test有啥不同:

由上面可知,最起码,大小就不同,会不会是cmake编译出来的,已经包含了装载信息? 我把test和动态库放到另外一台电脑,开始不能运行,但是,当我建立/home/guagua/workspace/useless/test_so_version/so_version/build/ 并把相应动态库拷贝进去,就能运行,这个能说明cmake生成的可执行文件,动态库的加载路径也有写入?



二、关于静态库

利用cmake生成静态库时,就没啥版本号的概念了,就是只生成一个libtest_version.a



静态链接不成功,是因为现在都是使用glibc ,一些静态库默认不安装,所以静态编译链接libtest_version.a 是没问题,但是链接libc.a就出问题了









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值