交叉編譯學習筆記(二)——交叉編譯器的命名規(guī)則

搬運自本人 CSDN 博客:https://blog.csdn.net/ajianyingxiaoqinghan/article/details/70941600


交叉編譯學習筆記(二)——交叉編譯器的命名規(guī)則

在進行嵌入式開發(fā)過程中,用到的交叉編譯器經(jīng)常是這樣的名稱:

  • arm-linux-gcc
  • arm-none-linux-gnueabi-gcc
  • arm-linux-gnu-gcc

上面對應的交叉編譯器的前綴有<code>arm-linux-</code>, <code>arm-none-linux-gnueabi-</code>, <code>arm-linux-gnu-</code>

筆者很困惑,這些編譯器同為ARM下的gcc編譯器,不同的命名到底會導致這些編譯器有哪些區(qū)別?于是筆者開始在網(wǎng)上查閱資料,并進行總結。

參考網(wǎng)址:
http://blog.csdn.net/zqixiao_09/article/details/51823165
http://www.cnblogs.com/wxishang1991/p/5322499.html
http://blog.csdn.net/onlyshi/article/details/51952799
https://zhidao.baidu.com/question/1691117630864232868.html

一. 交叉編譯器命名規(guī)則

交叉編譯工具鏈的命名規(guī)則:

arch [-vendor][-kernel][-system]

其中每部分的含義如下:

  • arch:體系架構,如ARM, MIPS
  • vendor:工具鏈提供商
  • kernel:目標內核
  • system:目標系統(tǒng)
    • 一般為(gnu)eabi,即嵌入式應用二進制接口(Embedded Application Binary Interface)

另外ARM GCC可以根據(jù)是否支持操作系統(tǒng)進行分類。如:

  • arm-none-eabi:該編譯器沒有操作系統(tǒng),不能支持那些與操作系統(tǒng)關系密切的函數(shù)(如fork(2))
  • arm-none-linux-eabi:該編譯器用于Linux系統(tǒng)

1. arch

arch,即系統(tǒng)架構,表明交叉編譯器的目標系統(tǒng)平臺架構,即用該交叉編譯器編譯出的程序是運行在哪種CPU上。
常用的arch值如:

  • <code>arm-cortex_a8-linux-gnueabi</code>中的arm
  • <code>mips-ar2315-linux-gnu中</code>的mips
  • <code>powerpc-e500v2-linux-gnuspe</code>中的powerpc
  • <code>x86_64-unknown-mingw32</code>中的x86_64

2. [-vendor]

vendor,即工具鏈提供商,表示該交叉編譯器提供者。
vendor的值貌似是可以隨便填寫的…… 但一般情況下,大家把vendor攜程體系架構的值。如:

  • <code>arm-cortex_a8-linux-gnueabi</code>中的cortex_a8
  • <code>mips-ar2315-linux-gnu</code>中的ar2315
  • <code>powerpc-e500v2-linux-gnuspe</code>中的e500v2

另外,也有把vendor寫成交叉編譯器作者名字的。

3. [-kernel]

kernel,即內核,指使用該編譯器編譯出程序的目標系統(tǒng)。對應的環(huán)境或系統(tǒng)主要有兩種:
(1) Linux:表示有操作系統(tǒng)(此處主要指Linux)的環(huán)境。
(2) bare-metal:直譯為裸金屬,表示無操作系統(tǒng)的環(huán)境。
比如用該交叉編譯器編譯一個U-boot或者其他小程序,是運行在無嵌入式Linux系統(tǒng)環(huán)境中單獨運行的一個程序。又比如平常我們購買的嵌入式系統(tǒng)開發(fā)板中,常帶有一些如跑馬燈的小程序,這種也是運行在無操作系統(tǒng)環(huán)境的程序。

4. [-system]

system,直譯為系統(tǒng),其實主要表示交叉編譯器所選擇的庫函數(shù)和目標系統(tǒng)。
常見的值有:<code>gnu</code>, <code>gnueabi</code>, <code>uclibcgnueabi</code>

(1) gnu

其實筆者并不知道這里的gnu是不是平常我們所說的gnu…… 那么筆者就默認為是吧…… GNU是一個自由軟件工程項目。至于其他更多的信息,可以自行百度……
這里的gnu,貌似就是表示用的是glibc的意思。

(2) eabi

在說明eabi之前,需要先講一下abi:

ABI
??即二進制應用程序接口(Application Binary Interface(ABI) for the ARM Architecture)。
??計算機中,應用二進制接口描述了應用程序和操作系統(tǒng)之間或其他應用程序的低級接口。
??一個完整的ABI,像Intel二進制兼容標準(iBCS),允許支持它的操作系統(tǒng)上的程序不經(jīng)修改在其他支持此ABI的操作系統(tǒng)上運行。
??ABI不同于API(應用程序接口)。API定義了源代碼和庫之間的接口,所以同樣的代碼可以在支持該API的任何系統(tǒng)中編譯。而在使用兼容ABI的系統(tǒng)中,ABI允許編譯好的目標代碼無需改動,就能運行。

EABI為嵌入式ABI,即Embedded ABI。EABI指定了文件格式、數(shù)據(jù)類型、寄存器使用、堆積組織優(yōu)化和在一個嵌入式軟件中參數(shù)的標準約定。
EABI與ABI的主要區(qū)別,是應用程序代碼中允許使用特權指令,不需要動態(tài)鏈接,并且使用更緊湊的堆棧幀組織用來節(jié)省內存。廣泛使用EABI的有Power PC和ARM。

