在Linux 下面,如果要編譯一個(gè)C 語(yǔ)言源程序,我們要使用GNU 的gcc 編譯器。下面
我們以一個(gè)實(shí)例來(lái)說(shuō)明如何使用gcc 編譯器。假設(shè)我們有下面一個(gè)非常簡(jiǎn)單的源程序
(hello.c):
int main(int argc,char **argv)
{
printf("Hello Linux\n");
}
要編譯這個(gè)程序,我們只要在命令行下執(zhí)行:
gcc -o hello hello.c
下面就詳細(xì)說(shuō)一下gcc的編譯過(guò)程
gcc由C語(yǔ)言源代碼文件生成可執(zhí)行文件的過(guò)程,一般來(lái)說(shuō)分為四個(gè)階段:預(yù)處理(也稱預(yù)編譯Preprocessing)、編譯(compilation)、匯編(Assembly)和鏈接(linking)。這四個(gè)階段分別由gcc調(diào)用不同的程序來(lái)實(shí)現(xiàn)。
- 預(yù)處理是調(diào)用cpp程序來(lái)實(shí)現(xiàn)的,預(yù)處理主要是對(duì)包含語(yǔ)句、宏定義等進(jìn)行處理。
- 編譯是調(diào)用cc來(lái)實(shí)現(xiàn)的,它是源文件變?yōu)楹缶Y為.o的目標(biāo)文件的過(guò)程。
- 匯編過(guò)程是對(duì)匯編語(yǔ)言的操作,通過(guò)調(diào)用as來(lái)實(shí)現(xiàn),匯編同樣也生成目標(biāo)文件。
- 鏈接是通過(guò)用ld來(lái)實(shí)現(xiàn)的。這是最為關(guān)鍵的步驟,在該階段,ld會(huì)將各程序的執(zhí)行代碼放置在程序的適合位置,同時(shí),程序調(diào)用的庫(kù)函數(shù)也會(huì)以適當(dāng)?shù)姆椒ㄔO(shè)置調(diào)用接口。
gcc編譯時(shí),如果在命令行沒有指定其他參數(shù),則gcc會(huì)完成編譯、鏈接的過(guò)程,然后在當(dāng)前目錄中生成一個(gè)名為a.out的可執(zhí)行文件。一般來(lái)說(shuō),linux并不依賴文件的后綴來(lái)識(shí)別文件是否為可執(zhí)行程序,其判斷文件是否可執(zhí)行依據(jù)的是文件的屬性。如果對(duì)于當(dāng)前用戶而言,文件有運(yùn)行權(quán)限,則該文件為一個(gè)可執(zhí)行程序。
對(duì)于gcc而言,判斷文件的類型主要是依據(jù)文件的后綴名。所以,要使用gcc編譯代碼,正確使用文件后綴是保證編譯正確的前提。如果寫了一個(gè)C++代碼,卻使用了.c為后綴,gcc在編譯該文件時(shí)會(huì)將該文件按照C語(yǔ)言代碼來(lái)處理,一般會(huì)出錯(cuò)。
一些gcc常用的文件后綴名:
- c: C語(yǔ)言源代碼文件
- a:由目標(biāo)文件構(gòu)成的檔案庫(kù)文件
- .C、.cc 或.cxx:c++源代碼文件
- h:頭文件
- i:經(jīng)過(guò)預(yù)處理的C源代碼文件
- ii:經(jīng)過(guò)預(yù)處理的C++源代碼文件
- m:Objective-C源代碼文件
- o:編譯后的目標(biāo)文件
- s:匯編語(yǔ)言源代碼文件
- S:經(jīng)過(guò)預(yù)編譯的匯編語(yǔ)言源代碼文件
gcc hello.c編譯通過(guò)后,就可以簡(jiǎn)單的使用a.out調(diào)用該程序,使用命令如下:./a.out - 注意:這里不能直接使用a.out來(lái)調(diào)用該程序,因?yàn)閟hell在尋找可執(zhí)行程序時(shí),并不在當(dāng)前目錄中尋找,所以必須用“./”來(lái)顯示指定該文件的路徑是當(dāng)前目錄