gcc (GNU編譯器套件)

GNU編譯器套件(GNU Compiler Collection)包括 CC++Objective-CFortranJavaAdaGo語言的前端,也包括了這些語言的庫(如libstdc++、libgcj等等)。GCC的初衷是爲GNU操做系統專門編寫的一款編譯器。GNU系統是完全的 自由軟件。此處,「自由」的含義是它尊重用戶的自由。 [1]  
軟件名稱GNU Compiler Collection開發商Free Software Foundation (FSF)軟件平臺類Unix操做系統軟件語言多國語言軟件受權GNU通用公共許可證(GNU GPL)

創做背景 編輯

GCC(GNU Compiler Collection,GNU編譯器套件),是由 GNU 開發的編程語言編譯器。它是以 GPL許可證所發行的自由軟件,也是 GNU計劃的關鍵部分。GCC本來做爲GNU操做系統的官方編譯器,現已被大多數類 Unix操做系統(如 LinuxBSDMac OS X等)採納爲標準的 編譯器,GCC一樣適用於微軟的 Windows[2]   GCC是自由軟件過程發展中的著名例子,由自由軟件基金會以 GPL協議發佈。
GCC 原名爲 GNU C 語言編譯器(GNU C Compiler),由於它本來只能處理 C語言。GCC 很快地擴展,變得可處理 C++。後來又擴展可以支持更多編程語言,如 FortranPascalObjective-CJavaAdaGo以及各種 處理器架構上的 彙編語言等,因此更名GNU編譯器套件(GNU Compiler Collection)。 [2]  

結構 編輯

GCC的外部接口長得像一個標準的Unix 編譯器。使用者在命令列下鍵入gcc之程序名,以及一些命令參數,以便決定每一個輸入檔案使用的個別語言編譯器,併爲輸出程序碼使用適合此硬件平臺的組合語言編譯器,而且選擇性地執行鏈接器以製造可執行的程序。
每一個語言編譯器都是獨立程序,此程序可處理輸入的原始碼,並輸出組合語言碼。所有的語言編譯器都擁有共通的中介架構:一個前端解析符合此語言的原始碼,併產生一 抽象語法樹,以及一翻譯此語法樹成爲GCC的 暫存器轉換語言〈RTL〉的後端。編譯器最佳化與靜態程序碼解析技術(例如FORTIFY_SOURCE,一個試圖發現 緩衝區溢位〈buffer overflow〉的編譯器)在此階段應用於程序碼上。最後,適用於此硬件架構的組合語言程序碼以Jack Davidson與Chris Fraser發明的算法產出。
幾乎所有的GCC都由C寫成,除了Ada前端大部分以Ada寫成。

前端接口

前端的功能在於產生一個可以讓後端處理之語法樹。此語法解析器是手寫之 遞歸語法解析器。
直到2004年,程序的語法樹結構尚沒法與欲產出的處理器架構脫鉤。而語法樹的規則有時在不一樣的語言前端也不同,有些前端會提供它們特別的語法樹規則。
在2005年,兩種與語言脫鉤的新型態語法樹歸入GCC中。它們稱爲GENERIC與GIMPLE。語法解析變成產生與語言相關的暫時 語法樹, 再將它們轉成GENERIC。以後再使用"gimplifier"技術下降GENERIC的複雜結構,成爲一較簡單的靜態惟一形式(Static Single Assignment form,SSA)基礎的GIMPLE形式。此形式是一個與語言和處理器架構脫鉤的全域最佳化通用語言,適用於大多數的現代編程語言。

中介接口

通常 編譯器做者會將語法樹的最佳化放在前端,但其實此步驟並不看語言的種類而有不一樣,且不須要用到語法解析器。所以GCC做者們將此步驟納入通稱爲中介階段的部分裏。此類的最佳化包括消解死碼、消解重複運算與全域數值重編碼等。許多最佳化技巧也正在實做中。

後端接口

GCC後端的行爲因不一樣的前處理器 和特定架構的功能而不一樣,例如不一樣的字符尺寸、呼叫方式與大小尾序等。後端接口的前半部利用這些訊息決定其RTL的生成形式,所以雖然GCC的RTL理論上不受 處理器影響,但在此階段其抽象指令已被轉換成目標架構的格式。
GCC的最佳化技巧依其釋出版本而有很大不一樣,但都包含了標準的最佳化算法,例如循環最佳化、執行緒跳躍、共通程序子句消減、指令排程等等。而RTL的最佳化因爲可用的情形較少,且缺少較高階的資訊,所以相比較起來,增長的GIMPLE語法樹形式,便顯得比較不重要。
後端經由一次重讀取步驟後,利用描述目標處理器的 指令集時所取得的信息,將抽象 暫存器替換成 處理器的真實暫存器。此階段很是複雜,由於它必須關注全部GCC可移植平臺的處理器指令集的規格與技術細節。
後端的最後步驟至關公式化,僅僅將前一階段獲得的 彙編語言代碼藉由簡單的 子例程轉換其暫存器與內存位置成相對應的 機器碼

