linux+创建共享库的链接,Linux下的动态共享链接库的分析与使用

整理自网络

动态库的soname

动态共享库有一个重要的概念---soname。动态共享库在Linux系统上是以文件的形式存在的,这样,每个动态共享库也就有一个文件名, 假设把动态共享库的文件名定义为filename。那么必须牢记一件事性就是soname和filename不是一个概念的。在Linux下,每个动态共 享库都必须被赋予一个按特定的名称,Linux的文档将其称之为soname。soname通常包含共享库的名字和版本号,通过soname,系统或链接 器可以唯一地确定一个动态共享库。比如Linux的C函数库的soname是libc.so.6,这里,c是函数库的名字,6是该动态共享库的版本号。

然而,应用程序并不是直接和名字为soname的文件相链接的。比如,对于Linux C库而言,尽管通常在系统中能够找到名为libc.so.6的文件,但这个文件实际上却只是一个软连接也就是符号链接。这里清楚地显示出 libc.so.6是一个到libc-2.3.2.so的软连接。那么,这个软连接是由ldconfig建立的。ldconfig做的事情就是配置动态链接器的运行时绑定。对于一个编译好的动态链接库,如何知道它的soname是什么呢?可以使用readelf。readelf有一个选项-d,这个选项可 以打印出ELF文件中dynameic段的内容。在ELF中的dynamic段中就包含着动态共享库的soname。在Linux系统中存在着一个文件 /etc/ld.so.conf。这个文件中的每一行指定了ldconfig应当搜索的目录,在这些目录下面存放着系统运行中所需要的动态共享库文件, 以.so.x.x结尾的文件;ldconfig依次搜索这些目录,为找到的每个动态共享库文件建立一个到共soname的软链接。

动态共享库的构建和安装

在为动态共享库编译目标文件时,GCC编译器的下面这些选项是需要的:

-share:这个选项告诉GCC生成共享目标文件。生成的共享目标文件可以与其他目标文件链接在一起构成一个可自执行文件,此选项必须和-fPIC等选项联合使用。

-fPIC:这个选项告诉GCC生成位置无关代码(Position-Independent Code,PIC)在共享库中应当使用位置无关代码.

-Wl,-soname,xxx:这是一个特殊的GCC选项。通过该选项,GCC会把-soname,xxx作为一个命令行选项传递给链接器 ld,ld拿这个选项来做什么呢?在每个动态共享库的dynamic段都有一个soname项。-soname,xxx选项的作用就是告诉链接器ld,将 要链接产生的文件是一个动态共享库,它的soname是xxx.比如,如果编译版本号为6的Linux C库,就应当在生成libc-2.3.2.so时给GCC指定链接选项-Wl,-soname,libc.so.6.

构建动态共享库的最后一个步骤通常是下面的一个命令行:

gcc -share -Wl,soname,xxx -o libname filelist liblist

在这个命令行中,libname表示最终产生的动态共享库文件名。liblist是库要访问的库列表,比如libc-2.3.2.so.filelist是一组目标文件列表,它表 明了哪些编译好的目标文件将放到最终产生的动态共享库里面去。由于动态共享库可以依赖于其他共享库,因此这一项指定了最终产生的动态共享库将依赖的那些共享库的列表。filelist是想要放到库中的目标文件列表

例如:

gcc  -share  -Wl,soname,libfoo.so.1  -o  libfoo.so.1.0.1  foo.o  bar.o \

-lc

动态共享库在构建完成之后,如果需要安装到特定和系统目录下(如最常见的/usr/local/lib目录),只需要将动态共享库文件复制到相 应的目录下即可。然后运行ldconfig建立以soname命名的软连接,前提是共享库所在的目录包含在/etc/ld.so.conf文件中,此外 ,为了让链接器能够以标准的方式与动态共享库链接,还需要创建一个不带版本号的软连接。我们可以看到在Linxu系统下的lib目录下有很多的 的.so.XX 的文件,这就是系统中使用到的动态共享库

其中我们可以看到libc.so.6.这个是linux下的C函数库文件。我们可以看到这是一个符号链接,真正的文件是libc-2.10.2.so.

#lib$ ls -l libc.so.6

lrwxrwxrwx 1 root root 14 2009-12-09 20:59 libc.so.6 -> libc-2.10.1.so

#lib$ readelf -d libc-2.10.1.so

Dynamic section at offset 0x168b40 contains 26 entries:

Tag Type Name/Value

0x0000000000000001 (NEEDED) Shared library: [ld-linux-x86-64.so.2]

0x000000000000000e (SONAME) Library soname: [libc.so.6]

0x000000000000000c (INIT) 0x1e7b0

0x000000000000001a (FINI_ARRAY) 0x365740

