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

工程師WWW發表於2013-11-27

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。


glibc是什麼,以及與gcc的關係?

gcc 是編譯器,基本上 Linux 下所有的程式(包括核心)都是 gcc 編譯的,libc 當然也是。
gcc 和 libc 是互相依賴的兩個軟體,它們合作的方式類似 Linux 系統的 "自舉"。先在一個可以執行的帶有老 libc 和 gcc 的系統上,用老 gcc 編譯出一個新版本的 gcc + 老 libc,再用這個新 gcc 編譯出一個新 gcc + 新 libc,再用這套東東編譯整個新系統。


glibc版本檢視

4.9.	How can I find out which version of glibc I am using in the moment?

{UD} If you want to find out about the version from the command line simply
run the libc binary.  This is probably not possible on all platforms but
where it is simply locate the libc DSO and start it as an application.  On
Linux like

	ls -l /lib/libc.so.6 (#add centos5.5上可行,centos6.4上不存在此檔案)

This will produce all the information you need.

What always will work is to use the API glibc provides.  Compile and run the
following little program to get the version information:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <stdio.h>
#include <gnu/libc-version.h>
int main (void)
	puts (gnu_get_libc_version ());
	return 0; 
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This interface can also obviously be used to perform tests at runtime if
this should be necessary.


Just execute:

ldd --version

which comes with glibc package


*但是,在ARM板上,不能通過 1)/lib/libc.so.6 2)ldd --version 命令檢視到相應的gLibc版本,如何直接用命令檢視呢?

相關文章