arm交叉编译详解

转载自 交叉编译详解–版本:v1.3.0, 有修改

CSDN GitHub
arm交叉编译详解

arm交叉编译详解
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可, 转载请注明出处

本文主要介绍了什么是交叉编译,为何要有交叉编译;解释了什么是工具链,什么是交叉工具链;详解解释了交叉编译器的名字的命名规则,以及如何获得交叉编译器,制作交叉编译器的各种工具,使用已有的交叉编译器和自己手动编译交叉编译器之间的对比;最后总结了交叉编译方面的心得和注意事项。

本文提供多种格式供:

1 2 3 4 5 6 7 8
在线阅读 HTML HTMLs PDF CHM TXT RTF WEBHELP
下载(7zip压缩包) HTML HTMLs PDF CHM TXT RTF WEBHELP

HTML版本的在线地址为:

http://www.crifan.com/files/doc/docbook/cross_compile/release/html/cross_compile.html

有任何意见,建议,提交bug等,都欢迎去讨论组发帖讨论:

http://www.crifan.com/bbs/categories/cross_compile/

2015-05-23

修订历史
修订 1.3.0 2015-05-23 crl
将帖子内容整理过来
2. 添加了关于交叉编译器命名规则的解释
3. 添加了使用已有的交叉编译器和自己手动编译交叉编译器之间的对比
4. 补充完整帖子引用
5. 添加交叉编译器eldk的下载地址

版权 2015 Crifan, http://crifan.com

本文章遵从:署名-非商业性使用 2.5 中国大陆(CC BY-NC 2.5)

前言

  1. 本文目的

本文目的在于,介绍关于交叉编译方面的概念,以及如何获得和制作交叉编译器等等内容。

  1. 待完成

有空再去自己,不用工具,手动的,从头到尾的,制作一个交叉编译器。然后再把内容整理过来。

1 交叉编译简介


交叉编译和现存的交叉编译工具

关于Toolchain,cross toolchain,cross compiler

1.1 什么是交叉编译


解释什么是交叉编译之前,先要明白一个概念:本地编译

我们之前常见的软件开发,都是属于本地编译:

在当前的PC下,x86的CPU下,直接编译出来程序,可以运行的程序(或者库文件),其可以直接在当前的环境,即x86的CPU下,当前电脑中,运行。

此时的编译,可以叫做,本地编译,即在当前目标平台下,编译出来的程序,也只是放到当前平台下,就可以运行的。

交叉编译,是一个和,本地编译,相对应的概念。

而所谓的,交叉编译,就是:

在一种平台上编译,编译出来的程序,是放到别的平台上运行

即编译的环境,和运行的环境,不一样,属于交叉的,此所谓cross

交叉编译,这个概念,主要和嵌入式开发有关。

例 1.1. 在x86平台上编译,在ARM平台上运行

一种最常见的例子就是:

在进行嵌入式开发时

手上有个嵌入式开发板,CPU是arm的

然后在x86的平台下开发,比如Ubuntu的Linux,或者是Win7

然后就需要:

在x86的平台上,(用交叉编译器)去编译你写好的程序代码

编译生成的(可执行的)程序,是放到目标开发板,arm的CPU上运行的

此所谓:在x86平台上编译,在ARM平台上运行

交叉编译,英文常写作cross compile,也有其他写法:crosscompile, cross compiling等

1.2 为何要有交叉编译


之所以要有交叉编译,主要原因是:

嵌入式系统中的资源太少

具体的解释就是:

交叉编译出来的程序,所要运行的目标环境中,各种资源,都相对有限,所以很难进行直接的本地编译

最常见的情况是:

在进行嵌入式开发时,目标平台,即嵌入式开发板,比如是最大主频200MHz的ARM的CPU,加上32M的RAM,加上1G的Nand Flash等等。

在如此相对比较紧张的硬件资源的前提下,在已经运行了嵌入式Linux的前提下,是没法很方便的,直接在嵌入式Linux下,去本地编译,去在ARM的CPU下,编译出来,供ARM的CPU可以运行的程序的。

因为编译,开发,都需要相对比较多的CPU,内存,硬盘等资源,而嵌入式开发上的那点资源,只够嵌入式(Linux)系统运行的,没太多剩余的资源,供你本地编译。

提示

BusyBox中包含make等和编译开发相关的工具

对应的,等你后期熟悉了嵌入式开发,熟悉了Busybox后,

比如在Buildroot中去配置Busybox,或者单独交叉编译BusyBox时:

[记录] Ubuntu下为QEMU的arm平台交叉编译BusyBox

就会看到,后来的BusyBox,功能增加后,也已经包含了一些,和编译开发相关的工具,比如make等等

而这些工具,本来的话,只是,放在PC端使用,即在x86平台下做开发的时候,在交叉编译的时候,才用到的工具,

现在,也在(BusyBox的)嵌入式环境中,支持了。

此时,如果,你在BusyBox中把相关的开发工具都选上的话,

再加上,你的目标开发板的硬件配置足够强大的话,比如CPU都是以GHz为单位,等等

加上相关的开发的库和工具都很全的话

实际上,至少理论上,也是可以在你的嵌入式Linux中,进行,有限的,甚至是很大程度上的,本地开发

即,直接在ARM的开发板上,嵌入式Linux中,直接进行嵌入式开发,进行针对ARM的本地编译

比如,编译出一个helloworld,估计还是可以的

这样,就不存在,或者说,避免了,此处所说的,交叉编译,而变成了本地编译

就相当于,之前在x86的PC端的,编译程序放在x86的CPU上运行的本地编译,

在ARM的CPU,嵌入式Linux中,也实现了

但是很明显,对于更加复杂的程序或者库,在ARM开发板上直接编译的可行性和效率,相对就很低

而且如果是本身折腾Uboot等东西,本身目标运行环境,就没有完整的(嵌入式Linux)系统的话,那么就更加没法在目标平台实现本地编译了。

则还是只能进行,此处所说的,交叉编译

2 交叉工具链简介


搞懂了前面介绍的第 1 章 交叉编译简介的概念后,再来解释什么是交叉工具链。

  • 相关旧帖:[整理] 关于Toolchain,cross toolchain,cross compiler

2.1 什么是工具链


所谓的工具链,两部分的含义 :

  • 工具

工具,即tool

工具,是用来干活的

此处要干的活,目标是为了:生成(可以运行的)程序或库文件

而为了达成此目标,内部的执行过程和逻辑主要包含了:

  1. 编译

编译的输入(对象)是:程序代码

编译输出(目标)是:目标文件

编译所需要的工具是:编译器

编译器,常见的编译器,即为gcc

  1. 链接
    链接的输入(对象)是:(程序运行时所依赖的,或者某个库所依赖的另外一个)库(文件)

链接的输出(目标)是:程序的可执行文件,或者是可以被别人调用的完整的库文件

链接所需要的工具是:链接器

链接器,即ld

即,此处,为了将程序代码,编译成可执行文件,涉及到编译,链接(等其他步骤),要依赖到很多相关的工具,最核心的是编译器gcc,链接器ld。

而此处,所谓的工具,主要指的就是:和程序编译链接等相关的gcc,ld等工具

提示
binutils包含了ld等工具

实际上,上面所说的ld,只是处理操作目标文件,二进制文件的最主要的一个工具

而和操作目标等文件相关的,还有其他很多工具的:as,objcopy,strip,ar等等工具的

所以,对此,GNU官网,弄出一个binutils,即binary utils,二进制工具(包),集成了这些,和操作二进制相关的工具集合,叫做binutils

所以,之后你所见到的,常见的工具,就是那个著名的GNU Binutils了。

更加详细的解释,参见教程:GNU Binutils详解

链,即链条,chain

之所以能称为链,你是说明不止一个东西,然后,按照对应的逻辑,串在一起,链在一起

而对应的,涉及到的:

  1. 不止一个东西
    指的是就是前面所说的那个工具,即:和程序编译链接等相关的gcc,binutils等工具

  2. 按照对应的逻辑
    指的就是,按照程序本身编译链接的先后顺序,即:

先编译,后链接,再进行后期其他的处理等等,比如用objcopy去操作相应的目标文件等等。

如此的,将:

和程序编译链接等相关的gcc,binutils等工具

按照先编译后链接等相关的编译程序的内在逻辑

串起来,就成了我们所说的:工具链

2.2 什么是交叉工具链


普通所说的,工具链,指的是当前自己的本地平台的工具链。

用于,交叉编译,的工具链,就叫做交叉工具链

即,那些工具,即编译的gcc,链接的ld,以及相关的工具,用于交叉编译的,工具链,叫做交叉工具链。

交叉工具链,很明显,是用来,交叉编译,跨平台的程序所用的。

