編譯的相關流程

2021-05-25 06:00:43 字數 1161 閱讀 2757

二、編譯的相關流程

預處理(pre-processing)-->編譯(compiling)-->彙編(assembling)-->鏈結(linking)

1、預處理器

根據以字元#開頭的命令(directives),修改原始的c程式

這個階段並不會去檢查**的錯誤,只會把#的語句轉成c**

[gan@localhost gcc]# gcc e hello.c o hello.i

2、編譯階段

在這個階段中,gcc首先要檢查**的規範性、是否有語法錯誤等,以確定**的實際要做的工作,在檢查無誤後,gcc把**翻譯成組合語言。使用者可以使用」-s」選項來進行檢視,該選項只進行編譯而不進行彙編,生成彙編**。組合語言是非常有用的,它為不同高階語言不同編譯器提供了通用的語言。如:c編譯器和fortran編譯器產生的輸出檔案用的都是一樣的組合語言。

[gan@localhost gcc]# gcc s hello.i o hello.s

(3)彙編階段

彙編階段是把編譯階段生成的」.s」檔案轉成目標檔案,讀者在此可使用選項」-c」就可看到彙編**已轉化為」.o」的二進位制目標**了。如下所示:

[gan@localhost gcc]# gcc c hello.s(小寫s) o hello.o

(4)鏈結階段

將庫函式(標頭檔案中用到的)等鏈結到目標檔案中

"stdio.h"中也只有該函式的宣告,而沒有定義函式的實現,那麼,是在**實現」printf」這些庫函式的呢?最後的答案是:系統把這些函式實現都被做到名為libc.so.6的庫檔案中去了,在沒有特別指定時,gcc會到系統預設的搜尋路徑」/usr/lib」下進行查詢,也就是鏈結到libc.so.6庫函式中去,這樣就能實現函式」printf」 了,而這也就是鏈結的作用。

函式庫一般分為靜態庫和動態庫兩種。靜態庫是指編譯鏈結時,把庫檔案的**全部加入到可執行檔案中,因此生成的檔案比較大,但在執行時也就不再需要庫檔案了。其字尾名一般為」.a」。動態庫與之相反,在編譯鏈結時並沒有把庫檔案的**加入到可執行檔案中,而是在程式執行時由執行時鏈結檔案載入庫,這樣可以節省系統的開銷。動態庫一般字尾名為」.so」,如前面所述的libc.so.6就是動態庫。gcc在編譯時預設使用動態庫。

完成了鏈結之後,gcc就可以生成可執行檔案

[gan@localhost gcc]# gcc hello.o o hello

程式的編譯流程

程式的基本流程如圖 1.預處理 預處理相當於根據預處理指令組裝新的c c 程式。經過預處理,會產生乙個沒有巨集定義,沒有條件編譯指令,沒有特殊符號的輸出檔案,這個檔案的含義同原本的檔案無異,只是內容上有所不同。將所有的 define 刪除,並且展開所有的巨集定義 處理所有的條件編譯指令,如 if i...

gcc編譯流程,交叉編譯

gcc編譯過程 預編譯 gcc e c原始檔 o 輸出i目標檔案 編譯階段 gcc s i原始檔 o 輸出s目標檔案 彙編階段 gcc c s原始檔 o 輸出o目標檔案 gcc編譯例項 gcc g wall c原始檔 o 輸出可執行檔案 g表示在生成的目標檔案中帶除錯資訊,wall表示開啟編譯器常用...

C C 編譯流程

目錄結構 檔案內容 math.h ifndef math h define math h 計算階乘 param n 需要計算階乘的數 return 階乘 int factorial int n endif math.c include 計算階乘 param n 需要計算階乘的數 return 階乘 ...