LINUX动态库文件 soname realname linkname 详解

先明白动态库文件的3个名字
soname  :通过gcc/g++ -soname,libtest2.so.1 设置他是程序中连接文件的时候找的文件,本身为一个连接,他包含大版本,如果任何小版本的变化,直接替换到
          realname,然后ln -s 建立同样的soname 到新的realname文件即可,不需要重新编译程序。
realname:是动态库文件的真实的名字及-o libtest2.so.1.1 生成的,sonanme 软连接指向它,虽然程序连接的时候找到的soname但是通过连接找到实际的
          realname,他包含大版本和小版本。
linkname:这个可有可无,但是如果要,他不包含版本信息,在g++的时候应该使用这个名字,避免版本改动重新编译makefile,如果哪天大版本也发生了变化
          使用linkname是版本无关的任然能够编译通过。我们只需要重新建立linkname的指向到新版本即可
比如:
libtest2.so.1.1 为realname
libtest2.so.1   为soname
libtest2.so     为linkname
编译或者使用makefile的时候应该尽量使用linkname,而不是使用realname

g++ main.cpp libtest2.so 

1、生成目标文件,二进制机器码未连接,使用-c,-g为可以调试
 g++ -fPIC -c -g t2.cpp {可以多个}   
 生成.o的机器码文件没有连接 -fPIC代码位置无关
2、生成动态库文件
 g++ -shared -Wl,-soname,libtest2.so.1 -o libtest2.so.1.1 t2.o {可以多个}
 生成soname为libtest2.so.1真实名字为libtest2.so.1.1的动态库文件文件名字为relname
 1.1为主版本和发行版
 readelf -d libtest2.so.1.1
 可以查看soname和relname
3、生成soname软连接
 /etc/ld.so.conf 加入一行 /home/gaopeng/CPLUSPLUS/part9
 执行ldconfig自动生成soname
 同时搜索库文件文件也会搜索/etc/ld.so.conf的新配置的目录下的soname
 
 或者指定目录生成soname
 ldconfig -n /home/gaopeng/CPLUSPLUS/part9
 生成连接连接实际上就是soname指向realname
 或者
 也可以使用ln -s 来建立soname
 ln -s /home/gaopeng/CPLUSPLUS/part9/libfu.so.1.1 /home/gaopeng/CPLUSPLUS/part9/libfu.so.1
 后两种方式需要修改
 LD_LIBRARY_PATH环境变量指向这个目录/home/gaopeng/CPLUSPLUS/part9/
 因为默认不会再自定义的目录下面早除非指定了
 /etc/ld.so.conf并且ldconfig生效了
4、
 g++ main.cpp libtest2.so.1.1 不推荐这种方式应该使用linkname见下面
5、
ldd a.out
查看程序需要的库文件,这里表示出来的是soname位置,而不是rename或者linkname
程序动态连接实际上如果有soname就会找到soname

建立linkname
如 lns -s  libtest2.so.1.1 libtest2.so
这里的libtest2.so 就是一个link name
那么我们编译的时候
就是
g++ main.cpp libtest2.so 代替掉第四步

用户的soname和realname文件及linkname文件全部放到 /usr/lib下,这种情况下只要有soname正确的指向了,就
不需要修改,当然也可以随意
这里使用soname放到/usr/lib下其他放到当前目录
当前realname文件在目录/home/gaopeng/CPLUSPLUS/part9/
生成soname,使用ln -s方法
sudo ln -s /home/gaopeng/CPLUSPLUS/part9/libfu.so.1.1 /usr/lib/libfu.so.1
sudo ln -s /home/gaopeng/CPLUSPLUS/part9/libfu2.so.1.10 /usr/lib/libfu2.so.1
生成linkname,使用ln -s
gaopeng@bogon:~/CPLUSPLUS/part9$ ln -s libfu.so.1.1 libfu.so
gaopeng@bogon:~/CPLUSPLUS/part9$ ln -s  libfu2.so.1.10 libfu2.so
gaopeng@bogon:~/CPLUSPLUS/part9$ g++ main.cpp libfu.so libfu2.so 
gaopeng@bogon:~/CPLUSPLUS/part9$ ldd a.out 
        linux-vdso.so.1 =>  (0x00007ffccb799000)
        libfu.so.1 => /usr/lib/libfu.so.1 (0x00007f1be882e000)
        libfu2.so.1 => /usr/lib/libfu2.so.1 (0x00007f1be862c000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f1be8328000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1be7f63000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1be7c5d000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f1be8a31000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f1be7a47000)

