gcc編譯選項--轉

gcc提供了大量的警告選項,對代碼中可能存在的問題提出警告,一般可使用-Wall來開啓如下警告:
           -Waddress -Warray-bounds (only with -O2) -Wc++0x-compat
           -Wchar-subscripts -Wimplicit-int -Wimplicit-function-declaration
           -Wcomment -Wformat -Wmain (only for C/ObjC and unless
           -ffreestanding) -Wmissing-braces -Wnonnull -Wparentheses
           -Wpointer-sign -Wreorder -Wreturn-type -Wsequence-point
           -Wsign-compare (only in C++) -Wstrict-aliasing -Wstrict-overflow=1
           -Wswitch -Wtrigraphs -Wuninitialized (only with -O1 and above)
           -Wunknown-pragmas -Wunused-function -Wunused-label -Wunused-value
           -Wunused-variable
unused-function:警告聲明可是沒有定義的static函數;
unused- label:聲明可是未使用的標籤;
unused-parameter:警告未使用的函數參數;
unused-variable:聲明可是未使用的本地變量;
unused-value:計算了可是未使用的值;
format:printf和scanf這樣的函數中的格式字符串的使用不當;
implicit-int:未指定類型;
implicit-function:函數在聲明前使用;
char- subscripts:使用char類做爲數組下標(由於char多是有符號數);
missingbraces:大括號不匹配;
parentheses: 圓括號不匹配;
return-type:函數有無返回值以及返回值類型不匹配;
sequence-point:違反順序點的代碼,好比 a[i] = c[i++];
switch:switch語句缺乏default或者switch使用枚舉變量爲索引時缺乏某個變量的case;
strict- aliasing=n:使用n設置對指針變量指向的對象類型產生警告的限制程度,默認n=3;只有在-fstrict-aliasing設置的狀況下有效;
unknow-pragmas:使用未知的#pragma指令;
uninitialized:使用的變量爲初始化,只在-O2時有效;

如下是在-Wall中不會激活的警告選項:
cast-align:當指針進行類型轉換後有內存對齊要求更嚴格時發出警告;
sign- compare:當使用signed和unsigned類型比較時;
missing-prototypes:當函數在使用前沒有函數原型時;
packed:packed 是gcc的一個擴展,是使結構體各成員之間不留內存對齊所需的空間,有時候會形成內存對齊的問題;
padded:也是gcc的擴展,使結構體成員之間進行內存對齊的填充,會形成結構體體積增大.
unreachable-code:有不會執行的代碼時.
inline:當inline函數再也不保持inline時 (好比對inline函數取地址);
disable-optimization:當不能執行指定的優化時.(須要太多時間或系統資源).
可使用 -Werror時全部的警告都變成錯誤,使出現警告時也中止編譯.須要和指定警告的參數一塊兒使用.

優化:
gcc默認提供了5級優化選項的集合:
-O0:無優化(默認)
-O和-O1:使用能減小目標文件大小以及執行時間而且不會使編譯時間明顯增長的優化.在編譯大型程序的時候會顯著增長編譯時內存的使用.
-O2: 包含-O1的優化並增長了不須要在目標文件大小和執行速度上進行折衷的優化.編譯器不執行循環展開以及函數內聯.此選項將增長編譯時間和目標文件的執行性能.
-Os:專門優化目標文件大小,執行全部的不增長目標文件大小的-O2優化選項.而且執行專門減少目標文件大小的優化選項.
-O3: 打開全部-O2的優化選項而且增長 -finline-functions, -funswitch-loops,-fpredictive-commoning, -fgcse-after-reload and -ftree-vectorize優化選項.

-O1包含的選項-O1一般能夠安全的和調試的選項一塊兒使用:
           -fauto-inc-dec -fcprop-registers -fdce -fdefer-pop -fdelayed-branch
           -fdse -fguess-branch-probability -fif-conversion2 -fif-conversion
           -finline-small-functions -fipa-pure-const -fipa-reference
           -fmerge-constants -fsplit-wide-types -ftree-ccp -ftree-ch
           -ftree-copyrename -ftree-dce -ftree-dominator-opts -ftree-dse
           -ftree-fre -ftree-sra -ftree-ter -funit-at-a-time

