gcc編譯過程
gcc編譯程式的四個階段:
1、 預處理(也稱預編譯)
2、 編譯
3、 彙編
4、 鏈結
在編譯程式的過程,可以加上不同的引數使其在不同階段停止,以便觀察不同階段的輸出資訊和輸出問檔案。
gcc檔案型別:
.c為字尾的檔案,c語言原始檔
.a為字尾的檔案是由目標檔案構成的檔案庫檔案
.c、.cc、.cpp、.c++、.cp或.cxx為字尾的檔案,是c++原始檔
.h為字尾的檔案,是程式所包含的標頭檔案
.i為字尾的檔案是已經預處理過的c源**檔案
.ii為字尾的檔案是已經預處理過的c++源**檔案
.m為字尾的objective-c源**檔案
.o為字尾的檔案是編譯後的目標檔案
.s為字尾的檔案是組合語言源**檔案
.s為字尾的檔案是經過預編譯的組合語言源**檔案
gcc在各階段的角色
gcc首先呼叫cpp進行預處理,在預處理過程中隊源**檔案中的檔案包含(include)、預編譯語句(如巨集定義define等)進行分析。接著呼叫cc1進行編譯,這個階段根據輸入檔案生成以.o為字尾的目標檔案。彙編過程就是針對組合語言的步驟,呼叫as進行工作,一般來講,.s為字尾的組合語言源**檔案和.s為字尾的組合語言檔案經過預編譯和彙編後都生成以.o為字尾的目標檔案。當所有的目標檔案都生成之後,gcc就呼叫ld來完成最後的關鍵性工作,這個階段就是鏈結,在鏈結階段所有的目標檔案被安排在可執行程式的恰當位置,同時,該程式所呼叫到的庫函式也從各自所在的庫連到合適的地方。
在windows環境下我使用mingw來學習gcc,linux環境下直接使用gcc就可以了。先看看gcc是怎樣完成整個編譯過程的。
先安裝好mingw為了操作方便,將mingw安裝位置的bin資料夾的路徑加入到環境變數path後面,這樣就可以直接在dos命令下使用bin下的各種工具。
先用記事本類的工具寫個最簡單的c程式儲存為my.c,如下:
#include
int main(void){
printf("hello world!");
return 0;
先看下gcc如何生成可執行檔案,最簡單的方法就是在dos視窗中執行gcc my.c –o my,當然先要cd到my.c檔案所在的路徑下不然是找不到my.c,之後即可看到my.exe可執行檔案。
-e 預處理後停下來,生成字尾為.i的預編譯檔案;
-s 彙編後停下來,生成字尾為.s的彙編原始檔;
-c 編譯後停下來,生成字尾為.o的目標檔案。
第一步,進行預編譯使用-e引數讓gcc在預處理結束後停止編譯過程:gcc–e my.c –o my.i
會發現多了乙個my.i的檔案,按照gcc首先呼叫cpp進行預編譯,剛好發現mingw安裝目錄bin有cpp.exe這個工具,把之前生成的my.i刪除,嘗試使用cpp –emy.c –o my.i進行預編譯,發現也會生成乙個my.i,my.i檔案是預編譯檔案,檢視該檔案發現stdio.h的內容確實插到檔案中去了,其他應當被預處理的巨集定義也作了相應的處理。
第二步,編譯。將源**檔案編譯成彙編**,gcc –s my.c –o my.s也可以使用gcc –s my.i –o my.s效果是一樣的,為了更好理解gcc編譯過程,使用gcc –s my.i –o my.s剛好利用了前面第一步預處理生成的my.i檔案。按照gcc是呼叫cc1進行編譯的,開始在mingw安裝位置的bin資料夾並沒找著cc1.exe,後來在mingw安裝位置的libexec目錄往下找找到了,將my.i檔案放到cc1.exe的同級目錄下,用cc1 –s my.i –o my.s發現gcc的確是呼叫cc1進行編譯。
第三步,彙編。將第二步生成的my.s源檔案匯編成目標**檔案,使用gcc –c my.c –o my.o或gcc –c my.i –o my.o或gcc –c my.s –o my.o或as my.s –o my.o,根據gcc在編譯階段是呼叫as將彙編源**進行編譯,使用as my.s –o my.o進行編譯。
第四步,鏈結。將第三步生成的my.o目標檔案鏈結成可執行檔案,使用gcc my.c –o my或gcc my.i –o my或gcc my.o –o my,按照gcc是呼叫ld來鏈結的可是使用ld my.o –o my會出現undefined reference to `__main'、undefined referenceto `printf'的錯誤,加上-lc引數又顯示找不到-lc,但是在linux下使用ld –e main my.o –lc –o my沒問題,我用的是fedora23的虛擬機器,估計在windows下對應的c庫沒找著,暫時放在這。
現在來理清下整個過程,gcc編譯的預處理、編譯、彙編、鏈結四個階段對應呼叫的四個工具是cpp、cc1、as、ld,預處理後生成.i的檔案,cc1將預處理後的.i檔案編譯成彙編原始檔,as將彙編源檔案匯編成.o的目標**檔案,然後通過ld鏈結成可執行檔案。
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...