標籤:gcc g++ linux 編譯器 c
gcc是Linux下常用的C/C++編譯磁碟機。本文首先介紹了gcc整個編譯串連過程,然後討論gcc常用的選項,最後說明了gcc與g++的關係。
gcc編譯串連過程
gcc編程串連過程如:
這裡的cpp是C預先處理程式(比如可以直接調用cpp hello.c -o hello.i把預先處理結果輸出到hello.i);cc是C編譯器,它將hello.i編譯成一個ASCII組合語言檔案hello.S;as是彙編編譯器,它將hello.S翻譯成一個可重位目標檔案hello.o;ld是串連程式,把所有的可重位目標檔案組合起來,產生一個可執行檔。也就說gcc是一個編譯驅動程式,它通過調用上面的程式(比如cpp,cc等)來產生可執行檔。我們可以使用gcc的選項產生這些中間檔案,方法如下:
gcc -E hello.c -o preprocess_hello.i執行這個命令後,preprocess_hello.i 儲存的就是預先處理後的C程式。
gcc -S hello.c -o assemble_hello.s執行這個命令後,assemble_hello.s儲存的就是對於程式的彙編代碼。相當於直接執行了預先處理和編譯兩步。
gcc -c hello.c -o object_hello.o執行這個命令後,object_hello.o儲存的就是對於程式的機器代碼,還不能執行,因為還沒有串連。想當與一次執行了前面三步。
我們可以使用選項-save-temps在產生可執行檔時保留所有的中間檔案。比如gcc -save-temps -o hello hello.c可以保留中間檔案,即一次性會組建檔案hello.i,hello.o,hello.s和可執行檔hello。
gcc的常用選項
gcc可以使用gcc --help命令查看選項,gcc的選項用法,可以概括如下:
常用的選項概括如下:
下面對這些常用選項簡單說明:
-x用於指定的程式的語言,如果用改選項,gcc就不再使用檔案的尾碼判斷語言類型。
-v選項可以輸出gcc整個編譯串連過程的輸出資訊,包括尋找路徑等資訊。比如gcc -v hello.c(當然可以用gcc -v hello.c >& temp輸出檔案),除了產生a.out可執行檔外,還會輸出大量額外資訊,比如#include "..."和#include <...> 的搜尋路徑,LIBRARY_PATH(串連程式將在這些目錄中尋找特殊的串連檔案)的值。
-D選項可以用來預定義宏,比如在命令列定義宏:gcc -Dmacro hello.c這個等同於在檔案的開頭定義宏,即#define maco,但是在命令列定義更靈活。例如,在原始碼中有這些語句。
#ifdef DEBUG printf("this code is for debugging\n"); #endif
如果編譯時間加上-DDEBUG選項,那麼編譯器就會把printf所在的行編譯進目標代碼,從而方便地跟蹤該位置的某些程式狀態。這樣-DDEBUG就可以當作一個調試開關,編譯時間加上它就可以用來列印調試資訊,發布時則可以通過去掉該編譯選項把調試資訊去掉。並且還可以定義值,比如gcc -DDEBUG=42 hello.c,這樣在代碼使用這個值,比如printf("this code is for debugging,%d\n",DEBUG);預設預定義的值為1。
-Wall會開啟有用的警告選項,檢測編譯的是加此選項。
gcc預設的選項-o是不最佳化的,使用-O2,-Os可根據不同的運行平台分別對代碼的執行速度和大小進行最佳化。
-std=c99 指明使用標準 ISO C99 作為標準來編譯器。比如gcc -std=c99 hello.c。
-Xlinker可用於靜態庫連結順序問題。若gcc選項中有多個路徑時,都是按指定路徑的搜尋順序。
gcc與g++的關係
gcc和g++都是GNU的一個編譯磁碟機,但兩者有一些區別:
尾碼為.c的檔案gcc把它當做c程式,g++當做c++程式,尾碼為c++的兩者都當做c++程式(即此時gcc也相當於預定義了宏__cplusplus)。對於cpp程式,無論gcc或者是g++編譯階段都是相同的,都是用的gcc進行編譯,但是在連結階段gcc不能自動和c++程式常使用庫串連,而g++會自動連接這些庫。比如用g++編譯:g++ hello.cpp -o cpphello,而用gcc編譯需要串連C++常用的標準庫:gcc hello.cpp -lstdc++ -o cpphello,注意產生的可執行檔並不是完全相同的。
參考資料
http://wangcong.org/articles/learning-gcc.cn.html
http://www.yolinux.com/cgi-bin/man2html?cgi_command=gcc