-c
指定源代碼只編譯不鏈接.
如:
gcc -c -o a.o a.c
編譯成a.o目標工程文件.
-D
定義宏
gcc -DDIR = "/root" -o a a.c
-Idir
將目錄dir加入到頭文件搜尋的路徑中
-Ldir
將目錄dir加入到搜尋庫的目錄中
-llibhello.so
鏈接到libhello.so共享庫,注意這裏使用的是-l參數
-static
只鏈接靜態庫
-g,-ggdb
包含調試信息
-O
優化
-Wall
打開所有並且有用的警告信息.
下面是摘錄網絡上的:來源:http://blog.sina.com.cn/s/blog_4d6b1457010099ea.html
The History of GCC 生成特定格式的文件 以hello.c爲例子,可以設置選項生成hello.i, hello.s, hello.o以及最終的hello文件:
如果你不通過-o指定生成可執行文件名,那麼會默認生成a.out. 不指定生成文件名肯能覆蓋你上次生成的a.out. e.g. -c生成.o文件時,默認生成與源代碼的主幹同名的.o文件。比如對應hello.c生成hello.o. 但也可在生成目標文件時指定目標文件名(注意同時要給出.o後綴): $ gcc -c -o demo.o demo.c
GCC最初的全名是GNU C Compiler,之後,隨着GCC支持的語言越來越多,它的名稱變成了GNU Compiler Collection。
這裏介紹的gcc是GCC的前端,C編譯器.
警告信息
C語言標準
注意:後4個選項可以與-ansi結合使用,也可以單獨使用。
可在gcc中使用大量GNU C擴展.
$ gcc hello.c
在不給gcc傳遞任何參數的情況下, gcc執行默認的操作: 將源文件編譯爲目標文件--> 將目標文件連接爲可執行文件(名爲a.out) --> 刪除目標文件.
多文件編譯、連接
如果原文件分佈於多個文件中:file1.c, file2,c
若對其中一個文件作了修改,則可只重新編譯該文件,再連接所有文件:
注意:若編譯器在命令行中從左向右順序讀取.o文件,則它們的出現順序有限制:含有某函數定義的文件必須出現在含有調用該函數的文件之後。好在GCC無此限制。
編譯預處理
以上述的hello.c爲例, 要對它進行編譯預備處理, 有兩種方法: 在gcc中指定-E選項, 或直接調用cpp.gcc的編譯預處理命令程序爲cpp,比較新版本的gcc已經將cpp集成了,但仍提供了cpp命令. 可以直接調用cpp命令, 也可以在gcc中指定-E選項指定它只進行編譯預處理.
$ gcc -E hello.c
上述命令馬上將預處理結果顯示出來. 不利於觀看. 可採用-c將預處理結果保存:
$ gcc -E -c hello.i hello.c
注意, -c指定名稱要給出".i"後綴.
另外, gcc針對編譯預處理提供了一些選項:
(1) 除了直接在源代碼中用 #define NAME來定義宏外,gcc可在命令行中定義宏:-DNAME(其中NAME爲宏名),
e.g. $ gcc -Wall -DVALUE="2+2" tmp.c -o tmp
如果不顯示地賦值,如上例子,只給出:-DVALUE,gcc將使用默認值:1.
(2) 除了用戶定義的宏外, 有一些宏是編譯器自動定義的,它們以__開頭,運行: $ cpp -dM /dev/null, 可以看到這些宏. 注意, 其中含有不以__開頭的非ANSI宏,它們可以通過-ansi選項被禁止。
查看宏擴展
1, 運行 $ gcc -E test.c ,gcc對test.c進行編譯預處理,並立馬顯示結果. (不執行編譯) 2, 運行 $ gcc -c -save-temps test.c ,不光產生test.o,還產生test.i, test.s,前者是編譯預處理結果, 後者是彙編結果
針對含有編譯預處理命令的代碼,可以利用emacs方便地查看預處理結果,而不需執行編譯,更爲方便的是,可以只選取一段代碼,而非整個文件:
1,選擇想要查看的代碼
2,C-c C-e (M-x c-macro-expand)
這樣,就自動在一個名爲"Macroexpansion"的buffer中顯示pre-processed結果.
生成彙編代碼
使用"-S"選項指定gcc生成以".s"爲後綴的彙編代碼:
$ gcc -S hello.c
$ gcc -S -o hello.s hello.c
生成彙編語言的格式取決於目標平臺. 另外, 如果是多個.c文件, 那麼針對每一個.c文件生成一個.s文件.
調試
一般地,可執行文件中是不包含任何對源代碼的參考的,而debugger要工作,就要知道目標文件/可執行文件中的機器碼對應的源代碼的信息(如:哪條語 句、函數名、變量名...). debugger工作原理:將函數名、變量名,對它們的引用,將所有這些對象對應的代碼行號儲存到目標文件或可執行文件的符 號表中。
GCC提供-g選項,將調試信息加入到目標文件或可執行文件中。
$ gcc -Wall -g hello.c -o hello
注意:若發生了段錯誤,但沒有core dump,是由於系統禁止core文件的生成!
$ ulimit -c ,若顯示爲0,則系統禁止了core dump
解決方法:
$ ulimit -c unlimited (只對當前shell進程有效)
或在~/.bashrc 的最後加入: ulimit -c unlimited (一勞永逸)
優化
GCC具有優化代碼的功能,代碼的優化是一項比較複雜的工作,它可歸爲:源代碼級優化、速度與空間的權衡、執行代碼的調度。
GCC提供了下列優化選項:
一般來說,調試時不優化,一般的優化選項用-O2(gcc允許-g與-O2聯用,這也是GNU軟件包發佈的默認選項),embedded可以考慮-Os。
注意:此處爲O!(非0或小寫的o,-o是指定可執行文件名)。
檢驗優化結果的方法:$ time ./prog
time測量指定程序的執行時間,結果由三部分組成:
user和sys的和被稱爲CPU時間.
注意:對代碼的優化可能會引發警告信息,移出警告的辦法不是關閉優化,而是調整代碼。