GCC選項_-Wl,-soname
阿新 • • 發佈:2019-01-07
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
- [[email protected] c]# gcc -fPIC -shared -Wl,-soname,libto.so.1 -o libto.so.1.2 to.c
- [[email protected] c]# ls -lh
- -rwxr-xr-x 1 root root 4268 Jan 10 17:22 libto.so.1.2
- [[email protected] 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
- [[email protected] 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
- [[email protected] c]# gcc -fPIC -shared -Wl,-soname,libto.so.1 -o libto.so.1.3 to.c
- [[email protected] 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
- [[email protected] 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
- [[email protected] 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
- [[email protected] c]# gcc -fPIC -shared -Wl,-soname,libto.so.2 -o libto.so.1.4 to.c
- [[email protected] 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
- [[email protected] 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
- [[email protected] 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