gcc編譯過程
從 hello.c
到 hello(
或 a.out)
檔案, 必須歷經 hello.i
、 hello.s
、 hello.o
,最後才得到 hello(
或a.out)
檔案,分別對應著預處理、編譯、彙編和鏈結 4
個步驟,整個過程如圖 10.5
所示。
這 4
步大致的工作內容如下:
(1) 預處理, c
編譯器對各種預處理命令進行處理,包括標頭檔案包含、巨集定義的擴
展、條件編譯的選擇等;
(2) 編譯,將預處理得到的源**檔案,進行「翻譯轉換」,產生出機器語言的目標
程式,得到機器語言的彙編檔案;
(3) 彙編,將彙編**翻譯成了機器碼,但是還不可以執行;(4
下面根據 hello.c
這個示例,跟蹤一下其中的細節。
(1)預處理
在 gcc
命令加上-e
引數,可以得到預處理檔案。輸入下列命令:
vmuser@linux-host:hello$ gcc -e hello.c –o hello.i
將會產生 hello.i
檔案,這就是 hello.c
經過預處理後的檔案。實際操作結果見圖 10.6
圖 10.6
預編譯得到
hello.i
檔案乙個原本連同空行才 8
行的**,經過預處理,得到了乙個 800
多行的預處理檔案,文
件開的內容如圖 10.7
所示。
圖 10.7 hello.i
檔案開頭
hello.i
檔案末尾處的內容如圖 10.8
所示。
圖 10.8 hello.i
檔案末尾
其餘部分內容請用 vi
開啟後進行檢視。可以看到, hello.c
經過預處理後得到的 hello.i
檔案,除了原本的幾行**之外,還包含了很多額外的變數、函式等等,這些都是預處理器
處理的結果。
(2)編譯
在 gcc
編譯引數加上-s
,可以將 hello.i
編譯成 hello.s
檔案。命令如下:
vmuser@linux-host:hello$ gcc -s hello.i
實際操作和結果如圖 10.9
所示。圖 10.9
編譯得到
hello.s
檔案hello.s
是乙個彙編檔案,可用 vi
編輯器開啟檢視,如圖 10.10
所示。
圖 10.10 hello.s
檔案內容
可以看到,該檔案內容都是彙編語句。這裡不對彙編進行解釋。
(3)彙編
得到了彙編檔案後,通過 gcc
就可以得到機器碼了。在終端輸入下列命令,可以得到
hello.o
檔案。vmuser@linux-host:hello$ gcc -c hello.s
實際操作和結果如圖 10.11
所示。
圖 10.11
彙編得到
hello.o
檔案(4)鏈結
儘管已經得到了機器碼,但這個檔案卻還是不可以執行的,必須要經過鏈結才能執行。
在終端輸入下列命令,將會得到可執行檔案 a.out
。vmuser@linux-host:hello$ gcc hello.o
操作和結果如圖 10.12
所示。
圖 10.12
鏈結得到
a.out
檔案a.out
是 gcc
預設輸出檔名稱,可以通過-o
引數指定新的檔名。例如加上「-o hello
」引數,將會生成 hello
檔案,這個檔案和 a.out
實際上是一樣的,用 md5sum
命令計算檔案校
驗值,兩者完全一樣,如圖 10.13
所示。
圖 10.13 a.out
和 hello
檔案動態鏈結使用動態鏈結庫進行鏈結,生成的程式在執行的時候需要載入所需的動態
庫才能執行。動態鏈結生成的程式小巧,但是必須依賴動態庫,否則無法執行。
linux 下的動態鏈結庫實際是共享目標檔案(shared object),一般是.so 檔案,
作用類似於 windows 下的.dll 檔案。
靜態鏈結使用靜態庫進行鏈結,生成的程式包含程式執行所需要的全部庫,可以直
接執行,不過體積較大。
linux 下靜態庫是彙編產生的.o 檔案的集合,一般以.a 檔案形式出現。
gcc
預設是動態鏈結,加上-static
引數則採用靜態鏈結。再來看 hello.c
示例,在鏈結的
時候加上-static
引數:vmuser@linux-host:hello$ gcc hello.o -static -o hello_static
操作命令和結果如圖 10.14
所示,可以看到,動態鏈結生成的檔案大小是 7155
位元組,而靜態鏈結生成的檔案卻有 616096
位元組,體積明顯大了很多。
圖 10.14
靜態鏈結和動態鏈結結果對比
gcc編譯過程
本文對gcc編譯器如何工作做乙個概要描述.更為詳細的資訊請參考編譯器手冊。當我們進行編譯的時候,要使用一系列的工具,我們稱之為工具鏈.其中包括 預處理器cpp,編譯器前端gcc g 彙編器as,聯結器ld.乙個編譯過程包括下面幾個階段 1 預處理。預處理器cpp將對原始檔中的巨集進行展開。2 編譯。...
gcc編譯過程
當我們進行編譯的時候,要使用一系列的工具,我們稱之為工具鏈.其中包括 預處理器cpp,編譯器前端gcc g 彙編器as,聯結器ld.乙個編譯過程包括下面幾個階段 1 預處理。預處理器cpp將對原始檔中的巨集進行展開。2 編譯。gcc將c檔案編譯成彙編檔案。3 彙編。as將彙編檔案編譯成機器碼。4 連...
GCC編譯過程
第一步 預處理後結束 引數 e gcc e hello.c o hello.i 檢視hello.i檔案中的內容 cat hello.i stdio.h的內容插入到檔案裡去了,巨集定義也在預處理中都做了相應的處理 第二步 將hello.i 編譯為 目標 引數 c gcc c hello.i o hel...