主要產品系列 |
GCC是GNU項目的編譯器組件之一,也是GNU最具有代表性的作品。在GCC設計之初僅僅作為一個C語言的編譯器,可是經過十多年的發展,GCC已經不僅僅能支持C語言;它現在還支持Ada語言、C++語言、Java語言、Objective C語言,Pascal語言、COBOL語言,以及支持函數式編程和邏輯編程的Mercury語言,等等。而GCC也不再單是GNU C Compiler的意思,而是GNU Compiler Collection也即是GNU編譯器家族的意思了,目前已經成為Linux下最重要的編譯工具之一。
GCC是一個交叉平臺的編譯器,目前支持幾乎所有主流CPU處理器平臺,它可以完成從C、C++、Objective C等源文件向運行在特定cpu硬件上的目標代碼的轉換,GCC不僅功能非常強大,結構也異常靈活,便攜性(protable)與跨平臺支持(cross-plantform. support)特性是GCC的顯著優點,目前編譯器所能支持的源程序的格式如下表所示。
后綴格式 | 說明 |
.c | C語言程序 |
.a | 由目標文件構成的檔案文件 |
.C、cc、cxx | C++源程序 |
.h | 源程序所包含的頭文件 |
.i | 經過預處理的C程序 |
.ii | 經過預處理的C++程序 |
.m | Objective-C源程序 |
.o | 編譯后的目標文件 |
.s | 匯編語言源程序 |
.S | 經過預編譯的匯編程序 |
GCC是一組編譯工具的總稱,其軟件包里包含眾多的工具,按其類型,主要有以下的分類。
C編譯器cc,cc1,cc1 plus,gcc
C++編譯器c++,cc1 plus,g++
源代碼預處理程序cpp,cpp0
庫文件libgcc.a, libgcc_eh.a,libgcc_s.so,libiberty.a,libstdc++.[a,so],libsupc++.a
用GCC編譯程序生成可執行文件有時候看起來似乎僅通過編譯一步就完成了,但事實上,使用GCC編譯工具由C語言源程序生成可執行文件的過程并不單單是一個編譯的過程,而要經過下面的幾個過程。
在實際編譯的時候,GCC首先調用cpp命令進行預處理,主要實現對源代碼編譯前的預處理,比如將源代碼中指定的頭文件包含進來。接著調用cc1命令進行編譯,作為整個編譯過程的一個中間步驟,該過程會將源代碼翻譯生成匯編代碼。匯編過程是針對匯編語言的步驟,調用as命令進行工作,生成擴展名為.o的目標文件,當所有的目標文件都生成之后,GCC就調用連接器ld來完成最后的關鍵性工作——鏈接。
GCC是Linux下基于命令行的C語言編譯器,其基本的使用語法如下。
gcc [option |filename]…
對于編譯C++的源程序,其基本語法如下:
g++ [option |filename]…
其中option為GCC使用時的選項,而filename為需要GCC做編譯的處理的的文件名。就GCC來說,其本身是一個十分復雜的的命令,合理的使用其命令選項可以有效地提高程序的編譯效率、優化代碼,GCC擁有眾多的命令選項,有超過100個的編譯選項可用,按其應有如下的分類。
例如下面的指令:
# gcc -x c++ p1.c
該指令表示強制采用C++編譯器來編譯C程序P1.c。
-I<DIR>選項:庫依賴選項,指定庫及頭文件路徑。
在Linux下開發程序的時候,統常來講都需要借助一個或多個函數庫的支持才能夠完成相應的功能。一般情況下,Linux下的大多數函數都將頭文件放到系統/usr/include目錄下,而庫文件則放到/usr/lib目錄下。但在有些情況下并不是這樣的,在這些情況下,使用GCC編譯時必須指定所需要的頭文件和庫文件所在的路徑。-I選項可以向GCC的頭文件搜索路徑中添加新的目錄<DIR>。例如,一個源程序所依賴的頭文件在用戶/home/include/目錄下,此時就應該使用-I選項來指定。
# gcc –I /home/include -o test test.c
-L<DIR>:類似于上面的情況,用來特別指定所依賴庫所在的路徑
如果使用不在標準位置的庫,那么可以通過-L選項向GCC的庫文件搜索路徑中添加新的目錄。例如,一個程序要用到的庫libapp.so在/home/zxq/lib/目錄下,為了能讓GCC能夠順利地鏈接該庫,可以使用下面的指令:
# gcc -Test.c -L /home/zxq/lib/ -lapp –o Test
這里的-L選項表示GCC去鏈接庫文件libapp.so。在Linux下的庫文件在命名時遵循了一個約定,那就是應該以lib三個字母開頭,由于所有的庫文件都遵循了同樣的規范,因此在使用-L選項指定鏈接的庫文件名時可以省去lib三個字母,也就是說GCC在對-lapp進行處理的時候,會自動去鏈接名為libapp.so的文件
-static選項:GCC在默認情況下鏈接的是動態庫,有時為了把一些函數靜態編譯到程序中,而無需鏈接動態庫就采用-static選項,它會強制程序連接靜態庫。
-o選項:在默認的狀態下,如果GCC指令沒有指定編譯選項的情況下會在當前目錄下生成一個名為a.out的可執行程序,例如:執行# gcc Test.c命令后會生成一個名為a.out的可執行程序。因此,為了指定生成的可執行程序的文件名,就可以采用-o選項,比如下名的指令:
# gcc –o Test Test.c
執行該指令會在當前目錄下生成一個名為Test的可執行文件。
GCC編譯器包含完整的出錯檢查和警告提示功能,比如GCC提供了30多條警示信息和3個警告級別,使用這些選項有助于增強程序的穩定性和更加完善程序代碼的設計,此類選項常用的如下。
-pedantic以ANSI/ISO C標準列出的所有警告
當GCC在編譯不符合ANSI/ISO C語言標準的源代碼時,如果在編譯指令中加上了-pedantic選項,那么源程序中使用了擴展語法的地方將產生相應的警告信息。
-w禁止輸出警告信息
-Werror將所有警告轉換為錯誤
Werror選項要求GCC將所有的警告當成錯誤進行處理,這在使用自動編譯工具(如Make等)時非常有用。如果編譯時帶上-Werror選項,那么GCC會在所有產生警告的地方停止編譯,只有程序員對源代碼進行修改并起相應的警告信息消除時,才能夠繼續完成后續的編譯工作。
-Wall顯示所有的警告信息
-Wall選項可以打開所有類型的語法警告,以便于確定程序源代碼是否是正確的,并且盡可能實現可移植性。
對Linux開發人員來講,GCC給出的警告信息是很有價值的,它們不僅可以幫助程序員寫出更加健壯的程序,而且還是跟蹤和調試程序的有力工具。建議在用GCC編譯源代碼時始終帶上-Wall選項,養成良好的習慣。
-O選項:編譯時使用選項-O可以告訴GCC同時減小代碼的長度和執行時間,其效果等價于-O1。
-O2選項:選項-O2告訴GCC除了完成所有-O1級別的優化之外,同時還要進行一些額外的調整工作,如處理器指令調度
-g選項:生成調試信息,GNU調試器可以利用該信息。GCC編譯器使用該選項進行編譯時,將調試信息加入到目標文件中,這樣gdb調試器就可以根據這些調試信息來跟中程序的執行狀態。
-pg選項:編譯完成后,額外產生一個性能分析所需信息。
注意:使用調試選項都會使最終生成的二進制文件的大小急劇增加,同時增加程序在執行時的開銷,因此調試選項統常推薦僅僅在程序開發和調試階段中使用。
下面舉一個簡單的例子來說明GCC的編譯過程。首先用vi編輯器來編輯一個簡單的c程序test.c,程序清單如下。
根據上面的內容,使用gcc命令來編譯該程序。
可以從上面的編譯過程看到,編譯一個這樣的程序非常簡單,一條指令即可完成,事實上,這條指令掩蓋了很多細節。我們可以從編譯器的角度來看上述編譯過程,這對于更好理解GCC編譯工作原理有很好的幫助。
GCC編譯器首先做的工作是預處理:調用-E參數可以讓GCC在預處理結束后停止編譯過程。
# gcc –E test.c -o test.i
編譯器在這一步調用cpp工具來對源程序進行預處理,此時會生成test.i文件,下面部分列出了test.i文件中的內容。
聲明:本站部分內容根據互聯網資料整理而成,若侵犯您的權益,請聯系我們,我們會盡快處理。