GCC,全稱GNU Compiler Collection,是一套GNU開發的編譯器環境,它的創始人便是大名鼎鼎的Richard.M.Stallman。最初GCC剛開始開發時,它還叫做GNU C Compiler,隨著開發的深入,GCC很快得到了擴展,不僅可以支持C語言,還可以處理C++,Pascal,Object-C,Java以及Ada等其他語言。目前,GCC不僅是GNU的官方編譯器,也成為編譯和創建其他操作系統的編譯器,包括BSD家族以及MAC OS X等。另外,GCC也是跨平臺交叉編譯的首選,它不僅支持Intel的x86系列,同時也支持MIPS,ARM,PowerPC,SPARC等等處理器。可以這么說,即使GCC不是世界上效率最高的編譯器,它也一定是世界上最全面的編譯器。

1. GCC簡介
我們先回到一個常識性的問題,什么是編譯器呢?簡單地說,編譯器可以看作是一個語言翻譯器。就像把中文翻譯成英語一樣,編譯器可以把高級語言翻譯成計算機能夠執行的機器語言。這樣看來,GCC可以算得上是一個精通多國語言的高級翻譯官了。
最簡單的GCC使用指令如下所示:
gcc hello.c -o hello
GCC接受hello.c作為輸入,最后產生目標可執行代碼hello。這個簡單的流程實際上經歷了很多步驟,如下圖所示:
雖然我們只用了一條命令就完成了編譯,但實際上gcc命令依次呼叫了cpp,gcc自己,gas以及ld來進行完整的編譯流程,最后生成最終的可執行文件hello。
下面我們看一下分解動作:
cpp hello.c > hello.i
gcc -S hello.i
as hello.s -o hello.o
ld -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/gcc/i686-linux-gnu/4.4.5/crtbegin.o -L/usr/lib/gcc/i686-linux-gnu/4.4.5 hello.o -lgcc -lgcc_eh -lc /usr/lib/gcc/i686-linux-gnu/4.4.5/crtend.o /usr/lib/crtn.o -o hello
看完這些步驟有沒有暈頭轉向的感覺呢?對于普通的用戶來說,還是讓GCC幫我們做這些事情比較好。
對于如何學習使用GCC,可以參考GCC官方的手冊,如果大家覺得官方的手冊太羅嗦,我這里推薦一本GCC的入門書籍《
An Introduction to GCC》,這本書詳盡的介紹了GCC的使用方法,內容淺顯易懂,很適合初學者。
2. GCC強大的背后
學過編譯原理這門課程的同學對下面這副圖應該很熟悉,這是經典的編譯流程。

GCC作為經典的編譯器,自然也是遵循這個教科書流程(實際GCC的處理更復雜點,但本質上是一樣的)。我們先簡化一下上面這幅圖,以中間代碼為分界,前面的詞法分析、語法分析、語義分析我們把它稱之為前端處理,后面的優化和目標代碼生成我們稱之為后端處理。
試想一下,是否可以為不同的高級語言單獨寫一個前端,然后為不同的處理器架構單獨寫一個后端呢?

