前面一篇已經(jīng)簡(jiǎn)單的介紹了如何利用gcc編譯c源代碼,這篇說(shuō)一下gcc的具體編譯過(guò)程
- 預(yù)處理
預(yù)處理的工作主要是處理#include語(yǔ)句等,然后生成*.i文件。如果不加參數(shù)“-o *.i”,則會(huì)將預(yù)處理的結(jié)果輸出到標(biāo)準(zhǔn)輸出。
gcc -E *.c -o *.i #使用gcc的E參數(shù)進(jìn)行預(yù)處理
cpp *c - o *.i #使用cpp命令進(jìn)行預(yù)處理
這兩條命令預(yù)處理的結(jié)果一樣,因?yàn)間cc使用-E參數(shù)實(shí)際上也是調(diào)用了cpp指令。
2.生成匯編代碼
gcc -S *c -o *.s #將C代碼匯編為匯編語(yǔ)言代碼
gcc -S *.i -o *.s #將i文件匯編為匯編語(yǔ)言代碼
3.編譯
gcc -c *.c -o *.o
gcc -c *.s -o *o
as *.s -o *.o
cc -c *.c -o *.o
4.鏈接
gcc *.o -o *out
GCC高級(jí)技巧
1.指定頭文件位置
一是在源碼中指定頭文件的絕對(duì)路徑,簡(jiǎn)單直觀但缺乏靈活性,二是在編譯時(shí)使用“-I”參數(shù)來(lái)指定頭文件的路徑,實(shí)際工作中,一般選擇第二種。
使用第二種方法將resolv.c編譯為resolv.out的命令如下:
gcc resolv.c -I /home/myname/code/header -o resolv.out 如果找不到會(huì)按照代碼所在目錄或系統(tǒng)目錄尋找頭文件
gcc resolv.c -I /home/myname/code/header -I /home/myname/code/header2 -o resolv.out 多個(gè)路徑
2.定義符號(hào)常量
在代碼中會(huì)使用一些常量來(lái)控制程序的行為,如#define WIRELESS 211 等等一系列,怎么來(lái)檢驗(yàn)定義了符號(hào)常量與為定義符號(hào)常量的區(qū)別,一般在編譯時(shí)使用-D參數(shù)來(lái)指定符號(hào)常量,命令如下:gcc -D WIRELESS -I /home/myname/code/header resolv.c -o resolv.out
3.定義警告級(jí)別
最常用的警告選項(xiàng)是-Wall選項(xiàng)。其意思是warning all。使用如下命令顯示特定警告信息來(lái)編譯test.c,命令如下:
gcc -Wall test.c -o test
4.其他GCC選項(xiàng)
gcc [option] [filename]
- -c:只將源代碼編譯為以.o為后綴的目標(biāo)文件,而不是直接將這些文件連接可執(zhí)行文件。通常用于不包含主程序(man函數(shù))的子程序代碼。
- -o:filename: 指定輸出文件名。如果不用這個(gè)選項(xiàng),gcc會(huì)將文件輸出到a.out,而不管輸出文件的類(lèi)型
- -g:產(chǎn)生調(diào)試信息。如果要使用gdb進(jìn)行調(diào)式,則必須使用該選項(xiàng)。但是該選項(xiàng)所產(chǎn)生的調(diào)式符號(hào),并不能被其他調(diào)式器識(shí)別。
- -O:在程序編譯、連接過(guò)程中對(duì)代碼進(jìn)行優(yōu)化。
- -O2:比-O更好的優(yōu)化編譯、連接。
- -L dir:在程序連接時(shí),會(huì)首先在dir目錄尋找類(lèi)庫(kù)文件,然后在系統(tǒng)預(yù)設(shè)路徑中尋找類(lèi)庫(kù)。也可以使用多個(gè)-L參數(shù)指定多個(gè)類(lèi)庫(kù)存放的目錄。
- -lname:在程序連接時(shí)加載名為libname.a的函數(shù)庫(kù)。如-lmath 表示連接名為libmath.a的數(shù)學(xué)函數(shù)庫(kù)。
- --sysboot=dir:讓目錄dir作為頭文件和庫(kù)文件的根目錄
- -B dir:將目錄dir添加到編譯器的搜索路徑中。
- -b:指定gcc編譯的目標(biāo)機(jī)器架構(gòu),如ARM、DEC、GNU/Linux、IA64、MIPS等,這也可以看出gcc的超級(jí)跨平臺(tái)性。
- -V n1.n2:使用n1.n2指定版本的gcc進(jìn)行編譯
- -E:僅作預(yù)處理,不能進(jìn)行編譯等工作,生成i文件
- -S:將源碼編譯為匯編語(yǔ)言代碼
- -x lang:將源代碼依照特定語(yǔ)言進(jìn)行編譯,可以取得值包括但不限于C、C++、Objective-C、Objective-C++、Assembler、Ada、java等。在一系列的編譯中,該選項(xiàng)會(huì)一直保持,知道另一個(gè)-x lang出現(xiàn),指定另一種編譯語(yǔ)言。如果是none,意味著讓gcc一句文件的后綴來(lái)自動(dòng)判斷語(yǔ)言種類(lèi)。