內容介紹
一.gcc編譯器簡介
二.一般編譯舉例
三.預處理
四.編譯
五.匯編
六.鏈接
七.gcc編譯優化
一.gcc編譯器的簡單介紹
gcc是GNU項目中符合ANSI C標准的編譯系統,是開放源代碼領域應用最廣泛的編譯器,又是一個交叉平台編譯器,功能強大。GCC可以用來編譯C/C++、FORTRAN、JAVA、OBJC、ADA等語言的程序,它能夠在當前CPU平台上為多種不同體系結構的硬件平台開發軟件。
二.一般編譯舉例
通常我們對一個源文件進行編譯時都是使用:gcc hello.c -o hello 這一命令,下面是編譯示例
這一編譯進過了預處理、編譯、匯編、鏈接四個階段,最終生成hello這一可執行程序。
三.預處理
預處理是C語言程序從源代碼轉變成可執行程序的第一步,它在程序編譯的第一個階段處理源代碼的文本,主要包括頭文件的包含、宏定義的擴展、條件編譯的選擇等並打印出預處理之後的結果。預處理階段根據已放在文件中的預處理指令來修改源文件。例如:#include<stdio.h>、#include<math.h>等都是預處理指令,他們的內容會被添加到
•C文件中。主要有以下幾方面處理:頭文件包含指令(如#include<stdio.h>)、條件編譯(如#endif)、宏定義指令(#define a)。
預處理語句:gcc -E filename,生成.i文件。生成的.i文件比較繁瑣,對於這種情況我們可用gcc -E filename1 filename2將filename1的處理結果放入filename2文件中,查看時打開該文件即可。例如:
此時hello.c預編譯後的文件內容存放到了hello.i文件中。
四.編譯
編譯所做的工作就是通過詞法分析和語法分析,在確認所有語法都正確的條件下,將文本文件轉換為等價的匯編代碼。
gcc -c filename,該指令只進行到編譯階段,執行後生成.o文件。
五.匯編
匯編的本質是將匯編代碼轉換成能被機器識別的機器語言,生成的目標程序中存放的也就是與源代碼等價的機器代碼。
gcc -s filename ,該指令只進行到匯編階段,執行後生成.s文件。
六.鏈接
1、鏈接的主要任務就是將有關的目標文件彼此相連接,使得這些目標文件成為一個能被操作系統裝入執行的統一整體。鏈接處理有兩種,一種是靜態鏈接,一種是動態鏈接。在靜態鏈接下函數的代碼將從其所在的靜態鏈接庫中拷貝到目標文件中;動態鏈接下函數的代碼被放到稱為動態鏈接庫或共享對象的某個目標文件中,在可執行文件執行時動態鏈接庫的全部內容將被映射到運行時相應進程的虛擬空間中。
2、靜態庫鏈接時搜索路徑順序:
1. ld會去找GCC命令中的參數-L
2. 再找gcc的環境變量LIBRARY_PATH
3. 再找內定目錄 /lib /usr/lib /usr/local/lib 這是當初compile gcc時寫在程序內的
3、動態鏈接時、執行時搜索路徑順序:
1. 編譯目標代碼時指定的動態庫搜索路徑
2. 環境變量LD_LIBRARY_PATH指定的動態庫搜索路徑
3. 配置文件/etc/ld.so.conf中指定的動態庫搜索路徑
4. 默認的動態庫搜索路徑/lib
5. 默認的動態庫搜索路徑/usr/lib
七.gcc編譯優化
gcc有三個優化選項,分別為gcc -o1 filename、gcc -o2 filename、gcc -o3 filename。
1、gcc -o1 filename:這一優化稱一級優化,該模式下對於一個大的函數或者會花費很多時間和內存的情況下,其編譯時會嘗試減少代碼體積和代碼的運行時間。
2、gcc -o2 filename:這一優化稱二級優化,它在一級優化下進一步優化,優化時編譯器不會進行循環展開和函數內聯,這種優化會增加編譯時間但會生成性能更好的代碼。
3、gcc -o3 filename:這一優化稱三級優化,在二級優化下進一步再優化,-03打開了-02的所有優化操作並打開了-finline-functions、-funswitch-loops、-fgcse-after-reload。