动态共享库的构建和安装的步骤有哪些?
在为动态共享库编译目标文件时,GCC编译器的下面这些选项是需要的:
-share:这个选项告诉GCC生成共享目标文件。生成的共享目标文件可以与其他目标文件链接在一起构成一个可自执行文件,此选项必须和-fPIC等选项联合使用。
-fPIC:这个选项告诉GCC生成位置无关代码(Position-Independent Code,PIC)在共享库中应当使用位置无关代码。
-Wl,-soname,xxx:这是一个特殊的GCC选项。 通过该选项,GCC会把-soname,xxx作为一个命令行选项传递给链接器ld,ld拿这个选项来做什么呢?在每个动态共享库的dynamic段都有一个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表示最终产生的动态共享库文件名。
比如libc-2。3。2。so。filelist是一组目标文件列表,它表明了哪些编译好的目标文件将放到最终产生的动态共享库里面去。由于动态共享库可以依赖于其他共享库,因此这一项指定了最终产生的动态共享库将依赖的那些共享库的列表。
动态共享库在构建完成之后,如果需要安装到特定和系统目录下(如最常见的/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
这里的共享库的soname指定为libfoobar。
so。0,最终生成的动态共享库文件为libfoobar。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动态共享库的使用,为以后自己的使用做个记录。
编辑特别推荐:
揪出gcc默认使用的ld链接脚本
Linux操作系统单网卡双IP的设置
在Linux操作系统上玩转磁盘阵列。
收起