如果mv任何一个realname文件出错
gaopeng@bogon:~/CPLUSPLUS/part9$ mv libfu.so.1.1 libfu.so.1.1bak
gaopeng@bogon:~/CPLUSPLUS/part9$ ./a.out 
./a.out: error while loading shared libraries: libfu.so.1: cannot open shared object file: No such file or directory
gaopeng@bogon:~/CPLUSPLUS/part9$ ldd a.out 
        linux-vdso.so.1 =>  (0x00007ffcedde5000)
        libfu.so.1 => not found                   ---这里soname就找不到了
        libfu2.so.1 => /usr/lib/libfu2.so.1 (0x00007fd86e4f1000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fd86e1ed000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd86de28000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd86db22000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fd86e6f3000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fd86d90c000)
        
当然soname也可以放到任何目录,如我随意放了一个目录为
/home/gaopeng/CPLUSPLUS/part9/lib

realname文件在
/home/gaopeng/CPLUSPLUS/part9
那么显然在/usr/lib下找不到这个soname,那么我们需要做的就是
export LD_LIBRARY_PATH=/home/gaopeng/CPLUSPLUS/part9/lib
让g++程序能够找到这个soname,或者修改/etc/ld.so.conf并且ldconfig生效了

但是一般情况下linkname soname realname都在同一个目录下,这里只是想说明
程序执行的时候要找的只是soname的位置,而soname指向了realname
        
最后 
 g++ t2.cpp -fPIC -shared -o libtest2.so.1.10 不生成soname 的方式,不推荐这种方式,这种方式

readelf -d libmysqlclient.so.20.3.0  readelf可以查看soname及依赖库文件

