韌館-LearnHouse

gcc 參數

## -c
只生成 obj 檔,並沒有產生執行檔。
例:gcc -c hello.c

## -o
生成執行檔,file name 沒指定時,預設檔名為 a.out。
例:gcc -o hello hello.c

## -llibrary
設定 link 時需便用的 library。
例:gcc -o hello -lhell hello.c,需要的 library 為 libhello.a。

## -Ldir
設定 link 時,查找 library 的路徑。
例:gcc -o hello -lhell -L. hello.c,會在源碼目錄內找尋 libhello.a 。

## -Idir
設定 compile 時,查找 include 的路徑。
例:gcc -o hello -I. hello.c,會在源碼目錄內找尋 include 檔 。

## -I-
取消前面所有 -Idir 的設定。

## -g
在執行檔中,加入 debug 訊息。

## -traditional
試圖讓編譯器支援傳統的C語言特性。

## -static
禁止使用動態 library。

## -share
儘量使用動態 library。

##
聯結數個 object 成可執行檔。
例:gcc test1.o test2.o -o test
將 'test1.o'、'test2.o' 和程式庫聯結後成為可執行檔 test。

=========== 最佳化參數 ================
## -O0
不作最佳化;然而若是之前有指定其它 LEVEL 的參數,將不會受到本參數的影響。

## -O1
初步最佳化,作最佳化的編譯當然會花費更多的時間和記憶體;未使用本參數前 GCC編譯的原則是減少編譯成本,而且各個階段的編連是各自獨立的--可以在任一階段停下來,重新指定變數內容,且各階段的結果和一般的狀況相同,完全符合正常的程序,然而本參數會以整體四個階段一起考慮,且本參數包含許多其它參數,目的就是要減少程式大小及執行時間;使用本參數同時會將-fthread-jumps和-fdelayed-branch開啟。

## -O2
更進一步最佳化,本參數可直接使用不需配合上一個參數,在本參數下除了「大小--速度」需犧牲一方的演算法外其於都會用來作最佳化處理,也就是除了 frame pointer elimination 和 loop unrolling 外其餘將會利用上;和上一個參數比起來本參數在編連時間和執行碼效能都更優越。

============================
接下來是許多和 CPU 構造有關的參數,它們的型態為 -fFLAG,大部份有相反詞,而相反詞為 FLAG 之前加上 no- 所形成。
============================
## -ffloat-store
"不要"將浮點變數儲存在暫存器中,而且抑制其它會改變從暫存器或記憶體所得浮點數之值的參數功能;本參數避免了一個現象,即浮點數的值無緣無故的加了好幾位小數出來,本來若將變數內容放在暫存器中,會比在記憶體中快上許多,這也是一般最佳化的方法之一,然而對許多主機例如 68000 來說其浮點暫存器所能容納的長度比 double 還長,這對一般程式來說無可厚非,然而對數值計算程式或是利 IEEE 浮點數的程式而言卻是"窩裡反"的行為,本參數就是避免這種情況發生。

## -fno-inline
忽略關鍵字inline的作用。

## -fno-default-inline
inline 這個關鍵字的作用是在呼叫此類函數的地方有著這個函數的程式碼存在,如此雖然程式變大了但執行速度也加快許多,當使用 -O 時物件中定義在 class 區域中的每一個成員函數都是以 inline 的型態處理,而本參數便是限定不要將這些成員函數視為 inline。

## -finline-functions
整合所有「簡單」的函數到呼叫它們的函數內,而「簡單」的標準由 GCC自行判斷;假如一個函數被整合到其它函數中,且其型態為 static,此函數當然不會有自己本身的輸出。

## -fkeep-inline-functions
本參數要和上一參數對照;縱然一 static 函數被整合到其它函數內,仍輸出執行時期可供呼叫的version。

## -fno-defer-pop
函數呼叫時其間傳入值和傳回值的傳遞是靠堆疊來完成的,一般情況下編譯程式會在堆疊之中累積一些argument後再一起 pop出去,這是為了速率著想,而本參數的作用便是不要作堆積,進一個便彈一個出去。

## -fforce-mem
強制 memory operands 在作運算前先 copy 到暫存器中以加快運算速度。

## -fforce-addr
強制 memory address 之內容在作運算前先 copy 到暫存器中以加快運算速度。本參數對於程式整體效率的提升比 -fforce-mem 還好,但這兩個參數並不適合任一機種。

## -fomit-frame-pointer
當函數用不到 frame pointer 時將它從暫存器中清除,本參數同時抑制了任何儲存、設定或回存frame pointer 的動作,這將使得更多的函數可利用暫存器以提升執行效率。

