1. 程式人生 > >關於gcc,libc等相關概念的理解

關於gcc,libc等相關概念的理解

轉自 http://blog.163.com/[email protected]/blog/static/100473339201107101517380/

1、gcc(gnu collect compiler)是一組編譯工具的總稱。它主要完成的工作任務是“預處理”和“編譯”,以及提供了與編譯器緊密相關的執行庫的支援,如libgcc_s.so、libstdc++.so等。

Linux系統下的Gcc(GNU C Compiler)是GNU推出的功能強大、效能優越的多平臺編譯器,是GNU的代表作品之一。gcc是可以在多種硬體平臺上編譯出可執行程式的超級編譯器,其執行效率與一般的編譯器相比平均效率要高20%~30%。
Gcc 編譯器能將C、C++語言源程式、匯程式化序和目標程式編譯、連線成可執行檔案,如果沒有給出可執行檔案的名字,gcc將生成一個名為a.out的檔案。 在Linux系統中,可執行檔案沒有統一的字尾,系統從檔案的屬性來區分可執行檔案和不可執行檔案。而gcc則通過後綴來區別輸入檔案的類別,下面我們來 介紹gcc所遵循的部分約定規則。
.c為字尾的檔案,C語言原始碼檔案;
.a為字尾的檔案,是由目標檔案構成的檔案庫檔案;
.C,.cc或.cxx 為字尾的檔案,是C++原始碼檔案;
.h為字尾的檔案,是程式所包含的標頭檔案;
.i 為字尾的檔案,是已經預處理過的C原始碼檔案;
.ii為字尾的檔案,是已經預處理過的C++原始碼檔案;
.m為字尾的檔案,是Objective-C原始碼檔案;
.o為字尾的檔案,是編譯後的目標檔案;
.s為字尾的檔案,是組合語言原始碼檔案;
.S為字尾的檔案,是經過預編譯的組合語言原始碼檔案。
Gcc的執行過程
雖 然我們稱Gcc是C語言的編譯器,但使用gcc由C語言原始碼檔案生成可執行檔案的過程不僅僅是編譯的過程,而是要經歷四個相互關聯的步驟∶預處理(也稱 預編譯,Preprocessing)、編譯(Compilation)、彙編(Assembly)和連線(Linking)。
命令gcc首先 呼叫cpp進行預處理,在預處理過程中,對原始碼檔案中的檔案包含(include)、預編譯語句(如巨集定義define等)進行分析。接著呼叫cc1進 行編譯,這個階段根據輸入檔案生成以.o為字尾的目標檔案。彙編過程是針對組合語言的步驟,呼叫as進行工作,一般來講,.S為字尾的組合語言原始碼檔案 和彙編、.s為字尾的組合語言檔案經過預編譯和彙編之後都生成以.o為字尾的目標檔案。當所有的目標檔案都生成之後,gcc就呼叫ld來完成最後的關鍵性 工作,這個階段就是連線。在連線階段,所有的目標檔案被安排在可執行程式中的恰當的位置,同時,該程式所呼叫到的庫函式也從各自所在的檔案庫中連到合適的 地方。

2、binutils提供了一系列用來建立、管理和維護二進位制目標檔案的工具程式,如彙編(as)、連線(ld)、靜態庫歸檔(ar)、反彙編 (objdump)、elf結構分析工具(readelf)、無效除錯資訊和符號的工具(strip)等。通常,binutils與gcc是緊密相整合 的,沒有binutils的話,gcc是不能正常工作的。

3、glibc是gnu釋出的libc庫,也即c執行庫。glibc是linux系統中最底層的api(應用程式開發介面),幾乎其它任何的執行庫 都會倚賴於glibc。glibc除了封裝linux作業系統所提供的系統服務外,它本身也提供了許多其它一些必要功能服務的實現,主要的如下:
(1)string,字串處理
(2)signal,訊號處理
(3)dlfcn,管理共享庫的動態載入
(4)direct,檔案目錄操作
(5)elf,共享庫的動態載入器,也即interpreter
(6)iconv,不同字符集的編碼轉換
(7)inet,socket介面的實現
(8)intl,國際化,也即gettext的實現
(9)io
(10)linuxthreads
(11)locale,本地化
(12)login,虛擬終端裝置的管理,及系統的安全訪問
(13)malloc,動態記憶體的分配與管理
(14)nis
(15)stdlib,其它基本功能

glibc和libc都是Linux下的C函式庫,那麼到底有什麼區別呢?
見到Linux下好多的庫函式,曾經令我困惑,其實他們是有章可循的。
libc是Linux下的ANSI C的函式庫;
glibc是Linux下的GUN C函式庫;
ANSI C和GNU C有什麼區別呢?
ANSI C是基本的C語言函式庫,包含了C語言最基本的庫函式。這個庫可以根據 標頭檔案劃分為 15 個部分,其中包括:字元型別 (<ctype.h>)、錯誤碼 (<errno.h>)、 浮點常數 (<float.h>)、數學常數 (<math.h>)、標準定義 (<stddef.h>)、 標準 I/O (<stdio.h>)、工具函式 (<stdlib.h>)、字串操作 (<string.h>)、 時間和日期 (<time.h>)、可變引數表 (<stdarg.h>)、訊號 (<signal.h>)、 非區域性跳轉 (<setjmp.h>)、本地資訊 (<local.h>)、程式斷言 (<assert.h>) 等等。這在其他的C語言的IDE中都是有的。
而GNU C函式庫是一種類似於第三方外掛的東西,由於Linux是用C語言寫的,所以Linux的一些操作是用C語言實現的,所以GNU組織開發了一個C語言的庫 用於我們更好的利用C語言開發基於Linux作業系統的程式。其實我們可以把它理解為類似於Qt是一個C++的第三方函式庫一樣。
不過現在的不同的Linux的發行版本對這兩個函式庫有不同的處理方法,有的可能已經整合在同一個庫裡了,例如我用的Ubuntu就只有glibc。