GCC选项_-Wl,-soname
Posted sunmenggmail
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GCC选项_-Wl,-soname相关的知识,希望对你有一定的参考价值。
http://blog.csdn.net/gohome520/article/details/7259450
-Wl选项告诉编译器将后面的参数传递给链接器。
-soname则指定了动态库的soname(简单共享名,Short for shared object name)
soname的关键功能是它提供了兼容性的标准:
当要升级系统中的一个库时,并且新库的soname和老库的soname一样,用旧库链接生成的程序使用新库依然能正常运行。这个特性使得在Linux下,升级使得共享库的程序和定位错误变得十分容易。
在Linux中,应用程序通过使用soname,来指定所希望库的版本,库作者可以通过保留或改变soname来声明,哪些版本是兼容的,这使得程序员摆脱了共享库版本冲突问题的困扰。
可以通过readelf -d来查看每个动态库的SONAME
1. 声明libto.so.1,并生成libto.so.1.2
[plain] view plain copy
- [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.2
- Dynamic section at offset 0x504 contains 21 entries:
- Tag Type Name/Value
- 0x00000001 (NEEDED) Shared library: [libc.so.6]
- 0x0000000e (SONAME) Library soname: [libto.so.1]
- 0x0000000c (INIT) 0x2cc
- 0x0000000d (FINI) 0x4c4
- 0x6ffffef5 (GNU_HASH) 0xb4
- 0x00000005 (STRTAB) 0x1b4
- 0x00000006 (SYMTAB) 0xf4
- 0x0000000a (STRSZ) 150 (bytes)
- 0x0000000b (SYMENT) 16 (bytes)
- 0x00000003 (PLTGOT) 0x15d8
- 0x00000002 (PLTRELSZ) 24 (bytes)
- 0x00000014 (PLTREL) REL
- 0x00000017 (JMPREL) 0x2b4
- 0x00000011 (REL) 0x294
- 0x00000012 (RELSZ) 32 (bytes)
- 0x00000013 (RELENT) 8 (bytes)
- 0x6ffffffe (VERNEED) 0x264
- 0x6fffffff (VERNEEDNUM) 1
- 0x6ffffff0 (VERSYM) 0x24a
- 0x6ffffffa (RELCOUNT) 1
- 0x00000000 (NULL) 0x0
2. 声明libto.so.1,并生成libto.so.1.3
[plain] view plain copy
- [root@localhost c]# gcc -fPIC -shared -Wl,-soname,libto.so.1 -o libto.so.1.3 to.c
- [root@localhost c]# ls -lh
- 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
- -rwxr-xr-x 1 root root 4.2K Jan 10 17:23 libto.so.1.3
- [root@localhost c]# ldconfig -n ./
- lrwxrwxrwx 1 root root 12 Jan 10 17:24 libto.so.1 -> libto.so.1.3 #重新ldconfig,指向新的库文件
- -rwxr-xr-x 1 root root 4.2K Jan 10 17:22 libto.so.1.2
- -rwxr-xr-x 1 root root 4.2K Jan 10 17:23 libto.so.1.3
- [root@localhost c]# readelf -d libto.so.1.3
- Dynamic section at offset 0x504 contains 21 entries:
- Tag Type Name/Value
- 0x00000001 (NEEDED) Shared library: [libc.so.6]
- 0x0000000e (SONAME) Library soname: [libto.so.1]
- 0x0000000c (INIT) 0x2cc
- 0x0000000d (FINI) 0x4c4
- 0x6ffffef5 (GNU_HASH) 0xb4
- 0x00000005 (STRTAB) 0x1b4
- 0x00000006 (SYMTAB) 0xf4
- 0x0000000a (STRSZ) 150 (bytes)
- 0x0000000b (SYMENT) 16 (bytes)
- 0x00000003 (PLTGOT) 0x15d8
- 0x00000002 (PLTRELSZ) 24 (bytes)
- 0x00000014 (PLTREL) REL
- 0x00000017 (JMPREL) 0x2b4
- 0x00000011 (REL) 0x294
- 0x00000012 (RELSZ) 32 (bytes)
- 0x00000013 (RELENT) 8 (bytes)
- 0x6ffffffe (VERNEED) 0x264
- 0x6fffffff (VERNEEDNUM) 1
- 0x6ffffff0 (VERSYM) 0x24a
- 0x6ffffffa (RELCOUNT) 1
- 0x00000000 (NULL) 0x0
3. 声明libto.so.2,并生成libto.so.1.4
[plain] view plain copy
- [root@localhost c]# gcc -fPIC -shared -Wl,-soname,libto.so.2 -o libto.so.1.4 to.c
- [root@localhost c]# ls -lh
- lrwxrwxrwx 1 root root 12 Jan 10 17:24 libto.so.1 -> libto.so.1.3
- -rwxr-xr-x 1 root root 4.2K Jan 10 17:22 libto.so.1.2
- -rwxr-xr-x 1 root root 4.2K Jan 10 17:23 libto.so.1.3
- -rwxr-xr-x 1 root root 4.2K Jan 10 17:24 libto.so.1.4
- [root@localhost c]# ldconfig -n ./
- lrwxrwxrwx 1 root root 12 Jan 10 17:24 libto.so.1 -> libto.so.1.3 #重新ldconfig,不指向新的库文件,因为新库(1.4)的soname为libto.so.2
- -rwxr-xr-x 1 root root 4.2K Jan 10 17:22 libto.so.1.2
- -rwxr-xr-x 1 root root 4.2K Jan 10 17:23 libto.so.1.3
- -rwxr-xr-x 1 root root 4.2K Jan 10 17:24 libto.so.1.4
- lrwxrwxrwx 1 root root 12 Jan 10 17:24 libto.so.2 -> libto.so.1.4
- [root@localhost c]# readelf -d libto.so.1.4
- Dynamic section at offset 0x504 contains 21 entries:
- Tag Type Name/Value
- 0x00000001 (NEEDED) Shared library: [libc.so.6]
- 0x0000000e (SONAME) Library soname: [libto.so.2]
- 0x0000000c (INIT) 0x2cc
- 0x0000000d (FINI) 0x4c4
- 0x6ffffef5 (GNU_HASH) 0xb4
- 0x00000005 (STRTAB) 0x1b4
- 0x00000006 (SYMTAB) 0xf4
- 0x0000000a (STRSZ) 150 (bytes)
- 0x0000000b (SYMENT) 16 (bytes)
- 0x00000003 (PLTGOT) 0x15d8
- 0x00000002 (PLTRELSZ) 24 (bytes)
- 0x00000014 (PLTREL) REL
- 0x00000017 (JMPREL) 0x2b4
- 0x00000011 (REL) 0x294
- 0x00000012 (RELSZ) 32 (bytes)
- 0x00000013 (RELENT) 8 (bytes)
- 0x6ffffffe (VERNEED) 0x264
- 0x6fffffff (VERNEEDNUM) 1
- 0x6ffffff0 (VERSYM) 0x24a
- 0x6ffffffa (RELCOUNT) 1
- 0x00000000 (NULL) 0x0
总结:程式库主要的升级会破坏相容性;而次要的升级则可能不会;那麽以下面的方式来连结,所有的一切就都会相安无事了。
gcc -shared -Wl,-soname,libfoo.so.major -o libfoo.so.major.minor
直观理解,加上soname之后,要想修改这个名字,只能用软链接到这个库,修改软链接的名字。连接到可执行文件中去的名字还是soname
以上是关于GCC选项_-Wl,-soname的主要内容,如果未能解决你的问题,请参考以下文章
gcc编译器选项-Wl,--no-undefined(告诉链接器在链接过程中不允许有未定义的符号)(gcc编译器和链接器是分离的工具,它们需要通过选项来进行通信)