C/C++之Gcc常用参数
gcc是GNU旗艦產品,目前基本上就是和Unix捆綁在一起分發的。這個東西功能強大,有多達上千個選項,其用戶手冊也有將近一萬行。雖然其中的多數選項平時很少用到,但是不管裝軟件還是寫程序,往往都會用到gcc。下面我就gcc最最常用的幾個選項做一個簡要的說明。
Gcc指令的一般格式為: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... 指定所用的平臺。
Linux下常見文件擴展名
1、沒有任何選項:gcc hello.c
結果會在與hello.c相同的目錄下產生一個a.out的可執行文件。
2、-o選項,指定輸出文件名:gcc -o hello hello.c
-o意思是Output即需要指定輸出的可執行文件的名稱。這里的名稱為helloworld。
3、-c選項,只編譯,不匯編連接:gcc -c hello.c
-c意思就是Compile,產生一個叫hello.o的目標文件
4、-S選項,產生匯編源文件:gcc -S hello.c
-S意思就是aSsemble,產生一個叫hello.s的匯編源文件
5、-E選項,預處理C源文件:gcc -E hello.c
-E意思就是prEprocess。輸出不是送到一個文件而是標準輸出。當然可以對它進行重定向:gcc -E hello.c > helloworld.txt或者gcc –E hello.c –o hello.i
6.1、-O選項,基本優化:gcc -O hello.c
-O意思就是Optimize,產生一個經過優化的叫作a.out的可執行文件。也可以同時使用-o選項,以指定輸出文件名。如:gcc -O -o test hello.c
6.2、-O2選項,最大優化:gcc -O2 hello.c
產生一個經過最大優化的叫作a.out的可執行文件。
7、-g選項,產生供gdb調試用的可執行文件:gcc -g helloworld.c
產生一個叫作a.out的可執行文件,大小明顯比只用-o選項編譯匯編連接后的文件大。
8、-pg選項,產生供gprof剖析用的可執行文件:gcc -pg helloworld.c
產生一個叫作a.out的執行文件,大小明顯比用-g選項后產生的文件還大。
gcc編譯器的工作過程
Gcc的編譯流程分為了4個步驟,分別為:
- 預處理(Pre-Processing)
- 編譯(Compiling)
- 匯編(Assembling)
- 鏈接(Linking)。
預處理:gcc -E hello.c -o hello.i
?
編譯:gcc -S hello.i -o hello.s
gcc 編譯階段首先要檢查代碼的規范性,是否有語法錯誤等。以確定代碼實際要做的工作,在檢查無誤后,gcc 把代碼翻譯成匯編語言。用戶可以使用-S 選項進行查看,該選項只進
匯編:gcc -c hello.s -o hello.o
gcc 匯編階段:生成目標代碼 *.o ;有兩種方式:使用 gcc 直接從源代碼生成目標代碼 gcc -c *.s -o *.o 以及使用匯編器從匯編代碼生成目標代碼 as *.s -o *.o
鏈接:gcc hello.o -o hello
gcc 鏈接階段:生成可執行文件
也可以直接使用as *.s, 將執行匯編、鏈接過程生成可執行文件a.out, 可以像上面使用-o 選項指定輸出文件的格式。
?
Gcc的錯誤類型及對策
Gcc編譯器如果發現源程序中有錯誤,就無法繼續進行,也無法生成最終的可執行文件。為了便于修改,gcc給出錯誤資訊,我們必須對這些錯誤資訊逐個進行分析、處理,并修改相應的語言,才能保證源代碼的正確編譯連接。gcc給出的錯誤資訊一般可以分為四大類,下面我們分別討論其產生的原因和對策。
第一類∶C語法錯誤
error∶文件source.c中第n行有語法錯誤(syntex errror)。
這種類型的錯誤,一般都是C語言的語法錯誤,應該仔細檢查源代碼文件中第n行及該行之前的程序,有時也需要對該文件所包含的頭文件進行檢查。有些情況下,一個很簡單的語法錯誤,gcc會給出一大堆錯誤。
第二類∶頭文件錯誤
error∶找不到頭文件head.h(Can not find include file head.h)。
這類錯誤是源代碼文件中的包含頭文件有問題,可能的原因有頭文件名錯誤、指定的頭文件所在目錄名錯誤等,也可能是錯誤地使用了雙引號和尖括號。
第三類∶檔案庫錯誤
error∶連接程序找不到所需的函數庫,例如∶ ld: -lm: No such file or directory
這類錯誤是與目標文件相連接的函數庫有錯誤,可能的原因是函數庫名錯誤、指定的函數庫所在目錄名稱錯誤等,檢查的方法是使用find命令在可能的目錄中尋找相應的函數庫名,確定檔案庫及目錄的名稱并修改程序中及編譯選項中的名稱。
第四類∶未定義符號
error∶有未定義的符號(Undefined symbol)。
這類錯誤是在連接過程中出現的,可能有兩種原因∶一是使用者自己定義的函數或者全局變量所在源代碼文件,沒有被編譯、連接,或者干脆還沒有定義,這需要使用者根據實際情況修改源程序,給出全局變量或者函數的定義體;二是未定義的符號是一個標準的庫函數,在源程序中使用了該庫函數,而連接過程中還沒有給定相應的函數庫的名稱,或者是該檔案庫的目錄名稱有問題,這時需要使用檔案庫維護命令ar檢查我們需要的庫函數到底位于哪一個函數庫中,確定之后,修改gcc連接選項中的-l和-L項。
?
總結
以上是生活随笔為你收集整理的C/C++之Gcc常用参数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C/C++之大端模式和小端模式
- 下一篇: C/C++之C++命名空间