gcc鏈結階段

2021-08-01 17:47:57 字數 1499 閱讀 3152

gcc鏈結階段(link time)

此階段,告訴編譯器,在**找到庫檔案?以靜態還是動態的方式鏈結庫檔案?預設情況下使用動態方式鏈結,這要求存在對應的.so動態庫檔案,如果不存在,則尋找相應的.a靜態庫檔案。

若在編譯時向gcc傳入-static選項,則使用靜態方式鏈結,這要求所有庫檔案都必須有對應的*.a靜態庫。

那麼,是否可以令某些庫使用動態鏈結,另一些庫使用靜態鏈結?不太確定,請參考ld的使用手冊,我沒有這樣用過。

在鏈結階段,gcc編譯器如何尋找庫檔案呢

(linker本身並沒有預設的查詢路徑,這些查詢路徑是由gcc傳遞給linker的)

大家可以在編譯時,

向gcc加入-v選項來觀察它向linker傳遞的庫檔案查詢路徑(觀察library_path變數的值),

通常查詢路徑如下:

任何由-rpath-link或-rpath選項指定的目錄 

ld_run_path(如果沒有找到-rpath或-rpath-link選項) 

-ldir1 -ldir2 ... 

/usr/lib/gcc/// 

/usr/lib/ 

第一行-rpath-link與-rpath選項的區別在於,-rpath選項指定的目錄被硬編碼到可執行檔案中,-rpath-link選項指定的目錄只在鏈結階段生效。由於這兩個選項都是鏈結器ld的選項,如何從gcc中向ld傳遞這兩個選項?方法如下(更從細節參考gcc的-wl選項):

gcc -wl, -rpath, /usr/local/lib

這相當於向ld向傳遞了如下引數:

ld -rpath /usr/local/lib

第二行,如果沒有設定-rpath或-rpath-link選項,則查詢ld_run_path環境變數指定的目錄,並把它當作-rpath選項來處理。第三行-ldir1 -ldir2 ...,是我們通過gcc的-l選項向其指定的庫檔案查詢路徑,查詢順序按照我們傳遞的-l引數從左到右進行搜尋;第四行屬於gcc自己的庫目錄;第五行/usr/lib/是linux系統預設的系統庫檔案的目錄。第

四、第五行,都是gcc自動向linker傳遞的查詢目錄。例如我現在的機器上,使用gcc -v可以看到library_path變數值為:

library_path=/usr/lib/gcc/i686-redhat-linux/4.5.1/:/usr/lib/

但是這並不是全部真理!根據我自己的測試,我發現gcc會把/usr/local/lib/目錄也作為鏈結階段的查詢路徑,這正是問題的根源——我們在鏈結過程中,使用到了/usr/local/lib/裡面的一些庫檔案,但在執行時階段,卻說找不到該庫檔案。

gcc編譯幾個階段

正文 編譯流程分析 編譯分為幾個過程 a 預處理 b 編譯 c 彙編 d 鏈結 以下分析,如何處理各個階段 首先預處理階段 目的就是要使include之中的內容編譯進去。並且用 e命令作用是進行檢視。作用是gcc的預處理過程結束後停止編譯 gcc指令的一般格式為 gcc 選項 要編譯的檔案 選項 目...

GCC靜態鏈結和動態鏈結

寫在前面 最近因為需要在不同版本的linux上執行編譯後的檔案,經常會遇到找不到需要的鏈結庫檔案的問題,後來突然想起了靜態編譯這一說。建靜態庫 hellos.h ifndef hello s h define hello s h void prints char str endif hellos.c...

gcc 鏈結引數 解釋

l引數就是用來指定程式要鏈結的庫,l引數緊接著就是庫名,那麼庫名跟真正的庫檔名有什麼關係呢?就拿數學庫來說,他的庫名是m,他的庫檔名是libm.so,很容易看出,把庫檔名的頭lib和尾.so去掉就是庫名了 好了現在我們知道怎麼得到庫名,當我們自已要用到乙個第三方提供的庫名字libtest.so,那麼...