linux 动态库构造函数,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

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7728585/viewspace-2120139/,如需转载,请注明出处,否则将追究法律责任。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值