交叉工具链,和(本地)工具链类似,也是包含了很多的,对应的工具,交叉编译版本的gcc,ld,as等等。

但是,由于其中最最主要的是用于编译的gcc,所以,我们也常把:

交叉工具链,简称为交叉编译器

即:

严格意义上来说,交叉编译器,只是指的是交叉编译版本的gcc

但是实际上为了叫法上的方便,我们常说的交叉编译器,都是指的是交叉工具链

即,常说的交叉编译版本的gcc,比如arm-linux-gcc,实际上指代了,包含一系列交叉编译版本的交叉工具链(arm-linux-gcc,arm-linux-ld,arm-linux-as等等)

而此文中,后面,所说的,如无特殊指明,均用交叉编译器指代交叉工具链。

下面就对交叉编译器,进行详细的解释。

3 交叉编译器简介


相关旧帖:嵌入式开发之交叉编译器

3.1 交叉编译器的命名规则


在折腾嵌入式开发,用到交叉编译器的时候,常常会看到这样的名字:

等等

其中,对应的交叉编译器的前缀为:

而关于这些名字,我之前也是没注意其具体含义,或者说对于其含义也是很模糊的感觉,不是很清楚这些名字是从何而来的。

后来,经过折腾了crosstool-ng后,基本上明白了这些名字,是如何生成的。

其中,貌似此交叉编译器命名的规则,应该是通用的,至少记得是Buildroot中,好像也是这样命名的。

下面,就以crosstool-ng为例,参考我之前折腾crosstool-ng期间:

[整理] crosstool中如何设置xscale的Tuple’s vendor string(CT_TARGET_VENDOR)

所了解到的内容,来解释解释,这些名字的含义。

3.1.1 交叉编译器名字举例

此处,以编译crosstool-ng中:

[记录] 重试使用最新版本1.18.0的crosstool-ng去配置和编译xscale的交叉编译器

通过ct-ng list-samples中得到的输出为例,

当做交叉编译器的名字的例子,供参考:

3.1.2. crosstool-ng中交叉编译前缀的命名规则


中,交叉编译器的(前缀)的名字的命名规则是 :

arch-vendor-kernel-system

对应分别是 :

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

规则 描述
arch 体系架构, 如ARM, MIPS
vendor 工具链提供商
os 目标操作系统
eabi 嵌入式应用二进制接口(Embedded Application Binary Interface)

根据对操作系统的支持与否, ARM GCC可分为支持和不支持操作系统, 如

  • arm-none-eabi : 这个是没有操作系统的, 自然不可能支持那些跟操作系统关系密切的函数, 比如fork(2). 他使用的是newlib这个专用于嵌入式系统的C库

  • arm-none-linux-eabi:用于Linux的, 使用Glibc

实例

  1. arm-none-eabi-gcc
    (ARM architecture, no vendor, not target an operating system, complies with the ARM EABI)
    用于编译 ARM 架构的裸机系统(包括 ARM Linux 的 boot、kernel, 不适用编译 Linux 应用 Application), 一般适合 ARM7、Cortex-M 和 Cortex-R 内核的芯片使用, 所以不支持那些跟操作系统关系密切的函数, 比如 , 他使用的是 这个专用于嵌入式系统的C库.

  2. arm-none-linux-gnueabi-gcc
    (ARM architecture, no vendor, creates binaries that run on the Linux operating system, and uses the GNU EABI)
    主要用于基于 架构的 系统, 可用于编译 架构的 、内核、应用等. 基于GCC, 使用库, 经过 公司优化过推出的编译器. 交叉编译工具的浮点运算非常优秀. 一般ARM9、ARM11、Cortex-A 内核, 带有 操作系统的会用到.

  3. arm-eabi-gcc
    Android ARM 编译器.

  4. armcc
    公司推出的编译工具, 功能和 类似, 可以编译裸机程序(u-boot、kernel), 但是不能编译 Linux 应用程序. armcc一般和ARM开发工具一起, Keil MDK、ADS、RVDS和DS-5中的编译器都是armcc, 所以 armcc 编译器都是收费的(爱国版除外, 呵呵~~).

  5. arm-none-uclinuxeabi-gcc 和 arm-none-symbianelf-gcc
    arm-none-uclinuxeabi 用于uCLinux, 使用Glibc.
    arm-none-symbianelf 用于symbian, 没用过, 不知道C库是什么.