基本用法 編輯

在使用GCC 編譯器的時候,咱們必須給出一系列必要的調用參數和文件名稱。GCC編譯器的調用參數大約有100多個,這裏只介紹其中最基本、最經常使用的參數。具體可參考GCC Manual。
GCC最基本的用法是∶gcc [options] [filenames]
其中options就是編譯器所須要的參數,filenames給出相關的文件名稱。
-c,只 編譯,不連接成爲 可執行文件,編譯器只是由輸入的.c等 源代碼文件生成.o爲後綴的目標文件,一般用於編譯不包含主程序的 子程序文件。
-o output_filename,肯定輸出文件的名稱爲output_filename,同時這個名稱不能和源文件同名。若是不給出這個選項,gcc就給出預設的可執行文件a.out。
-g,產生符號調試工具(GNU的gdb)所必要的符號資訊,要想對源代碼進行調試,咱們就必須加入這個選項。
-O,對程序進行優化 編譯、連接,採用這個選項,整個 源代碼會在編譯、連接過程當中進行優化處理,這樣產生的 可執行文件的執行效率能夠提升,可是,編譯、連接的速度就相應地要慢一些。
-O2,比-O更好的優化編譯、連接,固然整個編譯、連接過程會更慢。
-Idirname,將dirname所指出的目錄加入到程序頭文件目錄列表中,是在 預編譯過程當中使用的參數。C程序中的頭文件包含兩種狀況∶
A)#include <myinc.h>
B)#include 「myinc.h」
其中,A類使用尖括號(< >),B類使用雙引號(「 」)。對於A類, 預處理程序cpp在系統預設包含 文件目錄(如/usr/include)中搜尋相應的文件,而B類,預處理程序在 目標文件的文件夾內搜索相應文件。
-v gcc執行時執行的詳細過程,gcc及其相關程序的版本號
原版gcc manual該選項英文解釋
Print (on standard error output) the commands executed to run the stages of compilation. Also print the version number of the compiler driver program and of the preprocessor and the compiler proper.
編譯程序時加上該選項能夠看到gcc搜索頭文件/庫文件時使用的搜索路徑!

基本規則 編輯

gcc所遵循的部分約定規則:
.c爲後綴的文件,C語言 源代碼文件;
.a爲後綴的文件,是由 目標文件構成的檔案庫文件;
.C,.cc或.cxx 爲後綴的文件,是C++源代碼文件且必需要通過 預處理
.h爲後綴的文件,是程序所包含的 頭文件
.i 爲後綴的文件,是C源代碼文件且不該該對其執行預處理;
.ii爲後綴的文件,是C++源代碼文件且不該該對其執行預處理;
.m爲後綴的文件,是Objective-C源代碼文件;
.mm爲後綴的文件,是Objective-C++ 源代碼文件;
.o爲後綴的文件,是 編譯後的 目標文件
.s爲後綴的文件,是 彙編語言源代碼文件;
.S爲後綴的文件,是通過 預編譯的彙編語言源代碼文件。

語言支持 編輯

以2006年5月24日釋出的4.1.1版爲準,本 編譯器版本可處理下列語言:
Ada 〈GNAT〉
C 〈GCC〉
C++(G++)
Fortran 〈Fortran 77: G77, Fortran 90: GFORTRAN〉
Java 〈編譯器:GCJ; 解釋器:GIJ〉
Objective-C 〈GOBJC〉
Objective-C++
先前版本歸入的CHILL前端因爲缺少維護而被廢棄。
Fortran前端在4.0版以前是G77,此前端僅支援Fortran 77。在本版本中,G77被廢棄而採用更新的GFortran,由於此前端支援Fortran 95。
下列前端依然存在:
Modula-2
Modula-3
PL/I
Mercury

執行過程 編輯

雖然咱們稱GCC是 C語言編譯器,但使用gcc由C語言 源代碼文件生成 可執行文件的過程不只僅是編譯的過程,而是要經歷四個相互關聯的步驟∶ 預處理(也稱 預編譯,Preprocessing)、 編譯(Compilation)、 彙編(Assembly)和連接(Linking)。
命令gcc首先調用cpp進行預處理,在預處理過程當中,對源代碼文件中的文件包含(include)、預編譯語句(如 定義define等)進行分析。接着調用cc1進行編譯,這個階段根據輸入文件生成以.i爲後綴的目標文件。彙編過程是針對彙編語言的步驟,調用as進行工做,通常來說,.S爲後綴的彙編語言 源代碼文件和彙編、.s爲後綴的彙編語言文件通過 預編譯彙編以後都生成以.o爲後綴的目標文件。當全部的 目標文件都生成以後,gcc就調用ld來完成最後的關鍵性工做,這個階段就是鏈接。在鏈接階段,全部的目標文件被安排在可執行程序中的恰當的位置,同時,該程序所調用到的 庫函數也從各自所在的檔案庫中連到合適的地方。

