目录
一、介绍
1、本地编译
2、交叉编译
二、交叉工具链
1、概念
2、工具
3、获取方法
三、交叉编译运行程序
1、pc机操作(x86_64)
2、开发板操作(ARM)
一、介绍
1、本地编译
本地编译是在与目标运行环境相同的机器上进行的编译过程,也就是说,编译器和生成的可执行文件在同一个平台上运行。
- 相同平台:编译和运行代码的平台相同。
- 简单性:配置和依赖关系比较简单,因为编译环境和运行环境是一致的。
- 调试方便:可以直接在本机器上调试生成的可执行文件。
2、交叉编译
交叉编译是在与目标运行环境下不同的机器上进行的编译过程。编译器生成的可执行文件是为另一种平台设计的。
- 不同平台:编译器所在的平台与目标运行平台不同。
- 复杂性:配置和依赖关系更复杂,因为需要设置交叉编译工具链和目标平台的库和头文件。
- 调试不便:生成的可执行文件不能在本地机器上运行,调试需要在目标平台上进行。
简单地说,编译生成的可执行程序可直接在本机运行的叫本地编译。而在一个平台上编译出能在另一种体系结构完全不同的处理器上运行的程序叫交叉编译。
为什么要有交叉编译器呢?简单来说,就是嵌入式系统中的资源太少。因为编译,开发,都需要相对比较多的CPU,内存,硬盘等资源,而嵌入式开发上的那点资源,只够嵌入式(Linux)系统运行的,没太多剩余的资源,支持本地编译。
二、交叉工具链
1、概念
在嵌入式开发过程中有宿主机和目标机的角色之分:宿主机是执行编译、链接嵌入式软件的计算机;目标机是运行嵌入式软件的硬件平台。
在宿主机执行编译的流程如下:
交叉工具链指的是将程序代码,编译成可执行文件的一系列工具,按照先编译后链接等相关的编译程序的内在逻辑串起来。交叉工具链主要由binutils、gcc和glibc组成。
为了将程序代码,编译成可执行文件,涉及到编译,链接(等其他步骤),要依赖到很多相关的工具,最核心的是编译器gcc,链接器ld。
- 编译:将程序代码生成目标平台的目标文件。
- 链接:将多个目标文件和库文件链接在一起,生成可执行文件或库文件。
其中,链接器ld只是处理操作目标文件,二进制文件的最主要的一个工具,而和操作目标等文件相关的,还有其他很多工具的:as,objcopy,strip,ar等等工具的。GNU官网弄出了一个二进制工具包,集成了这些和操作二进制相关的工具集合,叫做binutils。
一句话概括就是自己平台上用于交叉编译的一系列工具就叫做交叉工具链。由于其中最最主要的是用于编译的gcc,所以,我们也常把:交叉工具链,简称为交叉编译器。即:严格意义上来说,交叉编译器,只是指的是交叉编译版本的gcc。但是实际上为了叫法上的方便,我们常说的交叉编译器,都是指的是交叉工具链。即,常说的交叉编译版本的gcc,比如arm-linux-gcc,实际上指代了,包含一系列交叉编译版本的交叉工具链(arm-linux-gcc,arm-linux-ld,arm-linux-as等等)。
2、工具
工具名 | 工具说明 |
---|---|
gcc | c程序源码编译工具 |
g++ | c++程序源码编译工具 |
cpp | c程序预处理器 |
as | 将汇编源码汇编成目标机器代码.o文件 |
ar | 将多个可重定位的.o文件归档为一个静态库.a文件 |
ranlib | 产生归档.a文件索引,并将其保存到这个归档文件中,因为ar命令支持该特性,所以现在很少用了 |
ld | 链接器,用来将多个目标文件.o、静态库.a文件、动态库.so文件链接生成一个可执行文件 |
readelf | 列出ELF格式可执行文件的相关信息 |
nm | 列出目标文件中的函数符号表 |
size | 列出目标文件中每个段(text、data、bss等)的大小 |
strings | 列出目标文件中能打印出来的字符串 |
strip | 去掉目标文件中一些无关调试信息等,减小文件的大小 |
objcopy | 把一种目标文件中的内容复制到另一种目标文件中,裸机开发经常会用这个命令将ELF格式的文件转换成二进制文件 |
objdump | 该工具常用于对二进制进行反汇编,默认输出到标准输出,所以一般配合重定向一起使用 |
addr2line | 将程序地址转换为文件名、函数名和源代码行号,主要用来调试或反汇编 |
3、获取方法
获取交叉编译器一般有两种方式,一种是直接从官网上进行下载,或者购买开发板的时候厂家会提供你对应的交叉编译器;另一种就是自己制作交叉编译器,如果我们从零开始做一个交叉编译器难度是很大的,所以正常情况下我们都是借助工具来制作交叉编译器,推荐使用crosstool-NG和buildroot(不仅能制作交叉工具链,而且还可以制作根文件系统rootfs。而且还支持同时编译对应的Linux内核和Uboot)。
三、交叉编译运行程序
1、pc机操作(x86_64)
(1)在.bashrc中设置交叉编译路径
(2)编写程序并编译
(3)将执行文件上传至本地文件中
2、开发板操作(ARM)
(1)我的板子不支持scp传输命令,所以我这里采用的tftp命令(我这里用了tftp32软件,下载资源下面给大家了,可以免费下载)。
(2)连接开发板,下载运行文件
通过一个简单的hello程序,为大家整理了交叉编译的流程。由于每个人的开发板不同,所以设置可能略有不同,但是原理都是一样的,大家哪里遇到问题可以私信问我。