gcc及其选项详解
分類: LINUX
1.簡介:
gcc是gnu旗艦產品,目前基本上就是和unix捆綁在一起分發的。這個東西功能強大,但是有多達上千個選項,其用戶手冊也有將近一萬行.雖然其中的多數選項平時很少用到.但是不管裝軟件還是寫程序,往往都會用到gcc.下面我就gcc最最常用的幾個選項做一個簡要的說明,如果你想對gcc有一個全面的了解,比如你想知道在其他非x86平臺上gcc是如何工作的話,你可以用命令:man gcc;
gcc???? [-c|-S|-E] [-std=standard]
????????? [-g] [-pg] [-Olevel]
????????? [-Wwarn...] [-pedantic]
????????? [-Idir...] [-Ldir...]
????????? [-Dmacro[=defn]...] [-Umacro]
????????? [-foption...] [-mmachine-option...]
????????? [-o outfile] infile...
-c???????????????? 編譯為目標文件,不連接庫
-S???????????????? 編譯為匯編代碼
-E??? ?????????????預處理.預處理之后的代碼將送往標準輸出
-Wwarn... 設置警告,可以設置的警告開關很多,通常用-Wall開啟所有的警告
-Olevel?? 設置優化級別,level可以是0,1,2,3或者s,默認-O0,即不進行優化。.
-Dname=definition... 在命令行上定義宏,有兩種方式,-Dname或者-Dname=definition.在命令行上設置宏定義的目的主要是為了在調試的時候設定一些開關, 而在發布的時候再關閉或者打開這些開關即可,當然宏定義也用來對代碼進行有選擇地編譯.另外也還有其他的一些作用.
-Uname?????? 取消宏定義name,作用和上面的正好相反.
-Idir...??????? 把dir加到頭文件的搜索路徑中,而且gcc會在搜索標準頭文件之前先搜索dir.
-llibrary????? 在連接的時候搜索library庫,庫是一些archieve文件--其成員是目標文件.如果有文件引用library,library在命令行的位置應該在那個文件之后,因此,越底層的庫越要放在后面.比如如果你要連接pcap庫,那么你就需要使用-lpcap對源文件進行編譯.
-Ldir...??????? 把dir加到庫文件的搜索路徑中,而且gcc會在搜索標準庫文件之前先搜索dir.
-pthread?????? 通過pthreads庫加入對多線程的支持,這為預處理和連接設置了標志.pthread是POSIX指定的標準線程庫.
-std=standard?? 設置采用的標準,該選項是針對C語言的,比如-std=c99表示編譯器遵循C99標準.該選項較少使用.而且有時反而會把你搞糊涂.
-o outfile?????? 指定輸出文件的文件名,默認為a.out
-mmachine-option...?? 指定所用的平臺.
?
---------------------------------------------------------------------------------------
2.gcc常用選項總結
2.1 常規選項
1、沒有任何選項:gcc?? helloworld.c
結果會在與helloworld.c相同的目錄下產生一個a.out的可執行文件。
2、-o選項,指定輸出文件名:gcc -o helloworld helloworld.c
-o意思是Output即需要指定輸出的可執行文件的名稱。這里的名稱為helloworld。
3、-c選項,只編譯,不匯編連接:gcc -c helloworld.c
-c意思就是Compile,產生一個叫helloworld.o的目標文件
4、-S選項,產生匯編源文件:gcc -S helloworld.c
-S意思就是aSsemble,產生一個叫helloworld.s的匯編源文件
5、-E選項,預處理C源文件:gcc -E helloworld.c
-E意思就是prEprocess。輸出不是送到一個文件而是標準輸出。當然可以對它進行重定向:
gcc -E helloworld.c > helloworld.txt
2.2 優化選項
1) -O選項,基本優化:gcc -O helloworld.c
-O意思就是Optimize,產生一個經過優化的叫作a.out的可執行文件。也可以同時使用-o選項,以指定輸出文件名。如:
gcc -O -o test helloworld.c
即會產生一個叫test的經過優化的可執行文件。
2) -O2選項,最大優化:gcc -O2 helloworld.c
產生一個經過最大優化的叫作a.out的可執行文件。
2.3 調試選項
1) -g選項,產生供gdb調試用的可執行文件:gcc -g helloworld.c
產生一個叫作a.out的可執行文件,大小明顯比只用-o選項編譯匯編連接后的文件大。
2) -pg選項,產生供gprof剖析用的可執行文件:gcc -pg helloworld.c
產生一個叫作a.out的執行文件,大小明顯比用-g選項后產生的文件還大。
?
?
------------------------------------------------------------------------------------
3. Gcc的錯誤類型及對策
?Gcc編譯器如果發現源程序中有錯誤,就無法繼續進行,也無法生成最終的可執行文件。為了便于修改,gcc給出錯誤資訊,我們必須對這些錯誤資訊逐個進行分析、處理,并修改相應的語言,才能保證源代碼的正確編譯連接。gcc給出的錯誤資訊一般可以分為四大類,下面我們分別討論其產生的原因和對策。
第一類∶C語法錯誤
錯誤資訊∶文件source.c中第n行有語法錯誤(syntex errror)。這種類型的錯誤,一般都是C語言的語法錯誤,應該仔細檢查源代碼文件中第n行及該行之前的程序,有時也需要對該文件所包含的頭文件進行檢查。有些情況下,一個很簡單的語法錯誤,gcc會給出一大堆錯誤,我們最主要的是要保持清醒的頭腦,不要被其嚇倒,必要的時候再參考一下C語言的基本教材。
第二類∶頭文件錯誤
錯誤資訊∶找不到頭文件head.h(Can not find include file head.h)。這類錯誤是源代碼文件中的包含頭文件有問題,可能的原因有頭文件名錯誤、指定的頭文件所在目錄名錯誤等,也可能是錯誤地使用了雙引號和尖括號。
第三類∶檔案庫錯誤
錯誤資訊∶連接程序找不到所需的函數庫,例如∶
ld: -lm: No such file or directory
這類錯誤是與目標文件相連接的函數庫有錯誤,可能的原因是函數庫名錯誤、指定的函數庫所在目錄名稱錯誤等,檢查的方法是使用find命令在可能的目錄中尋找相應的函數庫名,確定檔案庫及目錄的名稱并修改程序中及編譯選項中的名稱。
第四類∶未定義符號
錯誤資訊∶有未定義的符號(Undefined symbol)。這類錯誤是在連接過程中出現的,可能有兩種原因∶一是使用者自己定義的函數或者全局變量所在源代碼文件,沒有被編譯、連接,或者干脆還沒有定義,這需要使用者根據實際情況修改源程序,給出全局變量或者函數的定義體;二是未定義的符號是一個標準的庫函數,在源程序中使用了該庫函數,而連接過程中還沒有給定相應的函數庫的名稱,或者是該檔案庫的目錄名稱有問題,這時需要使用檔案庫維護命令ar檢查我們需要的庫函數到底位于哪一個函數庫中,確定之后,修改gcc連接選項中的-l和-L項。
排除編譯、連接過程中的錯誤,應該說這只是程序設計中最簡單、最基本的一個步驟,可以說只是開了個頭。這個過程中的錯誤,只是我們在使用 C語言描述一個算法中所產生的錯誤,是比較容易排除的。我們寫一個程序,到編譯、連接通過為止,應該說剛剛開始,程序在運行過程中所出現的問題,是算法設計有問題,說得更玄點是對問題的認識和理解不夠,還需要更加深入地測試、調試和修改。一個程序,稍為復雜的程序,往往要經過多次的編譯、連接和測試、修改。總結
- 上一篇: Gaze Estimation笔记——d
- 下一篇: 还在担心没有服务器做不了数据分析?这个免