Linux系統下的gcc(GNU C Compiler)是GNU推出的功能強大,性能優越的多平台編譯器,是GNU的代表作之一。gcc可以在多個硬體平台上編譯出可執行的程式,其執行效率與一般的編譯器相比,效率要高20%~30%。
GCC編譯器能将C,C++語言源程式,彙程式設計式編譯,連結成可以執行檔案,在Linux系統中,可執行檔案沒有統一的字尾,系統從檔案的屬性來區分可執行檔案和不可執行檔案。使用GCC編譯程式時,編譯過程可以被細分為四個階段:
(1)預編譯(Pre-Processing)
(2)編譯(Compiling)
(3)彙編(Assembling)
(4)連結(Linking)
GCC通過字尾來區分輸入檔案的類别:
.c為字尾的檔案:C語言源代碼檔案
.a為字尾的檔案:由目标檔案構成的庫檔案
.C , .cc或.cxx為字尾的檔案:是C++源代碼檔案
.h為字尾的檔案:頭檔案
.i為字尾的檔案:是已經預處理過的C源代碼檔案
.ii為字尾的檔案:是已經預處理過的C++源代碼檔案
.o為字尾的檔案:是編譯後的目标檔案
.s為字尾的檔案:是彙編語言源代碼檔案
.S為字尾的檔案:是經過預編譯的彙編語言源代碼檔案
gcc的基本用法是:gcc [options][filenames]
options:編譯器所需要的編譯選項
filenames:要編譯的檔案名
簡單的程式示範:
編譯和運作這段程式:
gcc編譯選項(option)大約有100多個,其中多數我們不會用到,這裡隻是介紹其中最基本,最常用的參數。
(1)-o output_filename: 确定可執行檔案的名稱為output_filename。如果不給出這個選項,gcc就給出預設的可執行檔案a.out。
(2)-c:隻編譯,不連接配接成為可執行檔案,編譯器隻是由輸入的.c等源代碼檔案生成.o為字尾的目标檔案。
(3)-g:産生調試工具(GNU的gdb)所必要的符号資訊,要想對編譯出的程式進行調試,就必須加入這個選項。
(4)-O:對程式進行優化編譯,連結,采用這個選項整個源代碼會在編譯連結過程中優化處理,這樣産生的可執行檔案的執行效率會提高,但是編譯連結的速度就相應的慢些。
同一個程式,上面沒有優化,下面優化過,編譯時間差别很大
(5)-O2:比-O更好的優化編譯連結,編譯連結過程會更慢
(6)-Idirname:将dirname所指出的目錄加入到程式頭檔案目錄清單中。例如:gcc –I/home/part hello.c
C程式中的頭檔案包含兩種情況:
1. #include <A.h>
2.#include “B.h”
對于<>, 預處理程式cpp在系統預設的頭檔案目錄(如/usr/include)中搜尋相應的檔案,而對于””,cpp在目前目錄中搜尋檔案。這個選項的作用是告訴cpp,如果在目前目錄中沒有找到需要的檔案,就到指定的dirname目錄中去尋找。
(7)-Ldirname: 将dirname所指出的目錄加入到庫檔案的目錄清單中,在預設狀态下,連接配接程式Id在系統的預設路徑中(如/usr/lib)尋找所需要的庫檔案,這個選項告訴連接配接程式,首先到-L指定的目錄中去尋找,然後再到系統預設路徑中尋找。
(8)-lname: 在連接配接時,裝載名字為”libname.a”的函數庫,該函數庫位于系統預設的目錄或者由-L選項确定的目錄下。例如,-lm表示連接配接名為”libm.a”的數學函數庫。
例: gcc foo.c -L /home/lib -lfoo -o foo
(9)-static: 靜态連結庫檔案,例:gcc –static hello.c –o hello
庫有動态與靜态兩種,動态通常用.so為字尾,靜态通常用.a為字尾。例如:libhello.so libhello.a 。當使用靜态庫時,連接配接器找出程式所需的函數,然後将它們拷貝到可執行檔案,一旦連接配接成功,靜态程式庫也就不再需要了。然而對于動态庫而言,就不是這樣,動态庫會在執行程式内留下一個标記,指明當程式執行時,首先必須載入這個庫。由于動态庫節省空間,linux下進行連接配接的預設操作是首先連接配接動态庫。
(10)-Wall: 生成所有的警告資訊
(11)-w: 不生成任何警告資訊
(12)-DMACRO: 定義MACRO宏,等效于在程式中使用#define MACRO