gcc的編譯過程分為四個過程,即預處理(也稱預編譯,Preprocessing)、編譯(Compilation)、匯編 (Assembly)和連接(Linking)。
例如,編譯文件test.c,那么整個過程如下:
1.預處理
gcc -E test.c -o test.i 或 gcc -E test.c
可以輸出test.i文件中存放着test.c經預處理之后的代碼。打開test.i文件,看一看,就明白了。后面那條指令,是直接在命令行窗口中輸出預處理后的代碼.
gcc的-E選項,可以讓編譯器在預處理后停止,並輸出預處理結果。在本例中,預處理結果就是將stdio.h 文件中的內容插入到test.c中了。
2.編譯
預處理之后,可直接對生成的test.i文件編譯,生成匯編代碼:
gcc -S test.i -o test.s
gcc的-S選項,表示在程序編譯期間,在生成匯編代碼后,停止,-o輸出匯編代碼文件。
3.匯編
對於上一步驟生成的匯編代碼文件test.s,gas匯編器負責將其編譯為目標文件,如下:
gcc -c test.s -o test.o
4.鏈接
gcc連接器是gas提供的,負責將程序的目標文件與所需的所有附加的目標文件連接起來,最終生成可執行文件。附加的目標文件包括靜態連接庫和動態連接庫。
對於上一步驟生成的test.o,將其與C標准輸入輸出庫進行連接,最終生成程序test。
gcc test.o -o test
最后在命令行窗口中,執行./test,即可得到結果。
若進行多個程序文件編譯
通常整個程序是由多個源文件組成的,相應地也就形成了多個編譯單元,使用GCC能夠很好地管理這些編譯單元。假設有一個由test1.c和 test2.c兩個源文件組成的程序,為了對它們進行編譯,並最終生
成可執行程序test,可以使用下面這條命令:gcc test1.c test2.c -o test
如果同時處理的文件不止一個,GCC仍然會按照預處理、編譯和鏈接的過程依次進行。如果深究起來,上面這條命令大致相當於依次執行如下三條命令:
gcc -c test1.c -o test1.o
gcc -c test2.c -o test2.o
gcc test1.o test2.o -o test
gcc -D選項
gcc的-D選項可以定義宏
C語言源程序中有#define定義的宏,可以起到替換、條件編譯的功能;定義宏的方式是放在頭文件或者C文件中。gcc提供了另外一種宏定義的方法,當然可以想象這樣的宏定義方法並不是很好用,但畢竟編譯器給我們提供了額外的宏定義的方法。假設程序需要很多宏,不可能這些宏都在編譯器中定義,可以說比較重要的宏才會放在gcc的D選項后邊。
(1)-Dname 定義宏name,默認定義內容為字符串“1”
(2)-Dname=defn 定義宏name,並且內容為defn
例:
1.執行編譯命令:
gcc test.c -o test
test的執行結果:
HELLO not define!
2.條件編譯測試,執行編譯命令
gcc -DHELLO test.c -o test
test的執行結果:
HELLO defined!
HELLO = 1
3.宏替換測試,執行編譯命令
gcc -DHELLO=64 test.c -o test
test的執行結果:
HELLO defined!
HELLO = 64