搬運(yùn)自本人 CSDN 博客:https://blog.csdn.net/ajianyingxiaoqinghan/article/details/70941600
交叉編譯學(xué)習(xí)筆記(二)——交叉編譯器的命名規(guī)則
在進(jìn)行嵌入式開發(fā)過程中术辐,用到的交叉編譯器經(jī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ū)別闸昨?于是筆者開始在網(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)行分類镐捧。如:
- arm-none-eabi:該編譯器沒有操作系統(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的值貌似是可以隨便填寫的…… 但一般情況下,大家把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寫成交叉編譯器作者名字的。
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:直譯為裸金屬诈铛,表示無操作系統(tǒng)的環(huán)境。
比如用該交叉編譯器編譯一個(gè)U-boot或者其他小程序勉躺,是運(yùn)行在無嵌入式Linux系統(tǒng)環(huán)境中單獨(dú)運(yùn)行的一個(gè)程序癌瘾。又比如平常我們購買的嵌入式系統(tǒng)開發(fā)板中,常帶有一些如跑馬燈的小程序饵溅,這種也是運(yùn)行在無操作系統(tǒng)環(huán)境的程序妨退。
4. [-system]
system,直譯為系統(tǒng)蜕企,其實(shí)主要表示交叉編譯器所選擇的庫函數(shù)和目標(biāo)系統(tǒng)咬荷。
常見的值有:<code>gnu</code>, <code>gnueabi</code>, <code>uclibcgnueabi</code>
(1) gnu
其實(shí)筆者并不知道這里的gnu是不是平常我們所說的gnu…… 那么筆者就默認(rèn)為是吧…… GNU是一個(gè)自由軟件工程項(xiàng)目。至于其他更多的信息轻掩,可以自行百度……
這里的gnu幸乒,貌似就是表示用的是glibc的意思。
(2) eabi
在說明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定義了源代碼和庫之間的接口,所以同樣的代碼可以在支持該API的任何系統(tǒng)中編譯。而在使用兼容ABI的系統(tǒng)中浊仆,ABI允許編譯好的目標(biāo)代碼無需改動(dòng)客峭,就能運(yùn)行。
EABI為嵌入式ABI抡柿,即Embedded ABI舔琅。EABI指定了文件格式、數(shù)據(jù)類型沙绝、寄存器使用搏明、堆積組織優(yōu)化和在一個(gè)嵌入式軟件中參數(shù)的標(biāo)準(zhǔn)約定鼠锈。
EABI與ABI的主要區(qū)別闪檬,是應(yīng)用程序代碼中允許使用特權(quán)指令,不需要?jiǎng)討B(tài)鏈接购笆,并且使用更緊湊的堆棧幀組織用來節(jié)省內(nèi)存粗悯。廣泛使用EABI的有Power PC和ARM。
(3) uclibc
uclibc同欠,是c庫中的一種样傍。
針對(duì)上述gnu, eabi, uclibc,對(duì)應(yīng)的常見組合的含義為:
- 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架構(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è)專用于嵌入式系統(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架構(gòu)的Linux系統(tǒng)互例,可用于編譯 ARM 架構(gòu)的u-boot、Linux內(nèi)核筝闹、linux應(yīng)用等媳叨。
arm-none-linux-gnueabi基于 gcc ,使用 glibc 庫关顷,是經(jīng)過 Codesourcery 公司優(yōu)化過推出的編譯器糊秆,且該交叉編譯工具的浮點(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 類似夫偶,可以編譯裸機(jī)程序(u-boot, kernel)界睁,但是不能編譯 Linux 應(yīng)用程序。
armcc一般和ARM開發(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è)交叉編譯器名稱上的區(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)模式鲸阔。