通常所說的GCC是GUN Compiler Collection的簡稱,除了編譯程序之外,它還含其他相關工
除了上面講的之外,GCC除了支持C語言外,還支持多種其他語言
本系列文章中,我們不僅介紹GCC的基本功能,還涉及到一些諸如優
二、程序的編譯過程
對于GUN編譯器來說,程序的編譯要經歷預處理、編譯、匯編
?????
從功能上分,預處理、編譯、匯編是三個不同的階段
在預處理階段,輸入的是C語言的源文件,通常為*.c。它們通常帶有.h之類頭文件的包含文件。這個階段主要處理源文件中的#ifdef、 #i nclude和#define命令。該階段會生成一個中間文件
gcc -E??? test.c -o test.i
在編譯階段,輸入的是中間文件*.i,編譯后生成匯編語言文件*
GCC -S test.i -o test.s
在匯編階段,將輸入的匯編文件*.s轉換成機器語言*.o
GCC -c test.s -o test.o
最后,在連接階段將輸入的機器代碼文件*.s(與其它的機器代碼文
GCC test.o -o test
上面介紹了GCC編譯過程的四個階段以及相應的命令
三、GCC常用模式
這里介紹GCC追常用的兩種模式:編譯模式和編譯連接模式
$ GCC -o test
這里test.c是源文件,生成的可執行代碼存放在一個名為test 的文件中(該文件是機器代碼并且可執行)。-o 是生成可執行文件的輸出選項。如果我們只想讓源文件生成目標文件
$ GCC -c test.c
默認情況下,生成的目標文件被命名為test.o,但我們也可以為輸出文件指定名稱,如下所示:
$ GCC -c test.c -o
上面這條命令將編譯后的目標文件命名為mytest.o,而不是默認的test.o。
迄今為止,我們談論的程序僅涉及到一個源文件;現實中
$ GCC -o test??? first.c second.c third.c
需要注意的是,要生成可執行程序時,一個程序無論有有一個源文件還
四、常用選項
許多情況下,頭文件和源文件會單獨存放在不同的目錄中。例如
$ gcc test.c –I../inc -o test
上面的命令告訴GCC包含文件存放在./inc 目錄下,在當前目錄的上一級。如果在編譯時需要的包含文件存放在多
$ gcc test.c –I../inc –I../../inc2 -o test
這里指出了另一個包含子目錄inc2,較之前目錄它還要在再上兩級
另外,我們還可以在編譯命令行中定義符號常量。為此
$ gcc -DTEST_CONFIGURATION test.c -o test
上面的命令與在源文件中加入下列命令是等效的:
#define TEST_CONFIGURATION
在編譯命令行中定義符號常量的好處是,不必修改源文件就能改變由符
五、警告功能
當GCC 在編譯過程中檢查出錯誤的話,它就會中止編譯;但檢測到警告時卻能
在眾多的警告選項之中,最常用的就是-Wall選項
$ gcc -Wall test.c -o test
該選項相當于同時使用了下列所有的選項:
◆unused-function:遇到僅聲明過但尚未定義的靜態
◆unused-label:遇到聲明過但不使用的標號的警告。
◆unused-parameter:從未用過的函數參數的警告。
◆unused-variable:在本地聲明但從未用過的變量的
◆unused-value:僅計算但從未用過的值得警告。
◆Format:檢查對printf和scanf等函數的調用
◆implicit-int:警告沒有規定類型的聲明。
◆implicit-function-:在函數在未經聲明就使用
◆char-subscripts:警告把char類型作為數組下
◆missing-braces:聚合初始化兩邊缺少大括號。
◆Parentheses:在某些情況下如果忽略了括號
◆return-type:如果函數定義了返回類型
◆sequence-point:出現可疑的代碼元素時
◆Switch:如果某條switch語句的參數屬于枚舉類型
◆strict-aliasing:對變量別名進行最嚴格的檢查。
◆unknown-pragmas:使用了不允許的
◆Uninitialized:在初始化之前就使用自動變量。
需要注意的是,各警告選項既然能使之生效,當然也能使之關閉
$ gcc -Wall -Wno-unused test.c -o test
下面是使用-Wall選項的時候沒有生效的一些警告項:
◆cast-align:一旦某個指針類型強制轉換時
◆sign-compare:將有符號類型和無符號類型數據進行比
◆missing-prototypes :如果沒有預先聲明函數原形就定義了全局函數,編譯器就發出警告
◆Packed:當結構體帶有packed屬性但實際并沒有出現緊
◆Padded:如果結構體通過充填進行對齊則給出警告。
◆unreachable-code:如果發現從未執行的代碼時給
◆Inline:如果某函數不能內嵌(inline)
◆disabled-optimization:當需要太長時間或
上面是使用-Wall選項時沒有生效,但又比較常用的一些警告選項
六、小結
本文介紹了GCC的基本編譯過程和編譯模式,并詳細闡述了GCC的
該命令將同時編譯三個源文件,即first.c、second.c和 third.c,然后將它們連接成一個可執行程序,名為test。
附錄:
[參數詳解]?????
?? -x??? language??? filename???????
?? ??? 設定文件所使用的語言,使后綴名無效,對以后的多個有效.也就是根?????
?? ??? 據約定c語言的后綴名稱是.c的,而c++的后綴名是.c或者.cpp,如果?????
?? ??? 你很個性,決定你的c代碼文件的后綴名是.pig??? 哈哈,那你就要用這?????
?? ??? 個參數,這個參數對他后面的文件名都起作用,除非到了下一個參數?????
?? ??? 的使用。?????
?? ??? 可以使用的參數嗎有下面的這些?????
?? ??? `c,??? `objective-c,??? `c-header,??? `c++,??? `cpp-output,???????
?? ??? `assembler,??? and??? `assembler-with-cpp.?????
?? ??? 看到英文,應該可以理解的。?????
?? ??? 例子用法:?????
?? ??? gcc??? -x??? c??? hello.pig?????
?? ?????
?? -x??? none??? filename?????
?? 關掉上一個選項,也就是讓gcc根據文件名后綴,自動識別文件類型?????
?? 例子用法:?????
?? gcc??? -x??? c??? hello.pig??? -x??? none??? hello2.c?????
?? ?????
?? -c???????
?? 只激活預處理,編譯,和匯編,也就是他只把程序做成obj文件?????
?? 例子用法:?????
?? gcc??? -c??? hello.c?????
?? 他將生成.o的obj文件???????
????
?? -s?????
?? 只激活預處理和編譯,就是指把文件編譯成為匯編代碼。?????
?? 例子用法?????
?? gcc??? -s??? hello.c?????
?? 他將生成.s的匯編代碼,你可以用文本編輯器察看?????
????
?? -e?????
?? 只激活預處理,這個不生成文件,你需要把它重定向到一個輸出文件里?????
?? 面.?????
?? 例子用法:?????
?? gcc??? -e??? hello.c??? >??? pianoapan.txt?????
?? gcc??? -e??? hello.c??? |??? more?????
?? 慢慢看吧,一個hello??? word??? 也要與處理成800行的代碼?????
????
?? -o?????
?? 制定目標名稱,缺省的時候,gcc??? 編譯出來的文件是a.out,很難聽,如果?????
?? 你和我有同感,改掉它,哈哈?????
?? 例子用法?????
?? gcc??? -o??? hello.exe??? hello.c??? (哦,windows用習慣了)?????
?? gcc??? -o??? hello.asm??? -s??? hello.c?????
????
?? -pipe?????
?? 使用管道代替編譯中臨時文件,在使用非gnu匯編工具的時候,可能有些問?????
?? 題?????
?? gcc??? -pipe??? -o??? hello.exe??? hello.c?????
????
?? -ansi?????
?? 關閉gnu??? c中與ansi??? c不兼容的特性,激活ansi??? c的專有特性(包括禁止一?????
?? 些asm??? inline??? typeof關鍵字,以及unix,vax等預處理宏,?????
????
?? -fno-asm?????
?? 此選項實現ansi選項的功能的一部分,它禁止將asm,inline和typeof用作?????
?? 關鍵字。?????
?? ?????
?? -fno-strict-prototype?????
?? 只對g++起作用,使用這個選項,g++將對不帶參數的函數,都認為是沒有顯式?????
?? 的對參數的個數和類型說明,而不是沒有參數.?????
?? 而gcc無論是否使用這個參數,都將對沒有帶參數的函數,認為城沒有顯式說?????
?? 明的類型?????
?? ?????
?? -fthis-is-varialble?????
?? 就是向傳統c++看齊,可以使用this當一般變量使用.?????
?? ?????
?? -fcond-mismatch?????
?? 允許條件表達式的第二和第三參數類型不匹配,表達式的值將為void類型?????
?? ?????
?? -funsigned-char?????
?? -fno-signed-char?????
?? -fsigned-char?????
?? -fno-unsigned-char?????
?? 這四個參數是對char類型進行設置,決定將char類型設置成unsigned??? char(前?????
?? 兩個參數)或者??? signed??? char(后兩個參數)?????
?? ?????
?? -include??? file?????
?? 包含某個代碼,簡單來說,就是便以某個文件,需要另一個文件的時候,就可以?????
?? 用它設定,功能就相當于在代碼中使用#include<filename>?????
?? 例子用法:?????
?? gcc??? hello.c??? -include??? /root/pianopan.h?????
?? ?????
?? -imacros??? file?????
?? 將file文件的宏,擴展到gcc/g++的輸入文件,宏定義本身并不出現在輸入文件?????
?? 中?????
?? ?????
?? -dmacro?????
?? 相當于c語言中的#define??? macro?????
?? ?????
?? -dmacro=defn?????
?? 相當于c語言中的#define??? macro=defn?????
?? ?????
?? -umacro?????
?? 相當于c語言中的#undef??? macro?????
????
?? -undef?????
?? 取消對任何非標準宏的定義?????
?? ?????
?? -idir?????
?? 在你是用#include"file"的時候,gcc/g++會先在當前目錄查找你所制定的頭?????
?? 文件,如果沒有找到,他回到缺省的頭文件目錄找,如果使用-i制定了目錄,他?????
?? 回先在你所制定的目錄查找,然后再按常規的順序去找.?????
?? 對于#include<file>,gcc/g++會到-i制定的目錄查找,查找不到,然后將到系?????
?? 統的缺省的頭文件目錄查找?????
?? ?????
?? -i-?????
?? 就是取消前一個參數的功能,所以一般在-idir之后使用?????
?? ?????
?? -idirafter??? dir?????
?? 在-i的目錄里面查找失敗,講到這個目錄里面查找.?????
?? ?????
?? -iprefix??? prefix?????
?? -iwithprefix??? dir?????
?? 一般一起使用,當-i的目錄查找失敗,會到prefix+dir下查找?????
?? ?????
?? -nostdinc?????
?? 使編譯器不再系統缺省的頭文件目錄里面找頭文件,一般和-i聯合使用,明確?????
?? 限定頭文件的位置?????
?? ?????
?? -nostdin??? c++?????
?? 規定不在g++指定的標準路經中搜索,但仍在其他路徑中搜索,.此選項在創建?????
?? libg++庫使用?????
?? ?????
?? -c?????
?? 在預處理的時候,不刪除注釋信息,一般和-e使用,有時候分析程序,用這個很?????
?? 方便的?????
?? ?????
?? -m?????
?? 生成文件關聯的信息。包含目標文件所依賴的所有源代碼?????
?? 你可以用gcc??? -m??? hello.c來測試一下,很簡單。?????
?? ?????
?? -mm?????
?? 和上面的那個一樣,但是它將忽略由#include<file>造成的依賴關系。?????
?? ?????
?? -md?????
?? 和-m相同,但是輸出將導入到.d的文件里面?????
?? ?????
?? -mmd?????
?? 和-mm相同,但是輸出將導入到.d的文件里面?????
?? ?????
?? -wa,option?????
?? 此選項傳遞option給匯編程序;如果option中間有逗號,就將option分成多個選?????
?? 項,然后傳遞給會匯編程序?????
?? ?????
?? -wl.option?????
?? 此選項傳遞option給連接程序;如果option中間有逗號,就將option分成多個選?????
?? 項,然后傳遞給會連接程序.?????
?? ?????
????
?? -llibrary???????
?? 制定編譯的時候使用的庫?????
?? 例子用法?????
?? gcc??? -lcurses??? hello.c?????
?? 使用ncurses庫編譯程序?????
?? ?????
?? -ldir?????
?? 制定編譯的時候,搜索庫的路徑。比如你自己的庫,可以用它制定目錄,不然?????
?? 編譯器將只在標準庫的目錄找。這個dir就是目錄的名稱。?????
?? ?????
?? -o0?????
?? -o1?????
?? -o2?????
?? -o3?????
?? 編譯器的優化選項的4個級別,-o0表示沒有優化,-o1為缺省值,-o3優化級別最?????
?? 高 ?????
?? ?????
?? -g?????
?? 只是編譯器,在編譯的時候,產生條是信息。?????
?? ?????
?? -gstabs?????
?? 此選項以stabs格式聲稱調試信息,但是不包括gdb調試信息.?????
?? ?????
?? -gstabs+?????
?? 此選項以stabs格式聲稱調試信息,并且包含僅供gdb使用的額外調試信息.?????
?? ?????
?? -ggdb?????
?? 此選項將盡可能的生成gdb的可以使用的調試信息.?