執行過程示例 編輯

  • 示例代碼
1
2
3
4
5
6
7
#include<stdio.h>
 
int main(void)
{
    printf("hello\n");
    return 0;
}
這個過程處理 宏定義和include,並作語法檢查。
能夠看到 預編譯後,代碼從6行擴展到了910行。
1
2
3
4
5
gcc -E a.c -o a.i
cat a.c|wc -l
5
cat a.i|wc -l
910
  • 編譯過程
這個階段,生成 彙編代碼。
1
2
3
gcc -S a.i -o a.s
cat a.s|wc-l
59
  • 彙編過程
這個階段,生成 目標代碼
此過程生成ELF格式的目標代碼。
1
2
3
gcc -c a.s -o a.o
file a.o
a.o:ELF64-bitLSBrelocatable,AMDx86-64,version1(SYSV),notstripped
連接過程。生成 可執行代碼。連接分爲兩種,一種是 靜態連接,另一種是 動態連接。使用靜態連接的好處是,依賴的動態連接庫較少,對動態連接庫的版本不會很敏感,具備較好的兼容性;缺點是生成的程序比較大。使用動態連接的好處是,生成的程序比較小,佔用較少的內存。
1
gcc a.o -o a
程序運行:
1
2
./a
hello

處理器架構 編輯

GCC4.1支持下列處理器架構:
Alpha
ARM
Atmel AVR
Blackfin
H8/300
IA-32〈x86〉 與 x86-64
IA-64例如: Itanium
MorphoSys 家族
Motorola 68000
Motorola 88000
System/370,System/390
SuperH
HC12
VAX
Renesas R8C/M16C/M32C家族
較不知名的處理器架構也在官方釋出版本中支援:
A29K
ARC
C4x
CRIS
D30V
DSP16xx
FR-30
FR-V
Intel i960
IP2000
M32R
68HC11
MCORE
MN10200
MN10300
NS32K
ROMP
Stormy16
V850
Xtensa
由FSF個別維護的GCC處理器架構:
D10V
MicroBlaze
PDP-10
MSP430
Z8000
當GCC須要移植到一個新平臺上,一般使用此平臺固有的語言來撰寫其初始階段。

程序除錯 編輯

爲 GCC 除錯的首選工具固然是 GNU 除錯器。其餘特殊用途的除錯工具是 Valgrind, 用以發現內存漏失 (Memory leak)。而 GNU 測量器 ( gprof) 能夠得知程序中某些函式花費多少時間,以及其呼叫頻率;此功能須要使用者在 編譯時選定測量〈profiling〉選項。

使用技巧 編輯

首先檢查是否在你的機器上安裝了GCC,使用命令:
可用rpm -q gcc 檢查。
若是沒有安裝,請依序檢查並安裝下面各RPM
libbinutils
binutils
make
glibc-devel
gcc-cpp
gcc
看下面的例子:test.c
1
2
3
4
5
6
7
8
#include<stdio.h>
 
