如果没有做过嵌入式开发
或者说没有在开发板上跑过程序
可能不太清楚什么是交叉编译
从一个现象讲起
编写一个简单的 helloworld 程序,在本地进行编译:gcc hello.c -o hello
生成的二进制文件 hello,我们先用 file 来看下文件 hello 的属性:
可以得到下面的信息:
32位可执行文件;
Intel 80386 架构;
Linux内核本版 2.6.9;
动态链接。
什么是交叉编译
本地编译
本地编译可以理解为,在当前编译平台下,编译出来的程序只能在当前平台下运行。平时我们常见的软件开发,都是属于本地编译。 比如,我们在电脑(X86架构)上编写程序并编译成可执行程序。使用 x86 平台上的工具,开发针对 x86 平台本身的可执行程序,这个编译过程称为本地编译。 交叉编译 交叉编译就是在一个平台上编译程序,得到的二进制文件可以在另外一种架构平台上运行。 比如我们在电脑(X86架构)上通过交叉编译器编译程序,编译出来的二进制文件在电脑上无法运行,但是在开发板(ARM 架构)上却能够运行。 通俗点讲, 把《唐诗三百首》翻译成英文,中国人看不懂了,但是美国人却看懂了。 为什么需要交叉编译 性能: 嵌入式设备出于成本的考虑,一般性能都比较低,和主机(服务器)根本不在一个级别。如果直接在嵌入式设备上编译,能不能编译不说,就算能编译,速度也是很慢。 方便: 一个完整的 Linux 编译环境需要很多软件包的支持,有了交叉编译,我们不需要花时间去移植依赖的软件包。 2交叉编译工具链
工具链 编译过程包括了预处理、编译、汇编、链接等功能。既然有不同的子功能,那每个子功能都由一个单独的工具来实现,它们合在一起形成了一个完整的工具集。 同时编译过程又是一个有先后顺序的流程,它必然牵扯到工具的使用顺序,每个工具按照先后关系串联在一起,这就形成了一个链式结构。 因此, 交叉工具链就是为了编译跨平台体系结构的程序代码而形成的由多个子工具构成的一套完整的工具集 。同时,它隐藏了预处理、编译、汇编、链接等细节,当我们指定了源文件(.c)时,它会自动按照编译流程调用不同的子工具,自动生成最终的二进制程序映像(二进制文件)。 交叉工具链命名规则交叉工具链有很多,我们通常会看到类似下面的名字:
或者也有这样的:
mipsel-linux-gcc
这些工具链的命名规则都是统用的,基本可以表示成:
arch-core-kernel-system
arch:目标平台架构;
core:使用的是哪个 CPU 内核,如Cortex A8。但是这一组命名好像比较灵活,有以厂家名称命名的,有以开发板命名的,或者直接是none等等;
kernel:所运行的OS,比如Linux;
systen:交叉工具链所选择的库函数和目标映像的规范,如gnu,gnueabi等。其中gnu等价于glibc+oabi;gnueabi等价于glibc+eabi。
包含的工具
BinutilsBinutils是GNU工具之一,它包括链接器、汇编器和其他用于目标文件和档案的工具,它是二进制代码的处理维护工具。比如 ld (链接器)、as (汇编器)等等。
GCC这个大家应该非常熟悉了,编译的工作主要靠它,支持多种语言。
GlibcLinux上通常使用的C函数库为glibc。glibc是Linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc。glibc除了封装Linux操作系统所提供的系统服务外,它本身也提供了许多必要功能服务的实现。
GDB这个也是我们经常使用的工具,用于调试程序。
4安装交叉工具链
最简单的安装方法是下载已经打包好的工具链。一般厂家在提供芯片或者开发板的时候,都会提供整套的开发软件,这其中就包含了交叉编译工具链。拿过来直接使用,比我们自己制作的可靠的多。
也可以去网上下载现成的工具链,比如:
http://ftp.arm.linux.org.uk/pub/armlinux/toolchain/安装方法很简单,解压后放到指定的位置,把工具链的路径加到环境变量中。
最后,我们解决下文章开头的问题。
使用 ARM 架构的工具链交叉编译:
可以看出,编译出来的二进制文件是 ARM 架构。
传输到开发板上,修改权限后运行: