GCC、ARM-LINUX-GCC、ARM-ELF-GCC淺析

GCCARM-LINUX-GCCARM-ELF-GCC淺析

一、GCC簡介:

The GNU Compiler Collection,通常簡稱GCC,是一套由GNU開發的編譯器集,爲什麼是編輯器集而不是編譯器呢?那是因爲它不僅支持C語言編譯,還支持C++, Ada, Objective C等許多語言。另外GCC對硬件平臺的支持,可以所無所不在,它不僅支持X86處理器架構還支持ARM, Motorola 68000, Motorola 8800, Atmel AVR, MIPS等處理器架構。

二、GCC內部結構:

GCC內部結構主要由Binutilsgcc-coreGlibc等軟件包組成。

1. Binutils:它是一組開發工具,包括連接器,彙編器和其他用於目標文件和檔案的工具。關於Binutils的介紹可以參考Binutils簡單介紹【這個軟件包依賴於不同的目標機的平臺。因爲不同目標機的指令集是不一樣的,比如armx86就不一樣】

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;

}

$ gcc -o test test.c編譯生成test可執行文件。gcc編譯流程分爲四個步驟:預處理、編譯、彙編、鏈接。個人認爲預處理和編譯主要由gcc-core來完成,彙編和鏈接主要由Binutils來完成。那麼何時用到glibc呢?看到源碼中的printf函數沒有,這個函數在GCC中是以庫函數的形式存在,這個庫函數在glibc庫中,在stdio.h頭文件中被聲明。

總的來說,如果真正瞭解了上面3個軟件包的作用,自然就明白GCC是如何工作的。

三、GCC的安裝:

既然GCC本身就是一個軟件集合,那麼這些軟件集合又怎麼安裝呢,因爲這個過程很複雜,我也沒有安裝過,但這個不是本文的重點,就不講了。不過網上的Linux徹底定製指南》講得非常詳細,感興趣的可以看一看。

四、交叉編譯:

交叉編譯(或交叉建立)是這樣一種過程,它在一種機器結構下編譯的軟件將在另一種完全不同的機器結構下執行。一個常見的例子是在PC機上爲運行在基於ARMPowerPCMIPS的目標機的編譯軟件。幸運的是,GCC使得這一過程所面臨的困難要比聽起來小得多。

GCC中的一般工具通常都是通過在命令行上調用命令(如gcc)來執行的。在使用交叉編譯的情況下,這些工具將根據它編譯的目標而命名。例如,要使用交叉工具鏈爲ARM機器編譯簡單的Hello World程序,你可以運行如下所示的命令:

使用如下命令編譯並測試這個代碼:

 $ arm-linux-gcc -o hello hello.c

五、arm-linux-gcc

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-gccGCC所需的安裝包的名字大同小易,可這是爲什麼呢?不知道網友沒有想到過這個問題,可能網友知道這些包跟GCC所用的包是不相同的,僅僅名字不一樣而已,但是知道爲什麼不一樣恐怕還是有相當多的人不清楚。個人認爲要了解arm-linux-gccGCC的關係和區別,這個問題纔是關鍵所在。好了,不賣關子了,入正題,因爲我們知道X86ARM所使用的指令集是不一樣的,所以所需要的binutils肯定不一樣咯;上面提到過gcc-core是依賴於binutils的,自然ARM跟X86所使用的gcc-core包也不一樣;glibc一個c庫,最終是以庫的形式存在於編譯器中,自然ARM所使用的glibc庫跟X86同樣也是不一樣的咯,其它的依此類推。

六、arm-linux-gccarm-elf-gcc:

arm-elf-gccarm-linux-gcc一樣,也是是基於ARM目標機的交叉編譯軟件。但是它們不是同一個交叉編譯軟件,兩者是有區別的,兩者區別主要在於使用不同的C庫文件。arm-linux-gcc使用GNUGlibc,而arm-elf-gcc一般使用 uClibc/uC-libc或者使用REDHAT專門爲嵌入式系統的開發的Cnewlib關於兩者的區別,請參考arm-linux-gcc  arm-elf-gcc區別

七、參考資料

 工具鏈技術說明

 Gcc編譯流程解析

 Linux高級程序設計》中的交叉編譯

 創建ARMlinux交叉編譯環境的實踐

 arm-linux-gcc  arm-elf-gcc區別


發佈了44 篇原創文章 · 獲贊 58 · 訪問量 26萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章