3.1.3 交叉编译器名字中的arch部分


arch,即系统架构, 表示交叉编译器,是用于哪个目标系统架构中,用于那个平台中的

即,用此交叉编译器编译出来的程序,是运行在哪种CPU上面的

arch的值,常见的有很多种,比如arm,x86,mips等等。

例 3.1. 举例:交叉编译器中的arch的值

crosstool-ng中arch的值

crosstool-ng中,和arch对应的值,应该就是”Target options”中的”Target Architecture”的值了.

比如常见的,配置为arm的话,就是:

对应的配置参数是:ARCH_arm

3.1.4 交叉编译器名字中的vendor部分


vendor,即生成厂家,提供商, 表示谁提供的,即谁制作出来这个交叉编译器的.

vendor的值,貌似是可以自己随便填写的

其他常见写法,还有写成编译交叉编译器的作者的自己的名字的

比如,我叫crifan,那么就可以写成crifan,然后生成的交叉编译器,就是xxx-crifan-xxx-xxx了。

更加通用的做法,好像是:

把vendor写成,体系架构的值,比如我之前针对xscale的去配置crosstool-ng的时候,就写了个xscale。

或者写成CPU的厂家的名字,或者是开发板的名字等等。

举例:交叉编译器中的vendor的值

crosstool-ng中vendor的值

crosstool-ng中,和vendor对应的值,应该就是”Toolchain options”中的”Tuple’s vendor string”的值了。

比如我之前配置为xscale的话,就是:

对应的配置参数是:CT_TARGET_VENDOR

对应的help的解释是:

3.1.5 交叉编译器名字中的kernel部分


kernel,直译为,内核

其实指的是,你用此交叉编译器,编译出来的程序,所运行的目标系统

即,此交叉编译器,编译出来的程序,在什么系统中,什么环境中,运行。

而对应的环境或系统,主要有两种:

  • Linux

    表示:有OS(此处主要指的是Linux)操作系统的环境

    比如,我用交叉编译器,编译一个helloworld程序,然后下载到嵌入式开发中的嵌入式Linux中运行,

    就属于,用此交叉编译器,编译出来的程序,是要运行于,带OS,即嵌入式Linux系统,环境中的

    此处,简称为,有OS的目标系统:Linux

  • bare-metal

    bare-metal,直译为:裸金属

    表示:无(此处主要指的是Linux)操作系统的环境,

    比如,用此交叉编译器,去编译一个Uboot,或者是其他一个小程序,是运行在,无嵌入式Linux的时候,单独运行的一个程序。

    比如,你购买的嵌入式系统开发版,常常附带一些小程序,比如点亮LED,跑马灯等程序,就是这种,运行在无OS的环境的

    此处,简称为:无OS系统的:bare-metal

关于,运行在有OS的Linux下,和,无OS的bare-metal,到底有何区别

目前,还没有完全搞懂。

但是,之前遇到一个实际的例子:

之前用比较新的一个交叉编译器去编译比较老的uboot时,会出现一个错误:

[已解决]uboot交叉编译出错:gcc/config/arm/lib1funcs.asm:1266: undefined reference to `raise’

其就是和这个kernel有关:

编译的uboot,目标运行平台,不是Linux,而是裸的开发板,即Linux还没有运行呢,Uboot去运行,去初始化开发板的时候

详细的情况,见该贴中的解释。

举例:交叉编译器中的kernel的值

crosstool-ng中kernel的值

crosstool-ng中,和kernel对应的值,应该就是”Operating System”中的”Target OS”的值了。

比如我之前配置为Linux的话,就是:

对应的配置参数是:GEN_CHOICE_KERNEL中的CT_KERNEL_linux

对应的help的解释是:

3.1.6 交叉编译器名字中的system部分


system,直译为,系统

其实主要表示的,交叉编译器所选择的库函数和目标系统

最常见的一些值有,gnu,gnueabi,uclibcgnueabi等等.

其中,此处有几方面的值,表示了几方面的含义:

system中的gnu

好像都是gnu

不是很明白,貌似是:

即,gnu,就是表示用的是glibc的意思。

crosstool-ng中system为gnu的情况

crosstool-ng中,和system中gnu对应的值,应该就是”C-library”中的”C library”的值设置为”glibc”了。

对应的配置参数是:CT_LIBC_glibc

对应的help的解释是:

来源:CHENG Jian

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2016年10月1日
下一篇 2016年10月1日

相关推荐