int main()
{
    char *str="I like Linux!I advice you to join in the Linux World";
    printf("%s",str);
    return 0;
}
使用gcc 編譯。輸入gcc -c test.c獲得目標文件test.o.-c命令表示對文件進行編譯和 彙編。但並不鏈接。若是再鍵入gcc -o ../bin/test test.o,那麼將獲得名爲test的 可執行文件。其實這兩步能夠一鼓作氣,gcc ../bin/test test.c.若是程序沒有錯誤就生成了可執行文件。也許你會以爲基於命令行的 編譯器比不上如VC之類的 集成開發環境,的確gcc的界面要改進,可是你一旦熟練了就會感到。gcc的效率如此之高。能夠告訴你們的是Linux底下強大的C/C++集成開發環境 Kdevelop和Vc同樣強大,使用了Gcc編譯器。
GNU C 編譯器 即gcc是一個功能強大的 ANSI C兼容編譯器,你會操做其餘操做系統下的一種C編譯器,能很快掌握GCC.
一、使用Gcc,Gcc是基於命令行的,使用時一般後跟一些選項和文件名。Gcc的基本用法以下: gcc [options] [filenames] 命令行選項制定操做將對命令行上的每一個給出的文件執行。
二、GCC的經常使用選項
編譯選項:gcc有超過100個的編譯選項可用。具體的可使用命令man gcc察看
優化選項:用GCC 編譯C/C++代碼時,它會試着用最少的時間完成編譯而且編譯後的代碼易於調試。易於調試意味着編譯後的代碼與 源代碼有一樣的執行順序,編譯後的代碼沒有通過優化。有不少的選項能夠告訴GCC在耗費更多 編譯時間和犧牲易調試性的基礎上產生更小更快的 可執行文件。這些選項中最典型的就是-O和-O2。-O選項告訴gcc對源代碼進行基本優化。-O2選項告訴GCC產生儘量小的和儘量快的代碼。還有一些很特殊的選項能夠經過man gcc察看。
調試和剖析選項:GCC支持數種調試剖析選項。在這些選項中最經常使用的是-g和-pg.-g選項告訴gcc產生能被GNU調試器(如gdb)使用的調試信息,以便調試用戶的程序。-pg選項告訴gcc在用戶的程序中加入額外的代碼,執行時,產生 gprof用的剖析信息以顯示程序的耗時狀況。
三、使用gdb
使用方法:在命令行中鍵入gdb並按回車就能夠運行gdb了,啓動gdb 後,能在命令行上制定不少的選項,也能夠下面的方式來運行gdb: gdb filename 用這種方式運行gdb時,能直接指定想要調試的程序。在命令行上健入gdb -h獲得一個有關gdb的選項的說明簡單列表。
編譯代碼以供調試,爲了使gdb工做,必須使程序在編譯時包含調試信息,調試信息包含程序裏的每一個變量的類型,在 可執行文件裏的 地址映射以及 源代碼行號。gdb利用這些信息使源代碼和 機器碼相關聯。
關於gcc的大致就寫這麼多吧,更多的信息能夠查找幫助,記得學習Linux的一大武器man或者info命令,下次在介紹一下使用C/C++編寫大型程序的 makefile文件和make命令。

版本發佈 編輯

2012年03月23日,GCC 首個公開發布版本是在 1987 年由 Richard Stallman 發佈的,到今天已經整整 25 年了。爲了慶祝 25 週年,GCC 也相應發佈了 GCC 4.7.0 版本,這是 GCC 一個全新的重要版本。
GCC 4.7.0 帶來了一組關於連接時優化 (LTO) 框架可提高伸縮性和下降內存使用,據開發者稱,在 64 位系統上須要 8G 內存來對 Firefox 進行優化,然而用了 LTO 後只需 3G。
此外就是體驗的支持軟件事務內存,支持更多 C++11 標準,包括原子性、C++11 內存模型,用戶定義文字、別名聲明、構造器委派和可擴展的語法等。
GCC 4.7.0 還改進對 Fortran 的支持,支持 Google Go 1 等等多項改進。 [3]  
2012年06月14日,GCC 4.7.1 發佈了,這是一個 bug 修復版本,主要是 4.7.0 中的一些迴歸測試發現的問題修復。 [4]  
2013年04月11日,GCC 4.7.3 發佈。
2013年03月22日,GCC 4.8.0發佈,進一步增強了對已C++11的支持。而且G++開始支持-std=c++1y選項,用來支持計劃於2014年發佈的C++11修訂版標準(C++14)。 [5]  
2013年10月16日,GCC 4.8.2發佈。提供了對於OpenMP 4.0的支持。
2014年04月22日,GCC發佈了4.9.0版本,提供了對 C11標準的Generic Selection語法特性(_Generic)的支持以及對多線程方面特性的支持。

linux中安裝 編輯

RedHat中安裝

用which gcc命令查看,假若有顯示」 /usr/bin/gcc」的話說明已經安裝了,不然就是沒有安裝。
這裏以redhat 64位 linux爲例。首先將redhat的iso系統鏡像掛在到/mnt/cdrom目錄下:
  mount -o loop /data/rhel-server-5.4-x86_64-dvd.iso /mnt/cdrom
  進入/mnt/cdrom目錄,就能夠訪問iso鏡像中的內容了。
  cd /mnt/cdrom
  cd Server/
安裝gcc的依賴包以及gcc,按如下命令依次執行:   rpm -ivh binutils-2.17.50.0.6-12.el5.x86_64.rpm   rpm -ivh cpp-4.1.2-46.el5.x86_64.rpm   rpm -ivh kernel-headers-2.6.18-164.el5.x86_64.rpm   rpm -ivh glibc-devel-2.5-42.x86_64.rpm   rpm -ivh glibc-headers-2.5-42.x86_64.rpm   rpm -ivh libgomp-4.4.0-6.el5.x86_64.rpm   rpm -ivh gcc-4.1.2-46.el5.x86_64.rpm   你們在安裝rpm包時,因爲依賴關係,在安裝時會提示「此包依賴其餘包xx」,讓你先安裝其餘包,總之你們按照提示來,提示你先安裝哪一個包就安裝哪一個包。
相關文章
相關標籤/搜索