0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)

0x0000000000000004 (HASH) 0x1620d8

0x000000006ffffef5 (GNU_HASH) 0x2b8

0x0000000000000005 (STRTAB) 0x10560

0x0000000000000006 (SYMTAB) 0x3c00

0x000000000000000a (STRSZ) 21963 (bytes)

0x000000000000000b (SYMENT) 24 (bytes)

0x0000000000000003 (PLTGOT) 0x368fe8

0x0000000000000002 (PLTRELSZ) 192 (bytes)

0x0000000000000014 (PLTREL) RELA

0x0000000000000017 (JMPREL) 0x1e5d8

0x0000000000000007 (RELA) 0x16e38

0x0000000000000008 (RELASZ) 30624 (bytes)

0x0000000000000009 (RELAENT) 24 (bytes)

0x000000006ffffffc (VERDEF) 0x16bf8

0x000000006ffffffd (VERDEFNUM) 15

0x000000000000001e (FLAGS) STATIC_TLS

0x000000006ffffffe (VERNEED) 0x16e08

0x000000006fffffff (VERNEEDNUM) 1

0x000000006ffffff0 (VERSYM) 0x15b2c

0x000000006ffffff9 (RELACOUNT) 1190

0x0000000000000000 (NULL) 0x0

下面以foo.c和bar.c 文件为例:如何构建动态共享库

#:~/program$ gcc -fPIC -g -c -o foo.o foo.c

#~/program$ gcc -fPIC -g -c -o bar.o bar.c

#:~/program$ gcc -shared -g -Wl,-soname,libfoobar.so.0 -o libfoobar.so.0.0 foo.o bar.o -lc

#:~/program$ sudo cp libfoobar.so.0.0 /usr/local/lib

#:~/program$ sudo ldconfig

#:~/program$ cd /usr/local/lib

#:/usr/local/lib$ ls

libfoobar.so.0 libfoobar.so.0.0 python2.6

#:/usr/local/lib$ ln -sf libfoobar.so.0 libfoobar.so

ln: creating symbolic link `libfoobar.so': Permission denied

#:/usr/local/lib$ sudo ln -sf libfoobar.so.0 libfoobar.so

#:/usr/local/lib$

#:~/program$ gcc -g -o foobar main.c -lfoobar

#:~/program$ ./foobar

This is foo!library2 is

foo()=foo

This is library1 is called

bar()=bar

ar这里的共享库的soname指定为libfoobar.so.0,最终生成的动态共享库文件为libfoob.so.0.0,foo.o和 bar.o是要放到libfoobar.so.0-.0中的目标文件列表,-lc则是libfoobar.so.0.0所依赖的共享库列表,这里只有一个 Linux C库被依赖。接着把libfoobar.so.0.0安装到/usr/local/lib目录上去,然后运行ldconfig,同时为了让链接器能够链接 上libfoobar.so.0.0,还要创建一个指向libfoorbar.so.0和符号连接。

这里简要的分析了一下Linux动态共享库的使用,为以后自己的使用做个记录。

另外,看看ldconfig命令需要注意的地方:

1. 往/lib和/usr/lib里面加东西,是不用修改/etc/ld.so.conf的,但是完了之后要调一下ldconfig,不然这个library会找不到

2. 想往上面两个目录以外加东西的时候,一定要修改/etc/ld.so.conf,然后再调用ldconfig,不然也会找不到

比如安装了一个mysql到/usr/local/mysql,mysql有一大堆library在/usr /local/mysql/lib下面,这时就需要在/etc/ld.so.conf下面加一行/usr/local/mysql/lib,保存过后 ldconfig一下,新的library才能在程序运行时被找到。

3. 如果想在这两个目录以外放lib,但是又不想在/etc/ld.so.conf中加东西(或者是没有权限加东西)。那也可以,就是export一个全局变 量LD_LIBRARY_PATH,然后运行程序的时候就会去这个目录中找library。一般来讲这只是一种临时的解决方案,在没有权限或临时需要的时 候使用。

4. ldconfig做的这些东西都与运行程序时有关,跟编译时一点关系都没有。编译的时候还是该加-L就得加,不要混淆了。

5. 总之,就是不管做了什么关于library的变动后,最好都ldconfig一下,不然会出现一些意想不到的结果。不会花太多的时间,但是会省很多的事。

./configure

make

make install

[root@localhost libusb-1.0.8]# ldconfig

[root@localhost libusb-1.0.8]# ldconfig -v | grep libusb

libusb-1.0.so.0 -> libusb-1.0.so.0.0.0

libusb-0.1.so.4 -> libusb-0.1.so.4.4.4

libusbpp-0.1.so.4 -> libusbpp-0.1.so.4.4.4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值