1. 程式人生 > >linux中動態庫的編譯和載入的查詢順序

linux中動態庫的編譯和載入的查詢順序

Glibc安裝的庫中有一個名為ld-Linux.so.X其中X為一個數字(版本),
在不同的平臺上可以通過ldd檢視
$ldd /bin/cat
linux-vdso.so.1 =>  (0x00007fff9176f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f16424d4000)
/lib64/ld-linux-x86-64.so.2 (0x00005592863c5000)

其中linux-vdso.so.1不是一個實際的庫檔案,它是一個虛擬庫檔案用來
和kernel互動。
ld-linux-x86_64.so.2是專門用來負責尋找庫檔案的庫。以cat為例,cat
首先告訴ld-linux-x86_64.so.2它需要libc.so.6這個庫檔案,ld-linux-x86_64.so
將按照一定的順序來查詢libc.so.6,再給cat進行呼叫。

===========================================================
問題1:ld-linux-x86_64.so.2這個庫是如何被找到的?
ld-linux-x86_64.so.2這個庫的位置是通過gcc編譯器寫死在裡面的。gcc寫到程式中
ld-linux-x86_64.so.2的位置是可以改變的,通過gcc的spec檔案。

============================================================
執行時,ld-linux.so查詢共享庫的順序
1.ld-linux.so在可執行的目標中被指定,可以通過readelf命令檢視。
2.ld-linux.so預設在/usr/lib和lib中搜索,當glibc安裝到/usr/local中時,
  它查詢/usr/local/lib
3.LD_LIBRARY_PATH 環境變數中設定的路徑
4./etc/ld.so.conf (或/usr/local/etc/ld.so.conf)中所指定的路徑,
  由ldconfig生成的二進位制ld.so.cache中。
 
============================================================
編譯時,ld-linux.so查詢共享庫的順序
1.ld-linux.so由gcc的spec檔案所指定
2.gcc --print-search-dirs所列印的路徑,主要是libgcc_s.so等庫
3.LIBRARY_PATH環境變數所設定的路徑,或編譯的命令列中指定 -L/usr/local/lib
4.binutils中的ld所設定的預設搜尋路徑順序,編譯binutils時指定
  可以通過 `ld --verbose | grep SEARCH` 來檢視
  ld --verbose | grep SEARCH | awk 'BEGIN{RS="; "} { print $0;}'
  可以按照行來檢視記錄
5.二進位制程式的搜尋路徑順序為PATH環境變數中所設定,一般/usr/local/bin高於/usr/bin
6.編譯的標頭檔案的搜尋路徑順序與library的查詢順序類似,一般/usr/local/include高於/usr/include