Dynamic section at offset 0x39ead8 contains 29 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
 0x0000000000000001 (NEEDED)             Shared library: [librt.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
 0x000000000000000e (SONAME)             Library soname: [libmysqlclient.so.20]
 0x000000000000000c (INIT)               0x25d90
 0x000000000000000d (FINI)               0xb81e8
 0x000000006ffffef5 (GNU_HASH)           0x1b8
 0x0000000000000005 (STRTAB)             0x1eb0
 0x0000000000000006 (SYMTAB)             0x5a8
 0x000000000000000a (STRSZ)              3872 (bytes)
 0x000000000000000b (SYMENT)             24 (bytes)
 0x0000000000000003 (PLTGOT)             0x59f9f0
 0x0000000000000002 (PLTRELSZ)           3960 (bytes)
 0x0000000000000014 (PLTREL)             RELA
 0x0000000000000017 (JMPREL)             0x24e18
 0x0000000000000007 (RELA)               0x3128
 0x0000000000000008 (RELASZ)             138480 (bytes)
 0x0000000000000009 (RELAENT)            24 (bytes)
 0x000000006ffffffc (VERDEF)             0x2fe8
 0x000000006ffffffd (VERDEFNUM)          3
 0x000000006ffffffe (VERNEED)            0x3048
 0x000000006fffffff (VERNEEDNUM)         6
 0x000000006ffffff0 (VERSYM)             0x2dd0
 0x000000006ffffff9 (RELACOUNT)          5506
 0x0000000000000000 (NULL)               0x0

时间: 2024-09-30 12:38:36

LINUX动态库文件 soname realname linkname 详解的相关文章

Linux下的文件权限设置修改详解

我们已经知道文件权限对于系统的安全重要性了,也知道文件权限与用户与用户组的关系了,那么,如何修改文件的权限呢?我们可以修改多少文件权限呢?其实,一个文件的权限很多.我们先介绍几个简单的,例如:用户组.拥有者.各种身份的权限等等. • chgrp:改变文件所属用户组 . • chown:改变文件拥有者. • chmod:改变文件的属性.SUID等特性. 更改所属用户组, chgrp 改变文件的用户组很简单,直接用chgrp即可,这个命令就是change group(改变用户组)的缩写.这样就很好记

清理Linux系统垃圾文件操作方法图文步骤详解

在Linux系统中管理垃圾文件并没那么简单,虽然产生的Linux垃圾文件比较少,但随着对Linux系统的操作难免会产生各种软件安装包.软件残余.浏览器缓存文件和文档缓存文件等等,对这些垃圾文件进行清理可以缓解系统空间容量,有效提高系统运行速度,下面介绍下利用命令清理Linux垃圾文件操作教程. 一.clean 命令删除所有的软件安装包. 在网络连接正常的情况下,我们执行软件安装命令,软件安装结束后,以 .deb 为后缀的软件包就不再需要了.这种情况和 Windows 平台.手机的安卓平台上的情况

c++-linux动态库与静态库之间的调用问题

问题描述 linux动态库与静态库之间的调用问题 linux程序编译通过,运行时出错symbol lookup error: /usr/lib/libE.so: undefined symbol: test_D1 静态库libD.a中: 提供函数接口test_D(),test_D1(),test_D2() 动态库libE.so中:提供函数接口test_E() int test_E() { test_D(); return 0; } 应用程序make时,链接了动态库libE.so,将静态库libD

linux 动态库-linux动态库比静态小吗

问题描述 linux动态库比静态小吗 同一个库,为什么编译成动态链接库比编译成静态链接库要小? 另外,发布的时候肯定要把动态库与可执行文件一起发布的啊,这样动态编译要发布的文件(可执行文件加上动态库)还比静态编译要发布的文件(只发布可执行文件即可,库也包含在可执行文件里面了)小吗? 解决方案 动态库拆成了lib和so文件,有可能比静态库a文件要要小.发布的时候只要so文件就可以了.通过动态加载的方式 解决方案二: 大多数情况下,动态库比静态库小,但也不是绝对的.

分析Windows和Linux动态库_unix linux

    摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系统中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高效率,增加程序的可扩展性,便于模块化管理.但不同操作系统的动态库由于格式 不同,在需要不同操作系统调用时需要进行动态库程序移植.本文分析和比较了两种操作系统动态库技术,并给出了将Visual C++编制的动态库移植到Linux上的方法和经验. 1.引言 动态库(Dynamic Link Library abbr,DLL)技术是程序设计中经常采用

工具-linux 动态库中方法查看

问题描述 linux 动态库中方法查看 大神们,我想查看linux 动态库中方法的详细定义,问有啥方法或工具能否实现????? 解决方案 没有,基本上nm,objdump等只能看到函数名等.都被修饰了 解决方案二: 楼上正解.......................

makefile把一个 .cpp文件和它所依赖的几个 .a(静态库文件 ) 生成一个动态库文件.so

问题描述 makefile把一个 .cpp文件和它所依赖的几个 .a(静态库文件 ) 生成一个动态库文件.so 假设编译交叉编译工具路径为dir1(arm-linux-androideabi-gcc-4.9 ),存放生成的.so文件的路径为dir2,test.cpp,依赖1.a,2.a,3.a这三个静态文件库,Makefile文件应该怎么写 解决方案 arm-linux-androideabi-gcc-4.9 -fPIC -shared -o dir2/xxx.so test.cpp 1.a 2

动态库 静态库-linux动态库静态库问题,大牛请进

问题描述 linux动态库静态库问题,大牛请进 /////// static.h void static_print(); ///////static.cpp #include #include "static.h" void static_print() { std::cout<<"This is static_print function"< } ////// shared.h void shared_print(); ////// share

Linux 文件查找命令which 详解

某个文件不知道放在哪里了,通常可以使用下面的一些命令来查找: which  查看可执行文件的位置 whereis 查看文件的位置 locate   配合数据库查看文件位置 find   实际搜寻硬盘查询文件名称 附:Linux文件查找命令find详解   which 命令详解 which命令的作用是,在PATH变量指定的路径中,搜索某个系统命令的位置,并且返回第一个搜索结果.也就是说,使用which命令,就可以看到某个系统命令是否存在,以及执行的到底是哪一个位置的命令. 1.命令格式: whic