选项笔记"/>
【GCC】参数选项笔记
-Wl,-soname
(原文:)
-Wl选项告诉编译器将后面的参数传递给链接器。
-soname则指定了动态库的soname(短名,Short for shared object name)
-Wl 表示后面的参数也就是-soname,libhello.so.1直接传给连接器ld进行处理。每一个库都有一个soname,当连接器发现程序库(如:libhello_v1.so)中有soname (libhello.so),连接器便会将soname (libhello.so)嵌入要连接的二进制文件内,而不是库文件的实际文件名(libhello_v1.so)。在程序执行期间,程序会查找拥有 soname名字(libhello.so)的文件,而不是库的文件名,换句话说,soname是库的区分标志。
这样做的目的主要是允许系统中多个版本的库文件共存(soname相同,库文件名不同,可以放在同一个文件夹),习惯上在命名库文件的时候通常与soname相同
libxxxx.so.major.minor
其中,xxxx是库的名字,major是主版本号,minor 是次版本号
简单的来说,真正指定了库的名字的是soname (libhello.so)而不是库文件名libhello_v1.so)。在做连接是将这个soname指定的名字加入执行文件中,而程序运行是也是去加载soname指定的库文件名。
所以如果程序连接了新升级的库(libhello_v2.so),只需要将这个新库拷贝到目录下面后,对其以soname做一个符号链接就能调用(libhello.so-->libhello_v2.so)。如果库升级了,但是程序依旧使用旧的链接库,那么只需对这个将旧库名字软链接到新升级的库中去即可。
soname的关键功能是它提供了兼容性的标准:
当要升级系统中的一个库时,并且新库的soname和老库的soname一样,用旧库的链接指向新库依然能正常运行。这个特性使得在Linux下,升级使得共享库的程序和定位错误变得十分容易。
在Linux中,应用程序通过使用soname,来指定所希望库的版本,库作者可以通过保留或改变soname来声明,哪些版本是兼容的,这使得程序员摆脱了共享库版本冲突问题的困扰。
可以通过readelf -d来查看每个动态库的SONAME
1. 生成文件名为libto.so.1.2,但soname为 libto.so.1的库
[root@localhost c]# gcc -fPIC -shared -Wl,-soname,libto.so.1 -o libto.so.1.2 to.c
[root@localhost c]# ls -lh
-rwxr-xr-x 1 root root 4268 Jan 10 17:22 libto.so.1.2
[root@localhost c]# ldconfig -n ./
lrwxrwxrwx 1 root root 12 Jan 10 17:23 libto.so.1 -> libto.so.1.2
-rwxr-xr-x 1 root root 4.2K Jan 10 17:22 libto.so.1.2
[root@localhost c]# readelf -d libto.so.1.2Dynamic section at offset 0x504 contains 21 entries:Tag Type Name/Value0x00000001 (NEEDED) Shared library: [libc.so.6]0x0000000e (SONAME) Library soname: [libto.so.1]0x0000000c (INIT) 0x2cc0x0000000d (FINI) 0x4c40x6ffffef5 (GNU_HASH) 0xb40x00000005 (STRTAB) 0x1b40x00000006 (SYMTAB) 0xf40x0000000a (STRSZ) 150 (bytes)0x0000000b (SYMENT) 16 (bytes)0x00000003 (PLTGOT) 0x15d80x00000002 (PLTRELSZ) 24 (bytes)0x00000014 (PLTREL) REL0x00000017 (JMPREL) 0x2b40x00000011 (REL) 0x2940x00000012 (RELSZ) 32 (bytes)0x00000013 (RELENT) 8 (bytes)0x6ffffffe (VERNEED) 0x2640x6fffffff (VERNEEDNUM) 10x6ffffff0 (VERSYM) 0x24a0x6ffffffa (RELCOUNT) 10x00000000 (NULL) 0x0
总结:程式库主要的升级会破坏相容性;而次要的升级则可能不会;那麽以下面的方式来连结,所有的一切就都会相安无事了。
gcc -shared -Wl,-soname,libfoo.so.major -o libfoo.so.major.minor
连接库
静态库
-L/your/library/path -l:libmylib.a
如果-l:filename
格式指定一个文件名,连接程序直接去找这个文件名了,不会再像使用-lname
时将name扩展成lib<name>.a
格式的文件名.
当然如果库的位置不在gcc默认搜索路径中,要用-L
参数另外指定搜索库的路径
更多推荐
【GCC】参数选项笔记
发布评论