(3) uclibc

uclibc,是c庫中的一種。

針對上述gnu, eabi, uclibc,對應的常見組合的含義為:

  • gnu = glibc + oabi
  • gnueabi = glibc + eabi
  • uclibc = uclibc + oabi

例:

  • arm-cortex_a8-linux-gnueabi中的nueabi,即glibc+eabi
  • mips-ar2315-linux-gnu中的gnu,即glibc+oabi
  • powerpc-e500v2-linux-gnuspe中的gnuspe
  • x86_64-unknown-mingw32中的mingw32,用的是64位Windows下的mingw32的庫

二. 交叉編譯工具鏈舉例

1. arm-none-eabi-gcc

  • arch: arm (ARM architecture)
  • vendor: none (NO vendor)
  • kernel: (empty) (not target an operating system)
  • system: eabi (complies with the ARM EABI)

該編譯器一般用于編譯ARM架構的裸機系統(tǒng)(包括 ARM Linux 的 boot、kernel,不適用編譯 Linux 應用 Application),一般適合 ARM7、Cortex-M 和 Cortex-R 內核的芯片使用,所以不支持那些跟操作系統(tǒng)關系密切的函數(shù)(比如fork(2),他使用的是 newlib 這個專用于嵌入式系統(tǒng)的C庫)。

2. arm-none-linux-gnueabi-gcc

  • arch: arm (ARM architecture)
  • vendor: none (NO vendor)
  • kernel: linux (creates binaries that run on the Linux operating system)
  • system: gnueabi (uses the GNU EABI)

該編譯器主要用于基于ARM架構的Linux系統(tǒng),可用于編譯 ARM 架構的u-boot、Linux內核、linux應用等。
arm-none-linux-gnueabi基于 gcc ,使用 glibc 庫,是經(jīng)過 Codesourcery 公司優(yōu)化過推出的編譯器,且該交叉編譯工具的浮點運算非常優(yōu)秀。一般ARM9, ARM11, Cortex-A 內核,帶有 Linux 操作系統(tǒng)的會用到。

3. arm-eabi-gcc

該編譯器是Android ARM編譯器。

4. armcc

ARM 公司推出的編譯工具,功能和 arm-none-eabi 類似,可以編譯裸機程序(u-boot, kernel),但是不能編譯 Linux 應用程序。
armcc一般和ARM開發(fā)工具一起,Keil MDK、ADS、RVDS和DS-5中的編譯器都是armcc,所以 armcc 編譯器都是收費的。

5. arm-none-uclinuxeabi-gcc & arm-none-sysbianelf-gcc

  • arm-none-uclinuxeabi用于uCLinux,使用glic
  • arm-none-symbianelf用于symbian(不了解)

6. arm-linux-gnueabi-gcc & arm-linux-gnueabihf-gcc

兩個交叉編譯器名稱上的區(qū)別在于 gnueabi 與 gnueabihf,分別適用于 armel 和 armhf 兩個不同的架構,armel 和 armhf 這兩種架構在浮點運算上采用了不同的策略(有 fpu 的 arm 才能支持這兩種浮點運算策略)。
其實這兩個交叉編譯器只是在 gcc 的選項 -mfloat-abi 的默認值不同。gcc的選項-mfloat-abi有三種值:soft, softfp, hard,其值含義如下:

  • soft: 不用fpu進行浮點計算(即使有fpu浮點運算單元,也不使用fpu);
  • softfp: armel架構(對應編譯器是arm-linux-gnueabi-gcc)的默認值,用 fpu 計算,但傳參數(shù)時使用普通寄存器。這樣中斷的時候,只需要保存普通寄存器,且中斷負荷小,但參數(shù)需要轉換成浮點數(shù)之后再計算;
  • hard: armhf架構(對應編譯器是arm-linux-gnueabihf-gcc)的默認值,用 fpu 計算,傳參數(shù)也用 fpu 中的浮點寄存器傳遞。這樣省去了轉換,性能最好,但中斷負荷高。

測試兩個編譯器的代碼如下:

    #include <stdio.h>  
    int main(void)  
    {  
        double a,b,c;  
        a = 23.543;  
        b = 323.234;  
        c = b/a;  
        printf(“the 13/2 = %f\n”, c);  
        printf(“hello world !\n”);  
        return 0;  
    }  

使用“-v”選項以獲取更詳細的信息:
(1) 使用 arm-linux-gnueabihf-gcc 編譯
輸入指令如下:

arm-linux-gnueabihf-gcc -v mfloat.c

輸出信息如下:
<code>COLLECT_GCC_OPTIONS=’-v’ ‘-march=armv7-a’ ‘-mfloat-abi=hard’ ‘-mfpu=vfpv3-d16′ ‘-mthumb’
-mfloat-abi=hard</code>
可看出使用hard硬件浮點模式。
(2) 使用 arm-linux-gnueabi-gcc 編譯
輸入指令如下:

arm-linux-gnueabi-gcc -v mfloat.c

輸出信息如下:
<code>COLLECT_GCC_OPTIONS=’-v’ ‘-march=armv7-a’ ‘-mfloat-abi=softfp’ ‘-mfpu=vfpv3-d16′ ‘-mthumb’ -mfloat-abi=softfp</code>
可看出使用softfp浮點模式。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容