如下全部的優化選項須要在名字前加上-f,若是不須要此選項可使用-fno-前綴
defer-pop:延遲到只在必要時從函數參數棧中pop參數;
thread- jumps:使用跳轉線程優化,避免跳轉到另外一個跳轉;
branch-probabilities:分支優化;
cprop- registers:使用寄存器之間copy-propagation傳值;
guess-branch-probability:分支預測;
omit- frame-pointer:可能的狀況下不產生棧幀;

-O2:如下是-O2在-O1基礎上增長的優化選項:
           -falign-functions  -falign-jumps -falign-loops  -falign-labels
           -fcaller-saves -fcrossjumping -fcse-follow-jumps  -fcse-skip-blocks
           -fdelete-null-pointer-checks -fexpensive-optimizations -fgcse
           -fgcse-lm -foptimize-sibling-calls -fpeephole2 -fregmove
           -freorder-blocks  -freorder-functions -frerun-cse-after-loop
           -fsched-interblock  -fsched-spec -fschedule-insns
           -fschedule-insns2 -fstrict-aliasing -fstrict-overflow -ftree-pre
           -ftree-vrp
cpu架構的優化選項,一般是-mcpu(將被取消);-march,-mtune

Debug選項:
在 gcc編譯源代碼時指定-g選項能夠產生帶有調試信息的目標代碼,gcc能夠爲多個不一樣平臺上帝不一樣調試器提供調試信息,默認gcc產生的調試信息是爲 gdb使用的,可使用-gformat 指定要生成的調試信息的格式以提供給其餘平臺的其餘調試器使用.經常使用的格式有
-ggdb:生成gdb專用的調試信息,使用最適合的格式(DWARF 2,stabs等)會有一些gdb專用的擴展,可能形成其餘調試器沒法運行.
-gstabs:使用 stabs格式,不包含gdb擴展,stabs經常使用於BSD系統的DBX調試器.
-gcoff:產生COFF格式的調試信息,經常使用於System V下的SDB調試器;
-gxcoff:產生XCOFF格式的調試信息,用於IBM的RS/6000下的DBX調試器;
-gdwarf- 2:產生DWARF version2 的格式的調試信息,經常使用於IRIXX6上的DBX調試器.GCC會使用DWARF version3的一些特性.
能夠指定調試信息的等級:在指定的調試格式後面加上等級:
如: -ggdb2 等,0表明不產生調試信息.在使用-gdwarf-2時由於最先的格式爲-gdwarf2會形成混亂,因此要額外使用一個-glevel來指定調試信息的等級,其餘格式選項也能夠另外指定等級.

gcc可使用-p選項指定生成信息以供porf使用.

 

GCC經常使用選項

 

選項 含義
--help 
--target-help
顯示 gcc 幫助說明。‘target-help’是顯示目標機器特定的命令行選項。
--version 顯示 gcc 版本號和版權信息 。
-o outfile 輸出到指定的文件。
-xlanguage 指明使用的編程語言。容許的語言包括:c c++ assembler none 。 ‘none’意味着恢復默認行爲,即根據文件的擴展名猜想源文件的語言。
-v 打印較多信息,顯示編譯器調用的程序。
-### 與 -v 相似,但選項被引號括住,而且不執行命令。
-E 僅做預處理,不進行編譯、彙編和連接。如上圖所示。
-S 僅編譯到彙編語言,不進行彙編和連接。如上圖所示。
-c 編譯、彙編到目標代碼,不進行連接。如上圖所示。
-pipe 使用管道代替臨時文件。
-combine 將多個源文件一次性傳遞給彙編器。

 

 

3 其餘GCC選項

更多有用的GCC選項:c++

 

