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

搬運(yùn)自本人 CSDN 博客:https://blog.csdn.net/ajianyingxiaoqinghan/article/details/70941600


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

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

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

上面對(duì)應(yīng)的交叉編譯器的前綴有<code>arm-linux-</code>, <code>arm-none-linux-gnueabi-</code>, <code>arm-linux-gnu-</code>

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

參考網(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:體系架構(gòu),如ARM, MIPS
  • vendor:工具鏈提供商
  • kernel:目標(biāo)內(nèi)核
  • system:目標(biāo)系統(tǒng)
    • 一般為(gnu)eabi,即嵌入式應(yīng)用二進(jìn)制接口(Embedded Application Binary Interface)

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

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

1. arch

arch,即系統(tǒng)架構(gòu),表明交叉編譯器的目標(biāo)系統(tǒng)平臺(tái)架構(gòu),即用該交叉編譯器編譯出的程序是運(yùn)行在哪種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的值貌似是可以隨便填寫(xiě)的…… 但一般情況下,大家把vendor攜程體系架構(gòu)的值。如:

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

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

3. [-kernel]

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

4. [-system]

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

(1) gnu

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

(2) eabi

在說(shuō)明eabi之前,需要先講一下abi:

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

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

(3) uclibc

uclibc,是c庫(kù)中的一種。

針對(duì)上述gnu, eabi, uclibc,對(duì)應(yīng)的常見(jiàn)組合的含義為:

  • 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的庫(kù)

二. 交叉編譯工具鏈舉例

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架構(gòu)的裸機(jī)系統(tǒng)(包括 ARM Linux 的 boot、kernel,不適用編譯 Linux 應(yīng)用 Application),一般適合 ARM7、Cortex-M 和 Cortex-R 內(nèi)核的芯片使用,所以不支持那些跟操作系統(tǒng)關(guān)系密切的函數(shù)(比如fork(2),他使用的是 newlib 這個(gè)專(zhuān)用于嵌入式系統(tǒng)的C庫(kù))。

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架構(gòu)的Linux系統(tǒng),可用于編譯 ARM 架構(gòu)的u-boot、Linux內(nèi)核、linux應(yīng)用等。
arm-none-linux-gnueabi基于 gcc ,使用 glibc 庫(kù),是經(jīng)過(guò) Codesourcery 公司優(yōu)化過(guò)推出的編譯器,且該交叉編譯工具的浮點(diǎn)運(yùn)算非常優(yōu)秀。一般ARM9, ARM11, Cortex-A 內(nèi)核,帶有 Linux 操作系統(tǒng)的會(huì)用到。

3. arm-eabi-gcc

該編譯器是Android ARM編譯器。

4. armcc

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

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

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

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

測(cè)試兩個(gè)編譯器的代碼如下:

    #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”選項(xiàng)以獲取更詳細(xì)的信息:
(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硬件浮點(diǎn)模式。
(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浮點(diǎn)模式。

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

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容