GCC簡介
Linux系統下的gcc(GNU C Compiler)是GNU推出的功能強大、性能優越的多平臺編譯器,是GNU的表明做品之一。gcc是能夠在多種硬體平臺上編譯出可執行程序的超級編譯器,其執行效率與通常的編譯器相比平均效率要高20%~30%。gcc編譯器能將C、C++語言源程序、匯程式化序和目標程序編譯、鏈接成可執行文件,若是沒有給出可執行文件的名字,gcc將生成一個名爲a.out的文件。
在Linux系統中,可執行文件沒有統一的後綴,系統從文件的屬性來區分可執行文件和不可執行文件。而gcc則經過後綴來區別輸入文件的類別,下面咱們來介紹gcc所遵循的部分約定規則。函數
.c爲後綴的文件,C語言源代碼文件; .a爲後綴的文件,是由目標文件構成的檔案庫文件; .C,.cc或.cxx 爲後綴的文件,是C++源代碼文件; .h爲後綴的文件,是程序所包含的頭文件; .i 爲後綴的文件,是已經預處理過的C源代碼文件; .ii爲後綴的文件,是已經預處理過的C++源代碼文件; .m爲後綴的文件,是Objective-C源代碼文件; .o爲後綴的文件,是編譯後的目標文件; .s爲後綴的文件,是彙編語言源代碼文件;
gcc的執行過程
雖然咱們稱gcc是C語言的編譯器,但使用gcc由C語言源代碼文件生成可執行文件的過程不單單是編譯的過程,而是要經歷四個相互關聯的步驟∶預處理(也稱預編譯,Preprocessing)、編譯(Compilation)、彙編(Assembly)和鏈接(Linking)。命令gcc首先調用cpp進行預處理,在預處理過程當中,對源代碼文件中的文件包含(include)、預編譯語句(如宏定義define等)進行分析。接着調用cc1進行編譯,這個階段根據輸入文件生成以.o爲後綴的目標文件。彙編過程是針對彙編語言的步驟,調用as進行工做,通常來說,.S爲後綴的彙編語言源代碼文件和彙編、.s爲後綴的彙編語言文件通過預編譯和彙編以後都生成以.o爲後綴的目標文件。當全部的目標文件都生成以後,gcc就調用ld來完成最後的關鍵性工做,這個階段就是鏈接。在鏈接階段,全部的目標文件被安排在可執行程序中的恰當的位置,同時,該程序所調用到的庫函數也從各自所在的檔案庫中連到合適的地方。性能
1、預處理(生成預編譯文件 ,.i文件)優化
gcc –E hello.c –o hello.i //必定.c做爲後綴,讓gcc識別
預處理過程主要處理那些源代碼中以#開始的預編譯指令,主要處理規則以下:
①將全部的#define刪除,而且展開全部的宏定義;
②處理全部條件編譯指令,如#if,#ifdef等;
③處理#include預編譯指令,將被包含的文件插入到該預編譯指令的位置。該過程遞歸進行,及被包含的文件可能還包含其餘文件。
④刪除全部的註釋//和 /**/;
⑤添加行號和文件標識,如#2 「hello.c」 2,以便於編譯時編譯器產生調試用的行號信息及用於編譯時產生編譯錯誤或警告時可以顯示行號信息;
⑥保留全部的#pragma編譯器指令,由於編譯器需要使用它們;spa
2、編譯(生成預編譯文件 ,.s文件)調試
gcc –S hello.i –o hello.s //能夠不用指定名字,默認生成一個.s文件
編譯過程就是把預處理完的文件進行一系列詞法分析,語法分析,語義分析及優化後生成相應的彙編代碼文件。code
3、彙編(生成彙編代碼,.o文件)blog
gcc –c hello.s –o hello.o //能夠不指定,默認生成.o的文件
彙編器是將彙編代碼轉變成機器能夠執行的命令,每個彙編語句幾乎都對應一條機器指令。遞歸
4、連接(生成可執行文件)ip
gcc hello.o –o hello
連接器ld將各個目標文件組裝在一塊兒,解決符號依賴,庫依賴關係,並生成可執行文件。編譯器
假定咱們有一個程序名爲hello.c的C語言源代碼文件,要生成一個可執行文件,最簡單的辦法就是∶
gcc hello.c -o myhello //一步便可完成
這時,預編譯、編譯鏈接一次完成,生成一個系統預設的名爲myhello.out的可執行文件。