1. 程式人生 > >GCC選項_-Wl,-soname

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

  1. [[email protected] c]# gcc -fPIC -shared -Wl,-soname,libto.so.1 -o libto.so.1.2 to.c  
  2. [[email protected] c]# ls -lh  
  3. -rwxr-xr-x 1 root root 4268 Jan 10 17:22 libto.so.1.2  
  4. [[email protected] c]# ldconfig -n ./  
  5. lrwxrwxrwx 1 root root   12 Jan 10 17:23 libto.so.1 -> libto.so.1.2  
  6. -rwxr-xr-x 1 root root 4.2K Jan 10 17:22 libto.so.1.2  
  1. [[email protected] c]# readelf -d libto.so.1.2  
  2. Dynamic section at offset 0x504 contains 21 entries:  
  3.   Tag        Type                         Name/Value  
  4.  0x00000001 (NEEDED)                     Shared library: [libc.so.6]  
  5.  0x0000000e (SONAME)                     Library soname: [libto.so.1]  
  6.  0x0000000c (INIT)                       0x2cc  
  7.  0x0000000d (FINI)                       0x4c4  
  8.  0x6ffffef5 (GNU_HASH)                   0xb4  
  9.  0x00000005 (STRTAB)                     0x1b4  
  10.  0x00000006 (SYMTAB)                     0xf4  
  11.  0x0000000a (STRSZ)                      150 (bytes)  
  12.  0x0000000b (SYMENT)                     16 (bytes)  
  13.  0x00000003 (PLTGOT)                     0x15d8  
  14.  0x00000002 (PLTRELSZ)                   24 (bytes)  
  15.  0x00000014 (PLTREL)                     REL  
  16.  0x00000017 (JMPREL)                     0x2b4  
  17.  0x00000011 (REL)                        0x294  
  18.  0x00000012 (RELSZ)                      32 (bytes)  
  19.  0x00000013 (RELENT)                     8 (bytes)  
  20.  0x6ffffffe (VERNEED)                    0x264  
  21.  0x6fffffff (VERNEEDNUM)                 1  
  22.  0x6ffffff0 (VERSYM)                     0x24a  
  23.  0x6ffffffa (RELCOUNT)                   1  
  24.  0x00000000 (NULL)                       0x0  

2. 宣告libto.so.1,並生成libto.so.1.3
  1. [[email protected] c]# gcc -fPIC -shared -Wl,-soname,libto.so.1 -o libto.so.1.3 to.c  
  2. [[email protected] c]# ls -lh  
  3. lrwxrwxrwx 1 root root   12 Jan 10 17:23 libto.so.1 -> libto.so.1.2  
  4. -rwxr-xr-x 1 root root 4.2K Jan 10 17:22 libto.so.1.2  
  5. -rwxr-xr-x 1 root root 4.2K Jan 10 17:23 libto.so.1.3  
  6. [[email protected] c]# ldconfig -n ./  
  7. lrwxrwxrwx 1 root root   12 Jan 10 17:24 libto.so.1 -> libto.so.1.3  #重新ldconfig,指向新的庫檔案  
  8. -rwxr-xr-x 1 root root 4.2K Jan 10 17:22 libto.so.1.2  
  9. -rwxr-xr-x 1 root root 4.2K Jan 10 17:23 libto.so.1.3  
  1. [[email protected] c]# readelf -d libto.so.1.3  
  2. Dynamic section at offset 0x504 contains 21 entries:  
  3.   Tag        Type                         Name/Value  
  4.  0x00000001 (NEEDED)                     Shared library: [libc.so.6]  
  5.  0x0000000e (SONAME)                     Library soname: [libto.so.1]  
  6.  0x0000000c (INIT)                       0x2cc  
  7.  0x0000000d (FINI)                       0x4c4  
  8.  0x6ffffef5 (GNU_HASH)                   0xb4  
  9.  0x00000005 (STRTAB)                     0x1b4  
  10.  0x00000006 (SYMTAB)                     0xf4  
  11.  0x0000000a (STRSZ)                      150 (bytes)  
  12.  0x0000000b (SYMENT)                     16 (bytes)  
  13.  0x00000003 (PLTGOT)                     0x15d8  
  14.  0x00000002 (PLTRELSZ)                   24 (bytes)  
  15.  0x00000014 (PLTREL)                     REL  
  16.  0x00000017 (JMPREL)                     0x2b4  
  17.  0x00000011 (REL)                        0x294  
  18.  0x00000012 (RELSZ)                      32 (bytes)  
  19.  0x00000013 (RELENT)                     8 (bytes)  
  20.  0x6ffffffe (VERNEED)                    0x264  
  21.  0x6fffffff (VERNEEDNUM)                 1  
  22.  0x6ffffff0 (VERSYM)                     0x24a  
  23.  0x6ffffffa (RELCOUNT)                   1  
  24.  0x00000000 (NULL)                       0x0  

