您的位置:68399皇家赌场 > 域名注册 > Linux怎么着缓慢解决动态库的版本调节

Linux怎么着缓慢解决动态库的版本调节

发布时间:2019-05-08 09:27编辑:域名注册浏览(138)

    前言

    以为到讲得挺详细 注: ln 命令用法 ln –s 源文件 指标文件 (目的文件即为软链接文件) 可用ls -l查看软链接文件具体指向哪些文件

     将库函数打包成一个单元使之力所能致在运转时被四个进程共享的手艺,这种技术能够节约磁盘空间和RAM。

    (换句话说,soname不是实际存在的文件,只是在此库花月前些天调用此库的文书中保留的四个名字,在加载时去找那一个名字,使用时创制3个软连接来指向真实文件,那样实在文件的版本号就能够提升了)

    今非昔比版本的动态库大概会不包容,如若程序在编写翻译时钦命动态库是某些低版本,运转是用的一个高版本,恐怕会招致力不从心运营。Linux上对动态库的命名选用libxxx.so.a.b.c的格式,其中a代表大版本号,b代表小版本号,c代表更加小的本子号,大家以Linux自带的cp程序为例,通过ldd查看其借助的动态库

    目录[-]

    一、 静态库:
    1.概念:
        静态库就是局地指标文件的聚焦,以.a结尾。静态库在程序链接的时候利用,链接器会将先后中行使到函数的代码从库文件中拷贝到应用程序中。一旦链接完毕,在实施顺序的时候就无需静态库了。 由于种种使用静态库的应用程序都要求拷贝所用函数的代码,所以静态链接的文书会非常大。
    2.创制与使用:
        首先创立库文件libhello.c
    1 #include <stdio.h>
    2 void hello()
    3 {
    4 printf("hello, welcome to library world!n");
    5 }
        创立头文件libhello.h
    1 void hello();
        今后咱们创建libhello静态库文件:
        $ gcc -c libhello -o libhello.o
        $ ar rcs libhello.a libhello.o  
        个中ar中的rcs的意味是:r注脚将模块到场到静态库中,c表示成立静态库,s表示生产索引。
        大家写二个测试程序:
        $ cat test.c
    1 #include <stdio.h>
    2 int main(void)
    3 {
    4 printf("use library hello.n");
    5 hello();
    6 return 0;
    7 }
        编写翻译与链接:
        $ gcc -c test.c -o test.o
        $ gcc test.o -L. -lhello -o test
        表明:-L.象征将当前目录参与到库搜索路线。暗中认可的库寻觅路线在/usr/lib目录下。
        其余这里说美赞臣(Dumex)下易混淆的参数-I, 它表示搜索头文件的路径。那样gcc在查找头文件的时候会首先到-I钦定的目录查找,然后才是系统暗许目录。
        -l参数: -lname表示库寻找目录下的libname.a 恐怕libname.so文件 ,那也是干吗库文件都以lib发轫的原故之一。多个常规嘛。当然了,假令你的库文件不是libhello,而是hello. 那就不能够用-l参数编译了。能够这样:
        gcc test.o -L. hello.a -o test    
        注意: $gcc -L. -lhello test.o -o test 会出错!。
        原因是: -l是链接器选项,必供给放置被编写翻译文件的前面。所以地点的下令中-lhello一定要放手test.o的前面。
        运行:
        $ ./test
        use library hello.
        hello, welcome to library world!

    Linux 系统,也一样面临和Window同样的难点,怎样调整动态库的四个本子难点。Window从前未有管理好,为此特地有个名词来描写那一个标题“Dll hell”,其严重影响软件的升官和爱惜。 Dll hell 是指windows 上动态库新本子覆盖旧版本,不过却不包容老版本。平常产生在程序进级之后,动态库更新,原有程序运维不起来;可能装新软件,不过已部分软件运营不起来。 一样Linux操作系统,也有同等的难题,那么它是怎么消除的啊?

     $ ldd /bin/cp            
    linux-vdso.so.1 => (0x00007ffff59df000)
    libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fb3357e0000)
    librt.so.1 => /lib64/librt.so.1 (0x00007fb3355d7000)
    libacl.so.1 => /lib64/libacl.so.1 (0x00007fb3353cf000)
    libattr.so.1 => /lib64/libattr.so.1 (0x00007fb3351ca000)
    libc.so.6 => /lib64/libc.so.6 (0x00007fb334e35000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007fb334c31000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fb335a0d000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fb334a14000)
    
    • 1. File libhello.c
    • 2. File libhello.h
    • 3. File main.c

    库是一组预先编写翻译好的函数集结,这一个函数须求依据可选择的规格编写制定,这个函数平日是有关系并执行同样项职分,举个例子荧屏处理函数库curses和nsurses库.
    正规种类库在/lib和/usr/lib中,编写翻译器会活动找到.除此而外的库在行使时需求钦定完全路线或用-L/路线和-l标志

    Linux 为化解那些主题材料,引进了1套机制,假若死守这几个机制来做,就能够幸免那些难点。 不过那只事三个预订,不是威胁的。不过提议听从那个约定,不然一律也会冒出 Linux 版的Dll hell 难点。 上面来介绍三个这么些机制。 那么些机制是由此文件名,来支配dll (shared library) 的版本。

    左边手是依赖的动态库名字,左侧是链接指向的文书,再查看libacl.so相关的动态库

    前言

    静态库和动态库:静态库和动态库是二种共享程序代码的办法,它们的界别是静态库在程序的链接阶段被复制到程序中,程序施行非亲非故;动态库在链接阶段未有被复制到程序中,而是程序在运维时由系统动态加载到内部存款和储蓄器中以供调用。使用动态库的独到之处是系统只需载入二次,分裂的程序可以赢得内部存款和储蓄器中一样的别本,由此节省了好些个内部存款和储蓄器。
    静态库:使gcc -c命令先生成.o文件,再用ar -r命令,将转换的.o文件成立成静态库.a文件
    例:ar crv libtest.a a.o b.o
    ar即archive,c是create表示创制,r是replacement,表示使用XX文件,v是呈现实践进度中的一些音讯

    Linux 上的Dll ,叫shared library,其有七个名字,分别有例外的目标。

     $ ll /lib64/libacl.so*           
    lrwxrwxrwx. 1 root root 15 1月 7 2015 /lib64/libacl.so.1 -> libacl.so.1.1.0
    -rwxr-xr-x. 1 root root 31280 12月 8 2011 /lib64/libacl.so.1.1.0
    

    针对同一动态组件的不如版本链接和加载。

    静态库.a文件类似windows中的.lib文件,.so文件类似.dll文件

    率先个是共享库本人的文书名(real name),其一般性包罗版本号,平常是是如此: libmath.so.一.1.123肆 。 lib是Linux 上的库的约定前缀,math 是共享库名字,so 是共享库的后缀名,1.1.123四的是共享库的本子号,其主版本号 小本子号 build号。主版本号,代表当前动态库的版本,假诺动态库的接口有调换,那么那个版本号将在加1;后边的五个版本号(小本子号 和 build 号)是告诉你详细的新闻,比方为3个hot-fix 而转换的2个版本,其小版本号加一,build号也应当变化。 那么些文件名包罗共享库的代码。

    大家开掘libacl.so.一实际上是1个软链接,它指向的文本是libacl.so.一.一.0,命名格局符合我们地点的描述。也有不按这种方法命名的,比方

    一、概念         
             DLL HELL字面意思是DLL"灾祸",是由于com组件(动态库)进级引起的次序不能够运作的气象。
            原因
             有二种或者的由来促成了DLL Hell的发出:
                    1是由使用旧版本的DLL替代原先3个新本子的DLL而引起的。那一个原因最布满,是Windows 九X用户平日碰着的DLL错误之一。
                    贰是由新版DLL中的函数无意发生退换而引起。固然在规划DLL时候理应向下包容,但是要保障DLL完全向下包容却是不可能的。
                    三是由新版DLL的装置引入三个新的Bug。

    将次第与静态库链接起来有二种办法
    cc -g -c prog.c
    cc -g -o prog prog.o libdemo.a  直接钦点静态库的称呼。-g选项是在编写翻译过的先后中隐含调节和测试消息
    或然:将静态库放在链接器搜索的中间叁个正式目录中(如/usr/lib),然后利用-l选项钦定库名(即库的文本名去除了lib前缀和.a后缀)
    cc -g -o prog prog.o -ldemo
    要是库不放在链接器搜索的目录中,那么能够只用-L选项钦命链接器应该找出那个额外的目录。
    cc -g -o prog prog.o -Lmylibdir -ldemo

    其次个是动态库的soname( Short for shared object name),其是应用程序加载dll 时候,其招来共享库用的文件名。其格式为

    $ ll /lib64/libc.so*            
    lrwxrwxrwx 1 root root 12 8月 12 14:18 /lib64/libc.so.6 -> libc-2.12.so
    

    二、linux下的减轻方案——命名标准       
           Linux 上的Dll ,叫sharedlibrary。Linux 系统面临和Window同样的主题材料,如何支配动态库的多少个本子难题。为缓慢解决那么些标题,Linux 为化解那个难题,引进了一套命名机制,假设死守这些机制来做,就能够幸免这一个标题。不过这只事三个预定,不是勒迫的。不过建议遵守那几个约定,不然1律也会出现Linux 版的Dll hell 难题。

    二、共享库:
    一、共享库的定义:
        共享库以.so结尾. (so == share object) 在先后的链接时候并不像静态库那样在拷贝使用函数的代码,而只是作些标识。然后在先后起首起步运行的时候,动态地加载所需模块。所以,应用程序在运维的时候依然须要共享库的扶助。 共享库链接出来的文本比静态库要小得多。
    2、共享库的命名
        一般多少个共享库的有多少个名字:soname, real-name, linker-name。下边先看实例:
        $ ls -l /usr/lib/libncurses*
        lrwxrwxrwx 1 root root     20 2008-05-25 13:54 libncurses.so -> /lib/libncurses.so.5
        lrwxrwxrwx 1 root root     13 2008-05-26 15:18 libncurses.so.5 -> libtermcap.so

    lib math .so ( major version number)

    无论怎么样命名,只要遵从规定的办法来变化和动用动态库,就不会有难点。而且大家1再是在机器A上编写翻译程序,在机器B上运转程序,编写翻译和平运动行的条件其实是有略微不一样的。上面就说说动态库在变化和接纳进度中的一些标题

    Real Name        
              首先是共享库自身的文本名:共享库的命名必须如 libname.so.x.y.z最前方使用前缀”lib”,中间是库的名字和后缀”.so”,最后多个数字是版本号。x是主版本号(Major Version Number),y是次版本号(Minor Version Number),z是发表版本号(Release Version Number)。

        上边包车型客车libncurses.so.5正是soname, 当中ncurses是库名,4分级是主版本号(major),当然也能够有次版本号(minor)和发行号(release)。(类似于ibncurses.so.伍.0.0)
        .so当然表示共享库了。平时soname只是real name的1个链接。
        而libtermcap.so 那是ncurse库的real-name, 相当于带有真是代码落成的文件.libncurses.so 则是linker name,用于应用程序链接的时候的1个找出名。它一般是soname的八个链接,格局为libname.so。
       实际上,每3个库都有一个soname,当连接器发掘它正在搜索的程序库中有如此二个称号,连接器便会将soname嵌入连结中的二进制文件内,而不是它正在运营的实际上文件名,在程序实施时期,程序会寻觅具有soname名字的文本,而不是库的公文名,换句话说,soname是库的界别标记。那样做的目标主若是允许系统中多少个本子的库文件共存,习惯上在命名库文件的时候一般与soname相同。
    3、共享库的装载
        (1) 在颇具基于GNU glibc的种类(当然包含Linux)中,在开发银行3个ELF贰进制实行顺序时,
        1个特殊的次第"程序装载器"会被机关装载并运维。在linux中,那几个顺序装载器就是
        /lib/ld-linux.so.X(X是版本号)。它会找出并装载应用程序所依据的具有共享库。
        被寻觅的目录保存在/etc/ls.so.conf文件中,但一般/usr/local/lib并不在找寻之列,至少debian/ubuntu是如此。那不啻是1个连串失误,只能本人加上了。当然,如若程序的每一次运维,都要去研究一番,势必功效不堪忍受。Linux系统已经怀想这点,对共享库选用了缓存管理。ldconfig就是落到实处这一职能的工具,其缺省读取/etc/ld.so.conf文件,对持有共享库依照一定标准创设符号连接,然后将音信写入/etc/ld.so.cache。
         /etc/ld.so.cache的存在大大加快了程序的运营速度。
        (二) 当然你也足以透过安装景况变量LD_LIBRARY_PATH来设置ld的装载路线。那样装载器就能首先寻觅该变量的目录,然后才是暗中同意目录。不过切记,LD_LIBRARY_PATH是用以开垦和测试的,你能够将一些用来测试的代表共享库的目录放到该变量中,类似于/etc/ld.so.preload的效果。可是该变量不应当用石钟山常用户的平常程序。
        (三) 假使您不行使LD_LIBRARY_PATH遭逢变量,能够通过如下格局给装载器传入路径:
            $ /lib/ld-linux.so.2 --library-path PATH EXECUTABLE
    四、共享库的创导与使用
        (一) 制造共享库:
        gcc -fpic/fPIC -c source.c -o source.o
        gcc -shared -Wl,-soname,your_soname -o library_name file_list library_list
        表达:  -fpic恐怕-fPIC注脚创设position independent code,这一般是创建共享库必须的。
               -Wl 声明给链接器传送参数,所以这里-soname, library_name 为给链接器的参数。
               -shared 声明是应用共享库
        上边是运用a.c和b.c创设共享库的演示:
           gcc -fPIC -g -c -Wall a.c
           gcc -fPIC -g -c -Wall b.c
           gcc -shared -Wl,-soname, libmyab.so.1 -o libmyab.so.1.0.1 a.o b.o -lc
        说明: lc == libc
        多少个供给留意的地点:
          a.不推荐使用strip管理共享库,最佳不要选取-fomit-frame-pointer编写翻译选项
          b.-fPIC和-fpic都得以发生指标独立代码,具体应用取决于平台,-fPIC是always work,
          就算其产生的对象文件大概会大些; -fpic产生的代码小,实践进程快,但大概有平台依赖限制。
          c.一般情状下,-沃尔,-soname,your_soname编写翻译选项是亟需的。当然,-share选项更无法丢。
        (2) 安装使用共享库
        一旦你创建好共享库后就须要设置使用了,最轻便易行的办法是将库拷贝到私下认可目录下(/usr/lib)。
        然后创制一些标志链接,最简易的章程或许利用ldconfig(八)来管理这里符号链接。最终是再度
        编写翻译链接你的顺序,通过-L和-l参数内定库路线就足以了。

    其只包括major version number,换句话说,也正是若是其接口未有变,应用程序都得以用,不管你其后minor build version or build version。

    动态库的编写翻译

    主版本号(不兼容):重大晋级,区别主版本的库之间的库是不相称的。所以若是要有限扶助向后异常就不能够去除旧的动态库的版本。

    gcc -g -fPIC -Wall mod1.c mod2.c mod3.c -shared -o libfoo.so

    标题来了,程序运营时怎么通过soname 找个real name? Soname 存在哪里?假如与real name 关联起来?哪天存的?

    笔者们以贰个轻松的次序当做例子

    次版本号(向下包容): 增量进级,扩充部分新的接口但保留原有接口。高次版本号的库向后相当低次版本号的库。

    综上可得,Linux动态库的暗中同意寻觅路线是/lib和/usr/lib。动态库被创制后,一般都复制到那八个目录中。当程序推行时索要某动态库,并且该动态库还未加载到内存中,则系统会自行到这多个默许搜索路线中去找出相应的动态库文件,然后加载该文件到内部存款和储蓄器中,那样程序就足以选取该动态库中的函数,以及该动态库的任何能源了。
    在Linux 中,动态库的探求路线不外乎暗许的检索路线外,还足以经过以下两种艺术来钦命。

    那就是接下去要介绍的第七个共享库的名字,link name,一孔之见,就是在编写翻译进程,link 阶段用的文件名。 其将sonmae 和real name 关联起来。

    // filename:hello.c
    #include <stdio.h>
    
    void hello(const char* name)
    {
     printf("hello %s!n", name);
    }
    
    // filename:hello.h
    void hello(const char* name);
    

    揭橥版本号(相互同盟):库的有个别诸如错误修改、品质创新等,不加多新接口,也不更换接口。主版本号和次版本号同样的前提下,不一样公布版本之间完全相配。

    方式一:在陈设文件/etc/ld.so.conf中内定动态库寻找路线。
    vi /etc/ld.so.conf
    添加 lib目录
    ldconfig
    主意2:通过情况变量LD_LIBRARY_PATH钦定动态库找出路线。
    export LD_LIBRARY_PATH=”$LD_LIBRARY_PATH:/opt/”
    方法三:在编译目的代码时钦赐该程序的动态库找出路线。
    还是可以在编写翻译指标代码时钦定程序的动态库寻找路线。通过gcc 的参数”-Wl,-rpath,”钦点

    其多少个名字,共享库的连日名(link name),是特地为build 阶段一连而用的名字。那个名字正是lib math .so ,例如libmath.so。其是不带其余版本音讯的。在共享库编译进程中,连接(link) 阶段,编写翻译器将生成三个共享库及real name,同时将共享库的soname,写在共享库文件里的公文头里面。能够用命令 readelf -d sharelibrary 去查看。

    接纳如下命令举办编写翻译

    SO-NAME       
             严俊根据上述规定,确实能防止动态库因为版本争持的主题素材,但是读者可能有疑问:在程序加载或运营的时候,动态链接器是哪些知道程序看重哪些库,怎么着抉择库的不如版本?
    Solaris和Linux等选择SO-NAME( Shortfor shared object name )的命名机制来记录共享库的重视性关系。每一个共享库都有3个一见好感的“SO-NAME”(共享库文件名去掉次版本号和发表版本号)。举个例子一个共享库名称叫libtest.so.三.八.二,那么它的SO-NAME就是libtest.so.三。

    linux 下有动态库和静态库,动态库以.so为扩大名,静态库以.a为扩大名。贰者都利用大规模。本文主要讲动态库方面知识。
    或然每2个linux 程序都至少会有1个动态库,查看某些程序选拔了这多少个动态库,使用ldd命令查看
    [root@localhost ~]# ldd /bin/ls
    linux-vdso.so.1 => (0x00007fffff600000)
    libselinux.so.1 => /lib64/libselinux.so.1 (0x00007faab7d50000)
    librt.so.1 => /lib64/librt.so.1 (0x00007faab7b48000)
    libcap.so.2 => /lib64/libcap.so.2 (0x00007faab7940000)
    libacl.so.1 => /lib64/libacl.so.1 (0x00007faab7738000)
    libc.so.6 => /lib64/libc.so.6 (0x00007faab73a0000)
    libdl.so.2 => /lib64/libdl.so.2 (0x00007faab7198000)
    /lib64/ld-linux-x86-64.so.2 (0x00007faab7f78000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x00007faab6f78000)
    libattr.so.1 => /lib64/libattr.so.1 (0x00007faab6d70000)
    [root@localhost ~]# strace /bin/ls
    open("/etc/ld.so.cache", O_RDONLY) = 3
    open("/lib64/libselinux.so.1", O_RDONLY) = 3
    open("/lib64/librt.so.1", O_RDONLY) = 3
    open("/lib64/libcap.so.2", O_RDONLY) = 3
    open("/lib64/libacl.so.1", O_RDONLY) = 3
    open("/lib64/libc.so.6", O_RDONLY) = 3
    open("/lib64/libdl.so.2", O_RDONLY) = 3
    open("/lib64/libpthread.so.0", O_RDONLY) = 3
    open("/lib64/libattr.so.1", O_RDONLY) = 3

    在应用程序引用共享库时,其会用到共享库的link name。在应用程序的link阶段,www.linuxidc.com其经过link名字找到动态库,并且把共享库的soname 提抽取来,写在团结的共享库的头文件之中。当应用程序加载时就能通过soname 去加以的路子下寻觅该共享库。

    gcc hello.c -fPIC -shared -Wl,-soname,libhello.so.0 -o libhello.so.0.0.1
    

    在Linux系统中,系统会为种种共享库所在的目录创制二个跟SO-NAME一样的还要指向它的软连接(Symbol Link)。那些软连接会指向目录中主版本号一样、次版本号和宣布版本号最新的共享库。也便是说,比如目录中有多个共享库版本分别为:/lib/libtest.so.三.八.2和/lib/libtest.so.叁.七.五,么软连接/lib/libtest.so.叁指向/lib/libtest.so.三.捌.2。

    [root@localhost ~]# ldd /bin/echo
    linux-vdso.so.1 => (0x00007fff71a00000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f207c5b8000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f207c958000)
    [root@localhost ~]# strace /bin/echo
    open("/etc/ld.so.cache", O_RDONLY) = 3
    open("/lib64/libc.so.6", O_RDONLY) = 3
    open("/usr/lib/locale/locale-archive", O_RDONLY) = 3

    下边通过这么些代码来证美赞臣(Meadjohnson)下系统是什么样做的,并且介绍系统的有些道具和工具:

    须求专注的参数是-Wl,soname(中间未有空格),-Wl选项报告编写翻译器将前面包车型客车参数字传送递给链接器,
    -soname则指定了动态库的soname(简单共享名,Short for shared object name)

    树立以SO-NAME为名字的软连接的指标是,使得全体正视某些共享库的模块,在编写翻译、链接和平运动转时,都应用共享库的SO-NAME,而无需选取详细版本号。在编写翻译生产ELF文件时候,纵然文件A注重于文件B,那么A的链接文件中的”.dynamic”段中会有DT_NEED类型的字段,字段的值正是B的SO-NAME。那样当动态链接器进行共享库重视文件查找时,就能够依附系统中各个共享库目录中的SO-NAME软连接自动定向到最新包容版本的共享库。

    那样多so,是的。使用ldd突显的so,并不是有所so都以亟需利用的,即使并未有运用,可是一样有链接进来,那看看程序运营时候有没有去加载它们啊,通过strace查看,有加载,所以必定会影响进度运维速度,所以我们最后不要把无用的so编写翻译进来,所以假设编写翻译进去,就能链接进来,启动时候便会加载,便会潜移默化进程运维速度

    代码:        

    今昔大家转移了libhello.so.0.0.一,当大家运转ldconfig -n .指令时,当前目录会多叁个软连接

    ★  readelf -d sharelibrary 能够查阅so-name
    ★  Linux提供了3个工具——ldconfig,当系统中设置或更新二个共享库时,供给周转这么些工具,它会遍历暗许全体共享库目录,举例/lib,/usr/lib等,然后更新具备的软链接,使她们指向最新共享库。

    linux从程序(program或对象)形成进度(process或进度),要由此什么样步骤呢,这里要是详细的说,测度要另开一篇作品。简单的说分三步:
    1、fork进度,在基本创立进程有关内核项,加载进程可推行文件;
    二、查找信赖的so,1One plus载映射虚拟地址
    3、初叶化程序变量。
    能够看看,第贰步中dll依赖更多,进度运行越慢,并且揭橥程序的时候,那一个链接但没有应用的so,一样要一齐跟着发表,不然进度运行时候,会停业,找不到对应的so。所以大家不能够像上面这样,把部分毫无意义的so链接进来,浪费能源。可是开采人士写makefile 一般有未有那么精心,图方便方便,那么有啥样好的格局啊。继续看下来,上边会给你化解方法。

    1. File libhello.c
      /* hello.c - demonstrate library use. */
      #include <stdio.h>
      void hello(void)
      { printf("Hello, library world./n");}
    2. File libhello.h
      /* libhello.h - demonstrate library use. */
      void hello(void);
    3. File main.c
      /* main.c -- demonstrate direct use of the "hello" routine */
      #include "hello.h"
      int main(void)
      {
      hello();
      return 0;
      }
      1.生成共享库,关联real name 和soname 。
     $ ll libhello.so.0            
    lrwxrwxrwx 1 handy handy 17 8月 17 14:18 libhello.so.0 -> libhello.so.0.0.1
    

    Link Name 
           当我们在编写翻译器里应用共享库的时候,如用GCC的“-l”参数链接共享库libtXXX.so.三.八.一,只要求在编译器命令行指定-l XXX 就可以,省略了前缀和版本信息。编译器会依据近日意况,在系统中的相关路径(往往由-L参数内定)查找最新版本的XXX库。那些XXX正是共享库的“链接名”。区别门类的库或然有同一的链接名,举个例子C语言运维库有静态版本(libc.a)也动态版本(libc.so.x.y.z)的区分,假若在链接时利用参数”-lc”,那么连接器就能够依赖输出文件的情景(动态/静态)来摘取相当版本的库。eg. ld使用“-static”参数时吗,”-lc”会查找libc.a;固然使用“-Bdynamic”(私下认可),会招来最新版本的libc.so.x.y.z。

    [root@localhost ~]# ldd -u /bin/ls
    Unused direct dependencies:

         gcc -g -Wall -fPIC -c hello.c -o hello.o

    其一软链接是何等变迁的吧,并不是截取libhello.so.0.0.1名字的日前部分,而是基于libhello.so.0.0.一编写翻译时钦赐的-soname生成的。也正是说我们在编写翻译动态库时通过-soname内定的名字,已经记载到了动态库的二进制数据之中。不管程序是不是按libxxx.so.a.b.c格式命名,但Linux上差不多具有动态库在编写翻译时都内定了-soname,大家能够通过readelf工具查看soname,比方小说开头列举的三个动态库

    更详细能够参见

    /lib64/libselinux.so.1
    /lib64/librt.so.1
    /lib64/libcap.so.2
    /lib64/libacl.so.1
    ldd -u demo 先查看
    g -Wl,--as-needed -o demo -lz -lm -lrt main.cpp 再另行编写翻译
    ldd demo 再查看
    ldd -u demo 再查看便未有未用的链接

         gcc -shared -W,soname,-libhello.so.0 -o libhello.so.0.0.0 hello.o

     $ readelf -d /lib64/libacl.so.1.1.0                     
    
    Dynamic section at offset 0x6de8 contains 24 entries:
    Tag Type    Name/Value
    0x0000000000000001 (NEEDED)  Shared library: [libattr.so.1]
    0x0000000000000001 (NEEDED)  Shared library: [libc.so.6]
    0x000000000000000e (SONAME)  Library soname: [libacl.so.1]
    

    g -o demo -lz -lm -lrt main.cpp 

         将会转移共享库libhello.so.0.0.0.

    此处大约了一部分,能够见见最终1行SONAME为libacl.so.一,所以/lib64才会有贰个如此的软连接

     

    [root@localhost df]# vi main.cpp
    [root@localhost df]# cat main.cpp
    #include <stdio.h>
    #include <iostream>
    #include <string>
    using namespace std;

         能够用系统提供的工具查看共享库的头:

    再看libc-二.1二.so文件,该文件并未选择大家说的命名情势

    代码:       

    int main()
    {
    cout << "test" << endl;
    return 0;
    }

          readelf -d libhello.so.0.0.0 | grep libhello

    本文由68399皇家赌场发布于域名注册,转载请注明出处:Linux怎么着缓慢解决动态库的版本调节

    关键词: 68399皇家赌场 Linux 开发

上一篇:Linux下Apache安装/扩展mod_rewrite模块的办法

下一篇:没有了