LINUX动态库文件 soname realname linkname 详解

简介: 先明白动态库文件的3个名字 soname  :通过gcc/g++ -soname,libtest2.so.1 设置他是程序中连接文件的时候找的文件,本身为一个连接,他包含大版本,如果任何小版本的变化,直接替换到           realname,然后ln -s 建立同样的soname 到新的realname文件即可,不需要重新编译程序。
先明白动态库文件的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

相关文章
|
4天前
|
Linux Shell 网络安全
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
本指南介绍如何利用 HTA 文件和 Metasploit 框架进行渗透测试。通过创建反向 shell、生成 HTA 文件、设置 HTTP 服务器和发送文件,最终实现对目标系统的控制。适用于教育目的,需合法授权。
29 9
Kali Linux系统Metasploit框架利用 HTA 文件进行渗透测试实验
|
1月前
|
Linux 开发工具 Perl
在Linux中,有一个文件,如何删除包含“www“字样的字符?
在Linux中,如果你想删除一个文件中包含特定字样(如“www”)的所有字符或行,你可以使用多种文本处理工具来实现。以下是一些常见的方法:
41 5
|
1月前
|
安全 Linux 数据安全/隐私保护
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。本文介绍了使用 `ls -l` 和 `stat` 命令查找文件所有者的基本方法,以及通过文件路径、通配符和结合其他命令的高级技巧。还提供了实际案例分析和注意事项,帮助读者更好地掌握这一操作。
48 6
|
1月前
|
Linux
在 Linux 系统中,`find` 命令是一个强大的文件查找工具
在 Linux 系统中,`find` 命令是一个强大的文件查找工具。本文详细介绍了 `find` 命令的基本语法、常用选项和具体应用示例,帮助用户快速掌握如何根据文件名、类型、大小、修改时间等条件查找文件,并展示了如何结合逻辑运算符、正则表达式和排除特定目录等高级用法。
78 6
|
1月前
|
监控 Linux Perl
Linux 命令小技巧:显示文件指定行的内容
在 Linux 系统中,处理文本文件是一项常见任务。本文介绍了如何使用 head、tail、sed 和 awk 等命令快速显示文件中的指定行内容,帮助你高效处理文本文件。通过实际应用场景和案例分析,展示了这些命令在代码审查、日志分析和文本处理中的具体用途。同时,还提供了注意事项和技巧,帮助你更好地掌握这些命令。
61 4
|
1月前
|
网络协议 Linux
linux系统重要文件目录
本文介绍了Linux系统中的重要目录及其历史背景,包括根目录、/usr、/etc、/var/log和/proc等目录的结构和功能。其中,/etc目录下包含了许多关键配置文件,如网卡配置、DNS解析、主机名设置等。文章还详细解释了各目录和文件的作用,帮助读者更好地理解和管理Linux系统。
56 2
|
1月前
|
缓存 监控 Linux
|
1月前
|
Linux Shell 数据库
文件查找是Linux用户日常工作的重要技能介绍了几种不常见的文件查找方法
文件查找是Linux用户日常工作的重要技能。本文介绍了几种不常见的文件查找方法,包括使用`find`和`column`组合、`locate`和`mlocate`快速查找、编写Shell脚本、使用现代工具`fd`、结合`grep`搜索文件内容,以及图形界面工具如`Gnome Search Tool`和`Albert`。这些方法能显著提升文件查找的效率和准确性。
50 2
|
1月前
|
Linux 数据库
linux 全局搜索文件
在 Linux 系统中,全局搜索文件常用 `find`、`locate` 和 `grep` 命令。`find` 根据文件名、类型、大小、时间戳等条件搜索;`locate` 通过预构建的数据库快速查找文件;`grep` 在文件中搜索特定文本,常与 `find` 结合使用。选择合适的命令取决于具体需求。
111 2
|
2月前
|
运维 安全 Linux
Linux文件清空的五种方法总结分享
每种方法各有优势,选择最合适的一种或几种,可以极大提高您的工作效率。更多有关Linux系统管理的技巧与资源,欢迎访问,持续提升您的运维技能。
81 1