3. 宣告libto.so.2,並生成libto.so.1.4
  1. [[email protected] c]# gcc -fPIC -shared -Wl,-soname,libto.so.2 -o libto.so.1.4 to.c  
  2. [[email protected] c]# ls -lh  
  3. lrwxrwxrwx 1 root root   12 Jan 10 17:24 libto.so.1 -> libto.so.1.3  
  4. -rwxr-xr-x 1 root root 4.2K Jan 10 17:22 libto.so.1.2  
  5. -rwxr-xr-x 1 root root 4.2K Jan 10 17:23 libto.so.1.3  
  6. -rwxr-xr-x 1 root root 4.2K Jan 10 17:24 libto.so.1.4  
  7. [[email protected] c]# ldconfig -n ./  
  8. lrwxrwxrwx 1 root root   12 Jan 10 17:24 libto.so.1 -> libto.so.1.3  #重新ldconfig,不指向新的庫檔案,因為新庫(1.4)的soname為libto.so.2  
  9. -rwxr-xr-x 1 root root 4.2K Jan 10 17:22 libto.so.1.2  
  10. -rwxr-xr-x 1 root root 4.2K Jan 10 17:23 libto.so.1.3  
  11. -rwxr-xr-x 1 root root 4.2K Jan 10 17:24 libto.so.1.4  
  12. lrwxrwxrwx 1 root root   12 Jan 10 17:24 libto.so.2 -> libto.so.1.4  
  1. [[email protected] c]# readelf -d libto.so.1.4  
  2. Dynamic section at offset 0x504 contains 21 entries:  
  3.   Tag        Type                         Name/Value  
  4.  0x00000001 (NEEDED)                     Shared library: [libc.so.6]  
  5.  0x0000000e (SONAME)                     Library soname: [libto.so.2]  
  6.  0x0000000c (INIT)                       0x2cc  
  7.  0x0000000d (FINI)                       0x4c4  
  8.  0x6ffffef5 (GNU_HASH)                   0xb4  
  9.  0x00000005 (STRTAB)                     0x1b4  
  10.  0x00000006 (SYMTAB)                     0xf4  
  11.  0x0000000a (STRSZ)                      150 (bytes)  
  12.  0x0000000b (SYMENT)                     16 (bytes)  
  13.  0x00000003 (PLTGOT)                     0x15d8  
  14.  0x00000002 (PLTRELSZ)                   24 (bytes)  
  15.  0x00000014 (PLTREL)                     REL  
  16.  0x00000017 (JMPREL)                     0x2b4  
  17.  0x00000011 (REL)                        0x294  
  18.  0x00000012 (RELSZ)                      32 (bytes)  
  19.  0x00000013 (RELENT)                     8 (bytes)  
  20.  0x6ffffffe (VERNEED)                    0x264  
  21.  0x6fffffff (VERNEEDNUM)                 1  
  22.  0x6ffffff0 (VERSYM)                     0x24a  
  23.  0x6ffffffa (RELCOUNT)                   1  
  24.  0x00000000 (NULL)                       0x0  


總結:程式庫主要的升級會破壞相容性;而次要的升級則可能不會;那麼以下面的方式來連結,所有的一切就都會相安無事了。 
gcc -shared -Wl,-soname,libfoo.so.major -o libfoo.so.major.minor

直觀理解,加上soname之後,要想修改這個名字,只能用軟連結到這個庫,修改軟連結的名字。連線到可執行檔案中去的名字還是soname