在制作交叉编译工具之前,首先对其命名规则和类型进行简单说明。
交叉编译工具链命名规则: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)建立一个制作交叉编译工具的目录crosstool
(2)ct-ng list-samples查看crosstoll-ng工具支持制作哪些工具模块,如下图所示:
这里选择arm-unknown-linux-gnueabi,通过执行ct-ng arm-unknown-linux-gnueabi命令生成对应的config文件。Config以隐藏文件.config方式在当前的目录生成。
执行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
库。默认参数
执行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版本即可。