轉自:https://blog.csdn.net/lisemi/article/details/91045791
一、安裝crosstool-ng
1、獲取crosstool-ng
從官網(http://crosstool-ng.org/)下載crosstool-ng,注意要下載官網打包好的版本,如果直接從github下載源碼,源碼版本主目錄沒有configure文件,無法配置和編譯。
2、編譯crosstool-ng
解壓進入crosstool-ng目錄,執行./configure,make,sudo make install,在configure的過程會出現很多依賴庫沒有,直接使用apt-get命令安裝對應的依賴庫即可,這里需要注意的是本人在使用apt-get命令安裝libtool庫的時候,提示已經安裝好,但是configure時還是提示沒有,此時同時下載libtool庫離線安裝解決此問題。安裝好crosstool-ng會在/usr/local對應的目錄下。
3、測試
ct-ng –v出現對應的版本信息則表示安裝成功。
二、制作編譯器
在制作交叉編譯工具之前,首先對其命名規則和類型進行簡單說明。
- 交叉編譯工具鏈命名規則:arch [-vendor] [-os] [-(gnu)eabi]
- arch - 體系架構,如ARM,MIPS
- verdor - 工具鏈提供商
- os - 目標操作系統
- eabi - 嵌入式應用二進制接口
- 不同交叉編譯工具鏈簡單說明:
- arm-none-eabi:沒有操作系統的,不支持那些跟操作系統關系密切的函數(Glibc),使用嵌入式newlib專用庫,常用於編譯ARM7、Contex-M和contex-R系統的arm裸機系統(boot,kernel),不能編譯應用軟件。
- arm-none-linux-eabi:指定linux系統,使用Glibc
- arm-none-linux-gnueabi-gcc 主要用於基於ARM架構的Linux系統,可用於編譯 ARM 架構的 u-boot、Linux內核、linux應用等。使用Glibc,經過Codesourcery公司優化。
- arm-eabi-gcc:android ARM編譯器
- arm-none-uclinuxeabi: 用於uCLinux,使用Glibc。
- arm-none-symbianelf: 用於symbian。
- ABI 和 EABI的區別
- ABI:二進制應用程序接口(Application Binary Interface (ABI) for the ARM Architecture)。在計算機中,應用二進制接口描述了應用程序(或者其他類
型)和操作系統之間或其他應用程序的低級接口。
- EABI:嵌入式ABI。嵌入式應用二進制接口指定了文件格式、數據類型、寄存器使用、堆積組織優化和在一個嵌入式軟件中的參數的標准約定。
- 兩者主要區別,ABI是計算機上的,EABI是嵌入式平台上(如ARM,MIPS等)。
- arm-linux-gnueabi-gcc 和 arm-linux-gnueabihf-gcc:
兩個交叉編譯器分別適用於 armel 和 armhf 兩個不同的架構,只是armel 和 armhf 這兩種架構在對待浮點運算采取不同的策略。他們其實只是在gcc 的選項 -mfloat-abi 的默認值不同。gcc 的選項 -mfloat-abi 有三種值 soft、softfp、hard(其中后兩者都要求arm 里有 fpu 浮點運算單元,soft 與后兩者是兼容的,但 softfp 和 hard 兩種模式互不兼容):
soft: 不用fpu進行浮點計算,即使有fpu浮點運算單元也不用,而是使用軟件模式。
softfp: armel架構(對應的編譯器為 arm-linux-gnueabi-gcc ),用fpu計算,但是傳參數用普通寄存器傳,這樣中斷的時候,只需要保存普通寄存器,中斷負荷小,但是參數需要轉換成浮點的再計算。
hard: armhf架構(對應的編譯器 arm-linux-gnueabihf-gcc ),用fpu計算,傳參數也用fpu中的浮點寄存器傳,省去了轉換,性能最好,但是中斷負荷高。
1、獲取工具類型
(1)建立一個制作交叉編譯工具的目錄crosstool
(2)ct-ng list-samples查看crosstoll-ng工具支持制作哪些工具模塊,如下圖所示:
這里選擇arm-unknown-linux-gnueabi,通過執行ct-ng arm-unknown-linux-gnueabi命令生成對應的config文件。Config以隱藏文件.config方式在當前的目錄生成。
2、配置
執行ct-ng menuconfig命令進入配置頁面
1)路徑配置:
- Local tarballs directory:指定制作編譯器所需要的源碼包的下載存放(一般下載會很慢,可以在編譯之前將需要的源碼包下載好放在該目錄里,或者在http://ftp.gnu.org/gnu/下載),可以修改成任意位置,請提前建好並注意權限。這里指定到crosstool/src下。
- Prefix directory:制作好的交叉編譯器所放置的目錄。
- Debug crosstool-NG:選擇Debug crosstool-NG,會多出一個子菜單,選中Save intermediate steps,此選項提供一個從上一步錯誤的地方繼續編譯,而不是從新編譯,這樣節約大量的時間。
- Number of parallel jobs:這個菜單需要下拉才能看到此項為增加編譯時的並行進程數,以增加運行速度,加速編譯。如選擇三個進程:選擇(3)Number of parallel jobs。
2)平台配置
進入Target option
- Target Architecture:這個選擇arm架構;
- Architecture level:Architecture level=CT_ARCH_ARCH=-march,指CPU指令集架構,這里選擇ARMv7
- ARMv4t- ARMv8t
- ARM920t
- 其他可以查arm芯片資料,可查到對應的架構
- Emit assembly for CPU:Emit assembly for CPU=CT_ARCH_CPU=-mcpu。cpu核心,如Contex-A7
- Tune for CPU:Tune for CPU=CT_ARCH_TUNE=-mtune。哪一款CPU。
- Use specific FPU:FPU處理器,VFP或neon等。
- Floating point:浮點運算類型,軟浮點或硬浮點
說明:具體都支持哪些架構呢?可以用man gcc來查詢,搜索arm,再搜索-march=就可以找到本gcc支持的處理器核心列表了。
3)工具鏈配置
進入Toolchain option
- Tuple's vendor string:供應商字符串,若設置為abc,則編譯后的工具鏈名字為arm-abc-linux-gnueabi。
- Tuple's alias:工具鏈的別名,若設置為arm-linux,則編譯后會建立工具鏈的軟連接,命名為arm-linux-xx。
- 其他配置
進入Operating System --->菜單。選擇編譯的內核版本。這里使用默認的參數;
進入Binary utilities --->選擇binutils的源碼包版本號,配置二進制工具。這里使用默認參數。
C-library --->菜單,選擇glibc庫版本,使用默認參數
C compiler --->菜單選擇GCC版本,選擇默認參數
Debug facilities --->菜單,選擇調試工具版本,默認參數。
Companion libraries --->菜單,編譯工具,GMP是實現任意精度算術運算的軟件包,可以完成有符號整數、有理數和浮點數的運算。只要計算機的內存滿足需求,GMP的運算精度沒有任何限制。MPFR是一個用於高精度浮點運算的C庫。默認參數
3、編譯
執行ct-ng build開始編譯
三、編譯常見問題
1)安裝到cross-gdb時,出現configure: error: expat is missing or unusable,expat-2.1.0.tar.gz這個文件是運行build時它自己下載的。解決:sudo apt-get install libexpat1-dev.
2)解決完問題1后執行ct-ng cross-gdb+可以接着前面的編譯。又出現了_123136.c:835:15: error: expected ')' before 'int'的錯誤。在網上搜尋答案。解決:export CPPFLAGS="-P"。
3)error: forced unwind support is required的錯誤,選中C庫選項的Force unwind support即可。
4)Error happened in: CT_DoExecLog[scripts/functions@257],在當前編譯目錄下,找到.build文件夾,除了tarballs和tools文件夾,其他的文件夾都刪除
5)included file 'linux/if_pppolac.h' is not exported 解決方法: Disable kernel header check。
6)Build failed in step 'Installing pass-1 core C gcc compiler',沒有找到具體原因,通過更改gcc的版本避免。
7)Don't set LD_LIBRARY_PATH. It screws up the build。直接執行unset LD_LIBRARY_PATH即可。
8)Error happened in: do_libc_get[scripts/build/libc/newlib.sh@741]。查看build.log發現是下載newlib庫失敗,再看發現下載的版本是2.2.0,該版本對應的官網沒有,因此我直接進入.config修改成2.0.0版本即可。