GCC基本上也是這么實現的,不過不要誤會,并沒有一個統一的gcc執行程序能夠處理如此多的前端和后端,每個語言的編譯器都是一個獨立的程序(如C語言的編譯器是gcc,C++的編譯器是g++),而不同的后端也要對應不同的可執行程序。你可以下載單獨的一份GCC源代碼,通過不同的configure來編譯自己需要的編譯器。
而且,編譯器的實現也比上圖要復雜的多,前端的主要功能是產生一個可供后端處理的語法樹,而語法樹結構實際上很難與處理器架構脫鉤,這些都是編譯器應用中需要解決的問題。
GCC強大的真正原因是什么?是因為它支持了眾多的前端和后端嗎?這些都不過是一個表象而已。GCC是一款真正自由的編譯器,我們可以隨時把代碼拿過來修改以實現自己需要的功能。如果你的硬件平臺增加了一些指令,而普通的編譯器并不能產生這些指令怎么辦?在GCC后端添加這些指令吧。如果你覺得C語言用的不太順手,想給它添加一些功能怎么辦?修改GCC的前端吧。因為有了GCC,我們才擁有這些自由,以及迅速實現自己想法的能力,而這些才是GCC強大背后的基礎。
2010年1月份的時候,Google的Go語言前端被允許進入GCC編譯器家族,GCC更加強大了。
3. GCC的多樣性
GCC因為其靈活性被應用到了很多領域和系統,從PC上的開發到嵌入式開發,都可以見到GCC的影子。
3.1 PC開發
我們先看看PC。MAC自從投入Intel的懷抱,是否也可以看作是一種PC呢?
Linux
Linux系統應該是GCC的主戰場,但也是最沒必要去說的一個系統,除了GCC,難道我們還有更好的選擇嗎?Linux內核、Apache服務器、MySQL數據庫,等等一系列偉大的作品都是通過GCC來構建的,GCC可以說是GNU/Linux系統的基石。
MAC OS X
MAC OS X也是GCC的重度用戶,其應用程序開發環境Cocoa就是使用的GCC,所以在MAC OS X下開發也是離不開GCC的。
Windows
現在在Windows下開發C/C++程序一般都是用微軟的編譯器,當年的Borland已經成為傳說。但是如果你不想付錢的話,也可以考慮Windows下的GCC。
在Windows下體驗GCC最常用的有兩種方式:一是在Cygwin下使用GCC,另外一種是使用MinGW。
Cygwin是一個自由軟件的集合,最初由Cygnus Solutions開發,目的是在Windows系統上運行類Unix的軟件。通過Cygwin編譯的程序可以在Windows上運行,但必須使用cygwin.dll。
MinGW(Minimalist GNU for Windows),是將GNU開發工具移植到Windows平臺的產物,包括一系列頭文件、庫和可執行文件,用MinGW開發的程序不需要額外的第三方DLL就可以直接在Windows上運行。Nokia的圖形開發包QT在Windows下就是調用MinGW來編譯的。
DOS
在DOS系統下也是可以用GCC的,國內的DOS開發者可能更熟悉Turbo C或者Open Watcom,GCC的DOS版本
DJGPP其實也是32位DOS程序開發的主流環境之一。最初DJGPP的發起人DJ Delorie曾經詢問過Richard Stallman,FSF是否考慮過把GCC移植到MS-DOS下,當時Richard的回答是GCC太龐大,而MS-DOS只不過是個16位的操作系統,所以官方并沒有考慮這件事。DJ Delorie并沒有因此而退縮,最終給我們帶來了這個優秀的開發平臺。DJGPP剛開始開發時叫做djgcc,在引入了C++之后改為現在這個名字(DJ's GNU Programming Platform)。
3.2 嵌入式開發
對于嵌入式開發領域來說,因為開發板的能力限制,是無法運行編譯環境的,這樣就需要在PC上通過交叉編譯來生成目標可執行程序,GCC的高度靈活性在嵌入式開發上發揮了極大的作用。
Android
看看當今最火的移動平臺Android,就是完全用GCC來構建的,請注意,這里指的不是Android應用程序,Android下的應用程序是運行在Dalvik虛擬機上的Java程序。
iOS
Apple的iOS應用程序開發也是用Cocoa來進行,這怎么會離開GCC呢?
MeeGo/Symbian
在Apple和Google的沖擊下,Nokia似乎已經日薄西山了,但對于中國國情來說,真的是這樣嗎?iPhone高高在上,擁有者只會是少數,Google退出中國之后,Android Market很難在國內有所作為,再加上Nokia手機一貫皮實的口碑,現在的Symbian以及將來的MeeGo的保有量應該不會低。Nokia已經把Symbian和MeeGo的開發環境統一到QT上了,這里依然是GCC的一畝三分田。
GCC是強大的,但它并不是一個人在戰斗,在它的背后站著
GNU工具鏈,包括make,GCC,Binutils,GDB等一系列工具,這些工具之間是相輔相成的,只有把它們組合起來使用才能發揮其最大的威力。