## -fno-function-cse
不要將函數所在位址放在暫存器中,這將使得每個呼叫函數的指令包含了函數位址,這會產生較沒效率的程式碼,但對於某些會改變 assembler 輸出的 hacks 來說,最佳化的過程會擾亂程式的行為,那時便需使用本參數。

## -ffast-math
本參數允許 GCC 違反某些 ANSI 或 IEEE 規則來作運算,這將使得執行速度加快,但對於運算程式等需依賴數值精密度作計算者則本參數不應和任何-O 參數共同使用,因為很有可能產生錯誤結果。

==============
前置處理器參數
==============
直觀來說前置處理器的作用為處理程式之中以 # 開頭的命令,這些命令於常見的有標頭檔的引入和定義常數及巨集等,可以說是在編譯之前的準備動作,有時也可用依某常數定義與否來決定那些程式片段是否要編譯,這對移植的工作有很大的助益,例如同樣要作到印出檔案名稱,在不同的 OS 和檔案格式上所得的結果就有蠻大的差異,在此就可分別寫不同的處理碼,然後再利用 #ifdef 等命令適機編連,不僅節省程式碼,還能加快速度;以下的參數,便是和前置處理時期有關者,而且許多參數需和 -E 配合使用。

## -include FILE
在編譯目標程式之前先編譯 FILE,而且 FILE 並無只能為標頭檔的限定,若是和 -D 及 -U 合併使用時以本參數為優先處理,當參數列中不只一個本參數及 -imacros 時依其順序執行。

## -imacros FILE
本參數和上一個參數幾乎相同,同樣都是在編譯目標程式之前先編譯 FILE ,所不同的是本參數會捨棄 FILE 的輸出,這使得FILE中唯有放置巨集定義才有作用。

## -idirafter DIR
將 DIR 內的路徑加至第二包含路徑中,當在主要包含路徑中找不到標頭檔時便可到第二來尋找,而主要包含路徑便是由 -I 所指定。

## -iprefix PREFIX
設定 PREFIX 之內容為 -iwithprefix 中之 prefix 預設值。

## -iwithprefix DIR
增加一個路徑到第二包含路徑中去,而這個路徑由 DIR 和 -iprefix 中的 PREFIX 之內容聯合組成。

## -iwithprefixbefore DIR
增加一個路徑到主要包含路徑中去,而這個路徑由 DIR 和 -iprefix 中的 PREFIX 之內容聯合組成。

## -nostdinc
不要在標準系統目錄下尋找標頭檔,只在目前目錄和 -I 所指定的目錄下尋找,因此這對於自行建立程式庫有幫助。

## -undef
不要預先定義任何非標準的巨集。相當於取消所有代碼中 #define。

## -E
作用為令 GCC 完成前置處理後便停止。展開程式中的巨集以便了解巨集是否依照預期方式展開,之後輸出到 stdout。
例:gcc -E test1.c > test1.c.ext

## -C
命令前置處理器不要捨棄註解部份,本參數需和 -E 共用。

## -P
命令前置處理器不要產生 #line 命令,本參數需和 -E 共用。

## -M
命令前置處理器輸出給 make 程式用的規則,內容為每個目的檔的依存規則,對於每個 source,前置處理器會將其 target 定為目的檔 (object),而其中所使用到的標頭檔便成為依存檔,有關本參數的最佳參考為 ~/linux下 Makefile 中 depend 這項依存規則的內容;另外一個如本參數功能的方法為設定環境變數 "DEPENDENICS_OUTPUT"。

