GCC編譯過程(預處理->編譯->彙編->連結)

英雄的小白發表於2020-09-30

GCC編譯過程(預處理->編譯->彙編->連結)
這裡gcc編譯器 是指在linux類作業系統下,windows編譯器 MinGW(相當於windows版GCC)

生成可執行程式過程為成四個步驟:

1、 由.c檔案到.i檔案,這個過程叫預處理。
以“#”號開頭的預處理指令如包含#include,巨集定義制定#define等。在源程式中這些指令都放在函式之外,而且一般放在原始檔的前面。

2、由.i檔案到.s檔案,這個過程叫編譯。
這裡的編譯不是指程式從原始檔到二進位制程式的全部過程,而是指將經過預處理檔案(test.i)之後的程式轉換成特定彙編(test.s)程式碼的過程。

彙編是機器語言的直接翻譯形式

人們便嘗試用英文助記符代替晦澀的機器指令,例如ADD代表一條機器加法指令,助記符和機器指令一一對應,就這樣組合語言出現了,它極大的提高了人的工作效率。但是計算機並不認識彙編指令,必須將它替換為對應的機器指令,計算機才能執行它,這個過程叫彙編!

***人的追求永無止境,後來出現了各種高階語言,它接近人類自然語言的表達方式,便於人理解和使用。***其中C語言脫穎而出,它不可撼動的成為了系統程式語言,眾多作業系統例如unix,linux,ios,andriod等底層全部由C語言實現。C語言雖然是一種高階語言,但是它的硬體親和性決定了適合於底層,驅動,作業系統等領域,在嵌入式領域,首選的也是C語言。計算機無法執行高階語言程式,需要通過編譯程式把它翻譯成彙編程式碼,然後通過彙編程式翻譯成二進位制序列(機器語言),計算機才能執行它!

C語言封裝了很多彙編變成需要考慮的事情,比如函式傳參和呼叫棧管理

3、由.s檔案到.o檔案,這個過程叫彙編。
彙編過程將上一步的彙編程式碼轉換成機器碼,這一步產生的檔案叫做目標檔案,是二進位制格式。

有兩種方式:
使用 gcc直接從原始碼生成目的碼 gcc -c .s -o .o
使用
彙編器
從彙編程式碼生成目的碼 as *.s -o *.o

到編譯階段,程式碼還都是人類可以讀懂的。彙編這一階段,正式將彙編程式碼生成機器可以執行的目的碼,也就是二進位制碼。

4、由.o檔案到可執行檔案,這個過程叫連結。
連結過程使用連結器將該目標檔案與其他目標檔案、庫檔案、啟動檔案等連結起來生成可執行檔案。附加的目標檔案包括靜態連線庫和動態連線庫。
-L 與 -l 連結器引數,就是指定連結時去(哪裡)找(什麼)庫。
• -l,代表連結哪個庫,會自動檢索lib開頭的對應庫名。 例如-lpthread,-lQt5Core。會自動檢索libpthread.so,libpthread.a,libQt5Core.so,libQt5Core.a
o 如果靜態庫動態庫同時存在,優先連結動態庫

• -L,指定去哪裡找庫檔案。例如指定:-L/home/threedog/test,則在編譯時會優先檢索/home/threedog/test/libpthread.so等檔案。
• 連結庫最直接的辦法是不用任何引數,直接寫庫的路徑載入編譯引數裡。
• 查詢順序 :
o 如果直接寫的庫的全路徑,則會直接去找到庫,不走下面的順序檢索。
o -L,優先順序最高
o 然後是系統的環境變數LIBRARY_PATH
o 最後再找內定目錄 /lib/usr/lib/usr/local/lib 這是當初編譯 gcc時寫在程式內的
o 如果都找不到,會報錯找不到檔案或找不到-lxxxx

相關文章