交叉編譯工具鏈建立與常識

交叉編譯工具鏈的命名規則

arch [-vendor] [-os] [-(gnu)eabi]

arch – 體系架構,如ARM,MIPS,對於MIPS可能還分大端模式mips或者小端模式mipsel;

vendor – 工具鏈提供商,可能有的工具鏈會省去這個字段,一般可能是none、芯片提供商如fsl或者是第三方提供商如buildroot(允許自行修改);

os – 目標板中運行的系統,一般爲linux,但對於一些專門用於裸板或者uboot的編譯工具這個字段可能是bare-metal(裸板);

gnu – 所使用的C庫,gnu代指glibC,這個字段還可能是eglibc,uclibc;

eabi – 相對於x86上面的abi,嵌入式應用二進制接口(Embedded Application Binary Interface),如果沒有“eabi”字段,說明用的是舊版本的oabi(Old Application Binary Interface)。
一般這個字段還有eabihf這個選項:
對於eabi一般使用softfp和 soft組合兼容軟硬浮點,方法是在浮點運算指令處設置一個“陷阱”,如果硬件不支持硬件浮點的話,這個指令將導致異常,這個時候軟件浮點處理將服務這個異常。這種運行方式雖然浮點運算使用硬件浮點單元,但是傳遞參數是仍然使用通用寄存器,這樣中斷的時候,只需要保存普通寄存器,中斷負荷小,但是參數需要轉換成浮點的再計算。
對於eabihf使用soft和hard處理浮點,與上述不同的是,這個運行方式傳參數也用fpu中的浮點寄存器傳,省去了轉換,性能最好,但是中斷中需要對浮點寄存器進行出入棧處理,負荷比較高。
一般大家都會使用eabi,由於eabihf與eabi不兼容,所以如果你的源碼工程有不開源的.o文件,那麼這個時候你只能使用保持跟這些.o文件的編譯選項保持一致。

[-(gnu)eabi]舉幾個例子:
gnu 等價於:glibc+oabi
gnueabi 等價於:glibc+eabi
uclibc 等價於:uclibc+oabi

查詢交叉編譯工具的默認編譯選項

有時候我們需要編譯新版本的工具鏈,但是不太清楚現在正在使用的工具鏈的詳細選項,可以使用以下命令查詢:

echo 'main(){}'|mipsel-linux-gcc -E -v -

可以對比前後新舊版本工具鏈的選項進行配置,比如下面是我的工具鏈的詳細描述:
這裏寫圖片描述

交叉編譯工具編譯選項的問題

這裏需要強調,無論對於編譯生成工具鏈的配置,還是對於工具鏈的命名,這些都只是影響工具鏈的默認選項,也就是直接輸入arm-linux-gcc這樣的命令時使用的編譯選項,在後期編譯的時候我們還是可以通過添加編譯的詳細描述進行適當修改:
但是還是非常推薦一個硬件平臺使用一套專用的工具鏈。
①工具鏈目標cpu的架構版本不同:
比如生成工具鏈時的目標架構是armv7(cortex-A、cortex-M),但實際使用的硬件平臺是armv5,由於新版架構中可能引入了新的指令,所以可能導致運行異常,這個時候可以在編譯中添加“-mcpu=arm1176jzf-s”,變換目標架構。
②默認不支持動態庫,可以添加“-enable-shared”;不支持多線程,可以添加–enable-threads=posix;浮點處理方式不對,可以通過’-mfloat-abi=softfp’(soft、hard)調整。
③使用的源碼比較久,但是版本太高的gcc可能導致莫名其妙的錯誤,主要可能是語法檢測的嚴謹程度問題,這個時候就只能更換工具鏈版本了;

MIPS交叉編譯工具的編譯

下面以生成MIPS的工具鏈爲例子進行演示,ARM工具鏈的不同只有Toolchain和Target Option下的配置不同:
1.下載:
http://buildroot.uclibc.org/downloads/snapshots/buildroot-snapshot.tar.bz2 下載buildroot:
tar -jxvf buildroot-snapshot.tar.bz2
cd buildroot
buildroot是一個根文件系統生成軟件,可以通過配置,非常方便的獲得各種交叉編譯工具鏈、busybox、U-boot甚至是Kernel。

2.配置buildroot:
make clean
make menuconfig
選擇第一項“Target Architecture”,改成MIPS(little endian)
這裏寫圖片描述
另外,選擇“Toolchain”,務必將“Kernel Headers”的Linux版本改成你自己主機的Linux版本(因爲我們編譯出的MIPS交叉工具是需要在我們的主機上運行的),如我的主機是Ubuntu 12.04.4的,Linux版本是3.11.0(可以使用uname -a查看,使用lsb_release -a查看Ubuntu發行版本,另外由於選項中沒有3.11.x這個選項,因此使用3.12.x):
這裏寫圖片描述

3.編譯:
注意:
1.編譯過程中必須聯網,因爲會下載一些壓縮包存放在buildroot/dl文件夾下,比如binutils、gcc等;

2.必須事先安裝好bison、flex、texinfo、ncurses等,比如我第一次編譯,出現如下錯誤,因爲我沒有安裝texinfo:sudo apt-get install texinfo 就可以了;
之後就是漫長的等待了,差不多1個小時。。。

4.編譯完成後,在buildroot文件夾下多了一個output文件夾,其中就是編譯好的文件:
cd buildroot/output/host/usr/bin
我們發現了mips的交叉編譯工具已經生成啦~~;
另外,在buildroot/output/target文件夾下,這裏有使用mipsel-linux-gcc生成的busybox;
這裏寫圖片描述
5.爲了以後方便使用,我們直接將其中的bin文件夾添加到環境變量中,省得我們日後輸入長長的路徑了。
將路徑添加到/etc/profile文件中,然後運行source命令:
source /etc/profile
6.需要強調的是,如果需要移動生成的交叉編譯工具鏈的路徑,需要從/host/usr/…節點開始移動,否則工具鏈將不能正常工作。

ARM交叉編譯工具鏈的編譯配置選項

下面是我爲S3C6410配置的交叉工具鏈配置:
Target Option下的配置:
這裏寫圖片描述
Toolchain下的配置如下:
這裏寫圖片描述
這裏寫圖片描述


關於編譯器的動態庫

在編譯的時候由於需要選擇C庫類型,所以對於一個完成編譯的gnueabi工具鏈,一般都會包含glibc庫。
一般工具鏈的庫路徑爲:
/usr/arm-none-linux-gnueabi/sysroot/lib (這個路徑主要放置glibc之類的系統動態庫)
/usr/arm-none-linux-gnueabi/sysroot/usr/lib (這個路徑主要放置一些第三方的庫,比如libjpeg、libpng、libts、libfreetype,當用戶更新工具鏈時,可以將以前工具鏈中安裝的第三方的動態庫直接複製過來使用 複製時建議使用“cp -ndR”,防止新版本的庫被舊版本的庫覆蓋)

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