-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
[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
总结:程式库主要的升级会破坏相容性;而次要的升级则可能不会;那麽以下面的方式来连结,所有的一切就都会相安无事了。
gcc -shared -Wl,-soname,libfoo.so.major -o libfoo.so.major.minor