## -MM
本參數唯一和 -M 不同之處在於輸出的規則中唯有使用者自定標頭檔(#include "FILE" 部份)才會列入,而系統標頭檔(#include 部份)並不會列入。

## -MD
作用如同-M一樣,然而在本參數會將規則輸出到和 .o 檔同檔名的 .d 檔中( -M 要用重新導向的方法),而 Mach utility 中的 "md" 可將各別的 .d 檔集合成可供 make 使用的依存檔。

## -MMD
為 -MM和 -MD功能的交集。

## -H
印出所使用的標頭檔。

## -DMARCO
定義巨集 MARCO 為字串 "1"; 相當於在代碼中加入 #define macro。

## -DMARCO=DEFN
定義巨集 MARCO 為 DEFN;相當於在代碼中加入 #define macro=value。此時所有的 -D 參數將比 -U 參數優先執行。

## -UMARCO
取消 MARCO的定義; 相當於在代碼中加入 #undef macro。此時 -U 還是比 -D 後執行,但卻在 -include 和 -imarcos 之前。

## -dM
命令前置處理器在前置處理完畢後列出所有有效的巨集名稱,本參數需和-E共用。

## -dD
命令前置處理器輸出所有的巨集定義內容。

## -dN
命令前置處理器輸出所有內定之外的巨集定義。

## -trigraphs
支援ANSI C trigraphs,本參數包含於 -ansi。

========
警告參數
警告是在編譯的過程中所發出的建議訊息,警告並非是錯誤,編譯後的程式仍可執行,不過警告的目的為指出某段可能會出錯的宣告方式語法,因此不可因不影響程式執行而掉以輕心;警告參數的目的為對某種語法提出(或抑制)警告訊息,以方便除錯或是順利執行,通常是以 -W 為開頭,這些參數的相反詞為加 no- 所形成,而不管是那種類型,都不是 GCC 的內定值。
========

## -fsyntax-only
只檢查程式之語法有無錯誤而不作編譯。

## -w
抑制所有警告訊息。

## -Wno-import
抑制所有和使用 #import 有關之警告訊息。

## -pedantic
依嚴格的 ANSI C 的標準發出警告訊息,並駁回任使用不允許擴充函數的程式。

## -pedantic-errors
作用如同 -pedantic,但除了警告外還會產生錯誤訊息。

## -W
對下列情況提出警告:
○一個 nonvolatile自動變數將被改成 longjmp  時,這種情況唯有作最佳化時才會發生。
○當一個函數可能有傳回值,也可能不傳回任何值時,例子如下:
foo (a)
{ if (a > 0) return a; }
○沒任何作用的 expression 敘述。
○一個 unsigned 數值和零比較大小時。
○如 'x<=y<=z'的表示式,此表示式 GCC會將其處理成 '(x<=y?1:0)<=z'以便程式能順利執行,當然這樣和原來想表現的意思差蠻多的。
○當 storage-class specifiers 如 'static' 並不是所有宣告中最先執行之時。

## -Wimplicit
當某函數或某參數 implicitly 宣告時提出警告。

## -Wreturn-type
當一函數內定傳回值為 int 時卻作別種型態的宣告便提出警告,或是當一函數無傳回值 (void),然而其中的 return 接一傳回值時便發出對 return 的警告。

## -Wunused
對某一 local 變數自宣告後便沒再使用、declare 一 static 函數後但未先 define、還有一段敘述算出一個結果,這個結果接下來卻未再使用等以上三種情況提出警告。

## -Wswitch
使用一列舉 (enum) 形態的變數為 switch 的 index 時,接下來卻缺少一個或以上的case作配合,或者是 case 的 label 超出了enum 中的選項時,便發出警告訊息,若是沒有必要列出每個 case 時可用default 代替。

## -Wcomment
當 '/* '符號 "又" 出現在註解中時。

## -Wformat
檢查 printf、scanf... 等函數其中第二個以後的參數型態是否和第一個字串中所寫有符合。

## -Wchar-subscripts
當陣列的註標 (subscript) 之型態為 char 時便發出警告,因為在某些主機上 char 為 signed。

## -Wuninitialized
當一自動變數未給予初值便使用時;如下的例子

 {
int x;
switch (y)
{
case 1: x = 1;
break;
case 2: x = 4;
break;
case 3: x = 5;
}
foo (x);
}

這個例子看起來沒錯,因為只要 y為 1、 2或 3則 x都會有初值,但 GCC 對於這樣的寫法並不夠聰明到能看出 x 會有初值這件事,因此對 foo(x) 而言其中的 x 就出問題了,然而當未使用最佳化編譯時並不會有本警告出現。

## -Wparentheses
當 parentheses 在以下這些敘述中省略時:當預期將為 true value 卻有 assignment 時,或是有令人頭昏眼花的 nest operators 時。

## -Wenum-clash
當兩個不同的 enum 型態作轉換時。(C++ only)

## -Wtemplate-debugging
若是在程式中使用了模版 (template) 但除錯功能未完全支援時。(C++ only)

## -Wall
本參數為以上所有 -W 參數的總集,且本參數為最推薦使用者,因為以上的情況便包含了一般情況下該警告的事項。

接下來的這些參數並不包含於 -Wall之中,這些參數所要警告的為一些結構上的問題。

## -Wtraditional
對傳統和 ANSI C 的一些結構上的差異提出警告:
○ switch 的 operand 型態為 long。
○函數在 block 中宣告為外部(external)而後在 block 結束後使用。
○巨集的參數是位於巨集本體的字串內容中,這種情況對傳統 C 是允許的,但對 ANSI C 會有不相容發生。

## -Wshadow
當一區域變數 shadow 另一區域變數時。

## -Wid-clash-LEN
當兩個以上的辨別字 (identifier) 在開頭和 LEN 相同時。

## -Wpointer-arith
當使用 size of 在函數時。

## -Werror
Make all warnings into errors.
將所有警告轉換成錯誤,這會讓編連停止。

2019年3 月 posted by admin in 程式&軟體 and have No Comments

Place your comment

Please fill your data and comment below.
名稱:
信箱:
網站:
您的評論: