1- 什么是交叉编译
(1)本地编译
在 X86 架构 Linux 系统下进行 C 程序开发时,我们使用系统的 gcc 编译器进行代码的编译,编译生成的可执行程序直接在 X86 架构下的 PC 下运行的,这个过程叫做本地编译 (Native Compile)
(2)交叉编译
如果该C程序想要编译出来后放到ARM处理器架构的系统上运行,则需要在 X86 架构Linux系统下使用支持 ARM 的编译器编译,这个编译器我们通常称为交叉编译器 (Cross Compiler)。
而在一种平台上编译出能在另外一种体系结构完全不同处理器上运行程序的编译过程,叫做交叉编译 (Cross Compile)。
比如在PC平台(X86 CPU)上编译出能运行在以ARM为内核的CPU平台上的程序,编译得到的程序在X86 CPU平台上是不能运行的,必须放到ARM CPU平台上才能运行,虽然两个平台用的都是Linux系统。
(3)为什么使用交叉编译
之所以几乎所有的ARM开发板开发都选择交叉编译,这是因为这些开发板生产出来后并没有系统,这时需要在PC上使用交叉编译器交叉编译操作系统源码,为它构建一个完整的 Linux 系统。
另外,由于CPU处理能力、外存和内存存储空间的大小限制,它们不足以能够运行 gcc 编译环境,所以嵌入式开发绝大部分的过程都是交叉编译。
2- 交叉编译代码测试
接下来我们以大家熟悉的 hello world 程序为例,讲解嵌入式交叉编译过程。
(1)本地编译运行hello程序
我们在我们的虚拟机上使用 vim 编辑器编写 hello.c 测试程序:
编译运行:
我们可以使用 file 命令查看 hello 程序的相关信息,由此可知该程序应该在X86-64位的系统上运行:
我们将该程序下载到开发板上运行试试看,这时系统会提示可执行文件格式出错,不能正常运行。(毕竟这是在X86-64位的系统上生成的可执行文件,怎么能在开发板上执行呢,系统都不一样)
更改文件权限 (chmod命令):chmod a+x hello
表示对于所有人都可以执行这个文件
Linux chmod权限详解
如果tftp不了解的可以查看这篇文章,了解如何搭建tftp服务器:
wpa_supplicant无线网络配置imx6ull以及搭建tftp服务器
(2)交叉编译运行hello程序
我们知道C程序具有可移植性,使用PC上的编译器编译生成的程序应该在PC上运行,而不能在其他处理器架构上运行,那怎样让 hello.c 程序在ARM开发板上运行呢?
这里就需要使用ARM的交叉编译器来对该程序进行交叉编译,这样编译输出的可执行程序就能在ARM开发板上运行了。
因为我们的 i.MX6ULL 处理器带有硬件浮点FPU(FPU(Floating Point Unit,浮点单元)是ARM内核中的硬件外设,用于硬件计算浮点数,要想使用FPU计算浮点数,需要程序和编译器配合),所以这里我们选择安装硬浮点交叉编译器。
sudo apt install -y gcc-arm-linux-gnueabihf
arm-linux-gnueabihf-gcc -v
接下来,我们使用 ARM 的交叉编译器编译该 hello.c 程序,并尝试在 X86-64位 Linux服务器上运行,我们会发现 Linux 服务器上默认并不能运行该程序:
arm-linux-gnueabihf-gcc hello.c -o hello
我们使用 file 命令查看该程序的相关信息,由此可知该程序应该在ARM处理器系统上运行:
file hello
我们将该程序下载到开发板上则能正常运行了。
tftp -gr hello 192.168.1.7
chmod a+x hello
./hello
由此可见:
- 其实交叉编译就是在PC上将文件变成成能够在开发板上执行的可执行文件,然后再下载过去,因为一般来说开发板不能直接编译,毕竟有的连操作系统都没有呢。
- C程序如果想在PC上运行,则应该用PC的编译器来编译;而该程序想要在ARM开发板上运行,则必须用ARM的交叉编译器对源码重新进行交叉编译。
- C程序具有可移植性是指,C程序源代码不用作任何的修改,使用不同的编译器编译生成的可执行程序可以在不同的处理器架构平台上运行。