命令 描述
-l library
-llibrary
進行連接時搜索名爲library的庫。
例子: $ gcc test.c -lm -o test
-Idir dir加入到搜索頭文件的路徑列表中。
例子: $ gcc test.c -I../inc -o test
-Ldir dir加入到搜索庫文件的路徑列表中。
例子: $ gcc -I/home/foo -L/home/foo -ltest test.c -o test
-Dname 預約義一個名爲name的宏,值爲1。
例子: $ gcc -DTEST_CONFIG test.c -o test
-Dname=definition 預約義名爲name,值爲definition的宏。
-ggdb 
-ggdblevel
爲調試器 gdb 生成調試信息。level能夠爲1,2,3,默認值爲2。
-g 
-glevel
生成操做系統本地格式的調試信息。-g 和 -ggdb 並不太相同, -g 會生成 gdb 以外的信息。level取值同上。
-s 去除可執行文件中的符號表和重定位信息。用於減少可執行文件的大小。
-M 告訴預處理器輸出一個適合make的規則,用於描述各目標文件的依賴關係。對於每一個源文件,預處理器輸出 一個make規則,該規則的目標項(target)是源文件對應的目標文件名,依賴項(dependency)是源文件中 `#include引用的全部文件。生成的規則能夠是單行,但若是太長,就用`/'-換行符續成多行。規則 顯示在標準輸出,不產生預處理過的C程序。
-C 告訴預處理器不要丟棄註釋。配合`-E'選項使用。
-P 告訴預處理器不要產生`#line'命令。配合`-E'選項使用。
-static 在支持動態連接的系統上,阻止鏈接共享庫。該選項在其它系統上無效。
-nostdlib 不鏈接系統標準啓動文件和標準庫文件,只把指定的文件傳遞給鏈接器。
Warnings  
-Wall 會打開一些頗有用的警告選項,建議編譯時加此選項。
-W 
-Wextra
打印一些額外的警告信息。
-w 禁止顯示全部警告信息。
-Wshadow 當一個局部變量遮蓋住了另外一個局部變量,或者全局變量時,給出警告。頗有用的選項,建議打開。 -Wall 並不會打開此項。
-Wpointer-arith 對函數指針或者void *類型的指針進行算術操做時給出警告。也頗有用。 -Wall 並不會打開此項。
-Wcast-qual 當強制轉化丟掉了類型修飾符時給出警告。 -Wall 並不會打開此項。
-Waggregate-return 若是定義或調用了返回結構體或聯合體的函數,編譯器就發出警告。
-Winline 不管是聲明爲 inline 或者是指定了-finline-functions 選項,若是某函數不能內聯,編譯器都將發出警告。若是你的代碼含有不少 inline 函數的話,這是頗有用的選項。
-Werror 把警告看成錯誤。出現任何警告就放棄編譯。
-Wunreachable-code 若是編譯器探測到永遠不會執行到的代碼,就給出警告。也是比較有用的選項。
-Wcast-align 一旦某個指針類型強制轉換致使目標所需的地址對齊增長時,編譯器就發出警告。
-Wundef 當一個沒有定義的符號出如今 #if 中時,給出警告。
-Wredundant-decls 若是在同一個可見域內某定義屢次聲明,編譯器就發出警告,即便這些重複聲明有效而且毫無差異。
Optimization  
-O0 禁止編譯器進行優化。默認爲此項。
-O 
-O1
嘗試優化編譯時間和可執行文件大小。
-O2 更多的優化,會嘗試幾乎所有的優化功能,但不會進行「空間換時間」的優化方法。
-O3 在 -O2 的基礎上再打開一些優化選項:-finline-functions, -funswitch-loops 和 -fgcse-after-reload 。
-Os 對生成文件大小進行優化。它會打開 -O2 開的所有選項,除了會那些增長文件大小的。
-finline-functions 把全部簡單的函數內聯進調用者。編譯器會探索式地決定哪些函數足夠簡單,值得作這種內聯。
-fstrict-aliasing 施加最強的別名規則(aliasing rules)。
Standard  
-ansi 支持符合ANSI標準的C程序。這樣就會關閉GNU C中某些不兼容ANSI C的特性。
-std=c89 
-iso9899:1990
指明使用標準 ISO C90 做爲標準來編譯程序。
-std=c99 
-std=iso9899:1999
指明使用標準 ISO C99 做爲標準來編譯程序。
-std=c++98 指明使用標準 C++98 做爲標準來編譯程序。
-std=gnu9x 
-std=gnu99
使用 ISO C99 再加上 GNU 的一些擴展。
-fno-asm 不把asm, inline或typeof看成關鍵字,所以這些詞能夠用作標識符。用 __asm__, __inline__和__typeof__可以替代它們。 `-ansi' 隱含聲明瞭`-fno-asm'。
-fgnu89-inline 告訴編譯器在 C99 模式下看到 inline 函數時使用傳統的 GNU 句法。
C options  
-fsigned-char 
-funsigned-char
把char定義爲有/無符號類型,如同signed char/unsigned char。
-traditional 嘗試支持傳統C編譯器的某些方面。詳見GNU C手冊。
-fno-builtin 
-fno-builtin-function
不接受沒有 __builtin_ 前綴的函數做爲內建函數。
-trigraphs 支持ANSI C的三聯符( trigraphs)。`-ansi'選項隱含聲明瞭此選項。
-fsigned-bitfields 
-funsigned-bitfields
若是沒有明確聲明`signed'或`unsigned'修飾符,這些選項用來定義有符號位域或無符號位域。缺省狀況下,位域是有符號的,由於它們繼承的基本整數類型,如int,是有符號數。
-Wstrict-prototypes 若是函數的聲明或定義沒有指出參數類型,編譯器就發出警告。頗有用的警告。
-Wmissing-prototypes 若是沒有預先聲明就定義了全局函數,編譯器就發出警告。即便函數定義自身提供了函數原形也會產生這個警告。這個選項 的目的是檢查沒有在頭文件中聲明的全局函數。
-Wnested-externs 若是某extern聲明出如今函數內部,編譯器就發出警告。
C++ options  
-ffor-scope 從頭開始執行程序,也容許進行重定向。
-fno-rtti 關閉對 dynamic_cast 和 typeid 的支持。若是你不須要這些功能,關閉它會節省一些空間。
-Wctor-dtor-privacy 當一個類沒有用時給出警告。由於構造函數和析構函數會被看成私有的。
-Wnon-virtual-dtor 當一個類有多態性,而又沒有虛析構函數時,發出警告。-Wall會開啓這個選項。
-Wreorder 若是代碼中的成員變量的初始化順序和它們實際執行時初始化順序不一致,給出警告。
-Wno-deprecated 使用過期的特性時不要給出警告。
-Woverloaded-virtual 若是函數的聲明隱藏住了基類的虛函數,就給出警告。
Machine Dependent Options (Intel)  
-mtune=cpu-type 爲指定類型的 CPU 生成代碼。cpu-type能夠是:i386,i486,i586,pentium,i686,pentium4 等等。
-msse 
-msse2 
-mmmx 
-mno-sse 
-mno-sse2 
-mno-mmx
使用或者不使用MMX,SSE,SSE2指令。
-m32 
-m64
生成32位/64位機器上的代碼。
-mpush-args 
-mno-push-args
(不)使用 push 指令來進行存儲參數。默認是使用。
-mregparm=num 當傳遞整數參數時,控制所使用寄存器的個數。

另外:編程

當靜態庫和動態庫同名時, gcc命令將優先使用動態庫。數組

-shared 該選項指定生成動態鏈接庫(讓鏈接器生成T類型的導出符號表,有時候也生成弱鏈接W類型的導出符號),不用該標誌外部程序沒法鏈接。至關於一個可執行文件
-fPIC:表示編譯爲位置獨立的代碼,不用此選項的話編譯後的代碼是位置相關的因此動態載入時是經過代碼拷貝的方式來知足不一樣進程的須要,而不能達到真正代碼段共享的目的。
l -L.:表示要鏈接的庫在當前目錄中
l -ltest:編譯器查找動態鏈接庫時有隱含的命名規則,即在給出的名字前面加上lib,後面加上.so來肯定庫的名稱
l LD_LIBRARY_PATH:這個環境變量指示動態鏈接器能夠裝載動態庫的路徑。
l 固然若是有root權限的話,能夠修改/etc/ld.so.conf文件,而後調用 /sbin/ldconfig來達到一樣的目的,不過若是沒有root權限,那麼只能採用輸出LD_LIBRARY_PATH的方法了。調用動態庫的時候有幾個問題會常常碰到,有時,明明已經將庫的頭文件所在目錄 經過 「-I」 include進來了,庫所在文件經過 「-L」參數引導,並指定了「-l」的庫名,但經過ldd命令察看時,就是死活找不到你指定連接的so文件,這時你要做的就是經過修改 LD_LIBRARY_PATH或者/etc/ld.so.conf文件來指定動態庫的目錄。一般這樣作就能夠解決庫沒法連接的問題了。安全

相關文章
相關標籤/搜索