The GNU Compiler Collection,通常簡稱GCC,是一套由GNU開發的編譯器集,為什麼是編輯器集而不是編譯器呢?那是因為它不僅支持C語言編譯,還支持C++, Ada, Objective C等許多語言。另外GCC對硬件平台的支持,可以所無所不在,它不僅支持X86處理器架構, 還支持ARM, Motorola 68000, Motorola 8800, Atmel AVR, MIPS等處理器架構。
GCC內部結構主要由Binutils、gcc-core、Glibc等軟件包組成。
1. Binutils:它是一組開發工具,包括連接器,匯編器和其他用於目標文件和檔案的工具。關於Binutils的介紹可以參考Binutils簡單介紹。【這個軟件包依賴於不同的目標機的平台。因為不同目標機的指令集是不一樣的,比如arm跟x86就不一樣】
2. gcc-core:顧明之意是GCC的核心部分,這部分是只包含c的編譯器及公共部分,而對其他語言【C++、Ada等】的支持包需要另外安裝,這也是GCC為何如此強大的重要原因。【它依賴於Binutils,可以參考安裝GCC】
3. Glibc:包含了主要的c庫,這個庫提供了基本的例程,用於分配內存,搜索目錄,讀寫文件,字符串處理等等。【這個包GCC編譯生成的庫,前輩們為了方便大家開發,就把Glibc放到GCC中】
舉例描述下上面3個包是如何進行運作的。有一個c源文件test.c源碼如下:
#include<stdio.h> int main(int argc, char *argv[]) { printf("Hello Linux!!\n"); return 0; }/* 何問起 hovertree.com */
$ gcc -o test test.c編譯生成test可執行文件。gcc編譯流程分為四個步驟:預處理、編譯、匯編、鏈接。個人認為預處理和編譯主要由gcc-core來完成,匯編和鏈接主要由Binutils來完成。那麼何時用到glibc呢?看到源碼中的printf函數沒有,這個函數在GCC中是以庫函數的形式存在,這個庫函數在glibc庫中,在stdio.h頭文件中被聲明。
總的來說,如果真正了解了上面3個軟件包的作用,自然就明白GCC是如何工作的。
既然GCC本身就是一個軟件集合,那麼這些軟件集合又怎麼安裝呢,因為這個過程很復雜,我也沒有安裝過,但這個不是本文的重點,就不講了。不過網上的《Linux徹底定制指南》講得非常詳細,感興趣的可以看一看。
交叉編譯(或交叉建立)是這樣一種過程,它在一種機器結構下編譯的軟件將在另一種完全不同的機器結構下執行。一個常見的例子是在PC機上為運行在基於ARM、PowerPC或MIPS的目標機的編譯軟件。幸運的是,GCC使得這一過程所面臨的困難要比聽起來小得多。
GCC中的一般工具通常都是通過在命令行上調用命令(如gcc)來執行的。在使用交叉編譯的情況下,這些工具將根據它編譯的目標而命名。例如,要使用交叉工具鏈為ARM機器編譯簡單的Hello World程序,你可以運行如下所示的命令:
使用如下命令編譯並測試這個代碼:
$ arm-linux-gcc -o hello hello.c
arm-linux-gcc是基於ARM目標機的交叉編譯軟件,前面幾年安裝arm-linux-gcc交叉編譯軟件對與一個初級嵌入式工程師來說特別棘手,因為它需要安裝多個軟件包,而且安裝過程中不能有半點差錯,因為每個軟件包都有它的依賴關系【換句話就是說安裝某個軟件包時,如果它的依賴軟件版本太低或者沒有安裝都將導致該軟件包安裝失敗】;嗯,廢話不說了,入正題,下面是我摘自創建ARMlinux交叉編譯環境的實踐的一部分,詳細的安裝過程請參考原文或GOOGLE搜索之。
......
1、源文件准備
binutils-2.14.tar.gz
ftp://ftp.gnu.org/gnu/binutils/binutils-2.14.tar.gz
gcc-core-2.95.3.tar.gz
ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3/gcc-core-2.95.3.tar.gz
gcc-g++2.95.3.tar.gz
ftp://ftp.gnu.org/gnu/gcc/gcc-2.95.3/gcc-g++-2.95.3.tar.gz
glibc-2.2.4.tar.gz
ftp://ftp.gnu.org/gnu/glibc/glibc-2.2.4.tar.gz
glibc-linuxthreads-2.2.4.tar.gz
ftp://ftp.gnu.org/gnu/glibc/glibc-linuxthreads-2.2.4.tar.gz
linux-2.4.21.tar.gz
ftp://ftp.kernle.org/pub/linux/kernel/v2.4/linux-2.4.21.tar.gz
patch-2.4.21-rmk1.gz # linux kernel patch for arm
ftp://ftp.arm.linux.org.uk/pub/l ... atch-2.4.21-rmk1.gz
binutils-2.14.tar.gz這個壓縮包包含有ld,ar,as等一些產生或者處理二進制文件的工具。
gcc-core-2.95.3.tar.gz這個壓縮包是GCC的主體部分,GCC是GNU Compiler Collection的簡稱,顧名思義,它能夠編譯很多種高級語言,例如C、C++,Java等,而這個壓縮包中含有C編譯器,及公共部分,而對其他語言的支持,采用另外的壓縮包單獨發布。
gcc-g++2.95.3.tar.gz,這個壓縮包就是為使GCC能夠編譯C++程序而單獨發布的。
glibc-2.2.4.tar.gz,libc是很多用戶層應用都要用到的庫,kernel和bootloader不需要這個庫的支持,這個庫主體部分封裝在這個壓縮包內。
glibc-linuxthreads-2.2.4.tar.gz,這是Libc用於支持Posix線程而單獨發布的一個壓縮包。
linux-2.4.21.tar.gz,這個壓縮包就是Linux的內核。
patch-2.4.21-rmk1.gz,這個壓縮包是用來給Linux內核打補丁,以使其可以支持ARM的硬件平台。
......
可以看出arm-linux-gcc跟GCC所需的安裝包的名字大同小易,可這是為什麼呢?不知道網友沒有想到過這個問題,可能網友知道這些包跟GCC所用的包是不相同的,僅僅名字不一樣而已,但是知道為什麼不一樣恐怕還是有相當多的人不清楚。個人認為要了解arm-linux-gcc與GCC的關系和區別,這個問題才是關鍵所在。好了,不賣關子了,入正題,因為我們知道X86跟ARM所使用的指令集是不一樣的,所以所需要的binutils肯定不一樣咯;上面提到過gcc-core是依賴於binutils的,自然ARM跟X86所使用的gcc-core包也不一樣;glibc一個c庫,最終是以庫的形式存在於編譯器中,自然ARM所使用的glibc庫跟X86同樣也是不一樣的咯,其它的依此類推。
arm-elf-gcc跟arm-linux-gcc一樣,也是是基於ARM目標機的交叉編譯軟件。但是它們不是同一個交叉編譯軟件,兩者是有區別的,兩者區別主要在於使用不同的C庫文件。arm-linux-gcc使用GNU的Glibc,而arm-elf-gcc一般使用 uClibc/uC-libc或者使用REDHAT專門為嵌入式系統的開發的C庫newlib。關於兩者的區別,請參考arm-linux-gcc arm-elf-gcc區別。