交叉编译器简介
首先和大家分享的是嵌入式系统移植中交叉编译工具集,具体如下图:
如图,第一个问题是为什么要有交叉编译?
众所周知我们的CPU它工作方式非常简单,就是根据不同的高低电平去干不同的事情。如下图:
如图,比如说CPU要做加法,那么很显然x86可以这样认为“add 1010”如果说看到这样一个组合我就认为CPU要做加法了。那么自然而然我们程序员只要写成高低的一个标示给CPU,CPU基本就能做加法。所以这个跟我们前面学习汇编的思想很像,但是我们现在不一样了因为我们的PC一般来说是x86的,但是如果说我们现在的CPU换一款换成ARM同样后面是1010,那么1010对于ARM来说因为它是两家不同的公司,那么它对这样的指定级的编码和译码的时候是不是会有不同的结果。比如说在arm中的1010就可能不是加法了而可能是mov这一数据的搬移指令。那么大家就可以发现如果我们在x86上编译的一个二进制集合包或者是二进制程序集合,我们不做任何的修改直接放到arm板子上运行那么就一定会出现一个新的问题,就是我们的arm是不认识这样的集合的,也就是说跟你本身想做加法的逻辑是不一致的。
所以这样我们就迫切想要去在x86上去编译一个arm也能理解的逻辑。也就是这个情况就变成了如下图:
如图,我们x86下也就是我们的主机和目标机,就是我们原来最开始学习应用开发的时候我们的主机就是x86,然后我们的目标机也是x86,因为我们运行也是在x86上运行起来进程或网络编程的概念。但是我们现在嵌入式开发不一样,我们的主机没有变还是x86但是我们的目标机现在已经变成了ARM CPU。
所以这样来看,我们原本正常情况下主机跟目标机是统一品牌的。但是到现在我们就变成了主机是一个平台目标机是另外一个平台,那这种情况我们就称为交叉。
也就是说,这种情况下我们就需要一个交叉编译器来完成从一个结构编译另外一个结构的编译器。如果目标机跟主机是同一平台的我们就称为同一编译器,比如说我们最典型的gcc,以上就是我们第一个为什么要有交叉编译器的概念,那么在这个概念中我们要引入一个命令叫file命令,通过这个命令我们来加深一下为什么我们在以后编译开发过程中可能遇到的新的问题,也就是我们都知道Linux系统中一个可执行程序并没有后缀名,也就是我们不会像Windows一样写成ese或者.xx让大家来区分,很有可能我们最终可执行程序都叫build,那么这种情况下就会经常出现如果我不小心在实际开发中把x86下编译的build烧写到了arm板上,结果跑了半天都跑不出来,甚至整个程序运行的逻辑都是混乱的。
这个原有就在于有时候我们粗心马虎把x86的程序放在了arm板上了,那么我们应该怎么去避免这样一个情况了?
如图我们还是用一个1.c用一个非常简单的hello world做一个例子,然后我们用gcc -o build 1.c生成一个build程序,然后点击ls查看会发现这个build一没有后缀名二没有其他的标识,我怎么知道它是在x86下运行还是在arm下运行,或者换句话来说把这个程序放到我的板子上能不能运行起来呢?然后我们就来看第一个命令叫做file build,然后点击回车键大家就可以发现它上面有一堆东西,这一堆东西一般情况下我们不用全部关心但是我们唯一需要关心的就是“x86-64”因为我这个机器是64位的,所以说你会发现看build真正属性的第二个选项中它会告诉我们build工作的平台是x86认识的,这就是从file中去读它文件头的一个信息。
以上就是file非常重要的一个概念。
交叉编译结果
下面我们来看如果有了交叉编译器后,交叉编译的结果又会变成什么样子。在之前我们讲交叉编译器也说过一般有两种方法:第一就是直接用编译好的,第二就是自己手动编译。我们今天还是采用芯片厂商已经编译好的。
在Linux系统安装软件其实比较简单,不是双击的形式,其实就是个解包的过程,它主要是把工具集解压到一个目录上然后我们直接使用它就可以。
然后我们来看看安装交叉编译器的方法:
安装交叉编译器其实非常简单就是一个解压缩的过程。解压缩的过程,解压到linux标准目录,在安装过程中我们就直接在Windows目录下把交叉编译器拷到你们的共享目录就可以了。
如图,安装命令就是“tar-zxvf arm-linux-qcc-4.5.1-vfp-20120301.tgz ”注意在上面的那行命令中的tgz,它实际上是个缩写,所以使用的就是zcvf,然后记住千万不用把这个包解完就直接回车了,因为我们知道这个包是默认Windows的共享目录,所以一旦回车就可能导致编译器中有些工具是用不了的,最典型的工具就是软链接因为在Windows里是没有软链接的概念的,所以说如果这个包里面有软链接的文件那很有可能就是解压出来它就支持不了,最后就可能报错或者占用的数据量比较大。所以我们建议大家尽量不要安装在Windows的共享目录尽量安装在Linux本身的虚拟机的硬盘目录。所以我们在切换到另一个目录需要“-C”一般来说交叉编译器在制作的时候就把整个目录都给你打包好了,所以有写时候我们就习惯直接解压的根(/)上,通过根就相当于把解压的权限直接交给交叉编译器,然后点击回车键:
如图,大家会发现这个地方出现了一些问题,“文件已存在”这个原因是因为我刚才在敲命令的时候没有使用超级用户,所以我们要早命令“tar-zxvf arm-linux-qcc-4.5.1-vfp-20120301.tgz -C /”前加上一个sudo在去输入就没有错了。然后我们把它进行解压,在解压过程中,一般来说是没有太大问题的,大家可以小心点看它有没有报什么错误,如果没有报错误就可以了。
解压完成后:
如图,我们进入opt目录后,因为opt中本身就有个目录,但是我们可以一级一级的进去。最后进入4.5.1目录后会发现这个目录下的选项其实就是交叉编译器中总括的安装包,其中有写目录对我们来说是有帮助的。
比如说“bin”这个目录就相当于交叉编译器中的命令集合,也就是说我们的命令基本上应该在bin里去找。而“lib”它有两种形式,第一种形式就是我们交叉编译器在运行的时候它有一个库。第二种就是我们最终要交叉编译器虽然在x86中运行但是最终要编译成arm,所以说我们在编译过程中就涉及到两种库,一种是x86的库一种就是arm的库。
也就是说我们交叉编译器本身是个软件,它在运行需要x86的一个平台,所以这个时候它肯定是要有一个x86的库为它运行时准备的,但是它最终生成的目标要依赖arm体系。所以它链接的时候需要arm库的提供。
如图,我们先进入bin里面看一下,这个地方大家会发现文件比较多,当然文件虽多大家可以发现都有一个统一的规则。当然这个地方先来提成一个思想也就是说我们安装的叫交叉编译集合或者叫交叉编译链一个整块,也就是说我们不仅仅要用到它叫gcc的东西,同时还可以看到gcc的外面还有很多其他的命令,这些命令其实就是我们在后面会给大家介绍叫做工具集的功能,所以说我们实际上安装交叉编译器就是安装一套工具,不光是gcc。然后输入如图上命令,它其实就是个l文件,l文件软链接到本地目录下的文件,所以这个命名规则跟我们之前讲的交叉编译器的规则也很像“arm-none-linux-gnueabi-gcc”也就是在Linux下新的标准接口的一个gcc工具。一般来说这个名字太长懒得去写,我们就可以用软链接的方式去把它链在这里,直接敲“arm-linux-gcc”就可以了,所以这就是我们比较常用的方式。
那么我们安装的一般步骤来说第一步就是把它解压,一般来说要把它解压到linux标准目录下一步就是我们的两种使用方法。
使用
1.使用简单方法(就是我直接在shear中敲)
#arm-linux-gcc -o build 1.c(这样就可以直接用它了,跟我们的gcc命令一样,只是调用命令不在调用gcc了而是“arm-linux”这个命令)
简单方法的优缺点:敲很少的字符就可以工作了,但是它的缺点也很多,就比如说你的系统不仅仅开发的这一个品牌,还有其他别的品牌,那在这种情况下就很可能不知道用这种快捷方式是找的哪一个,所以很有可能导致我们在编译中出现一些稀奇古怪的问题。因为你编译器用错了,很有可能你新编译器不知道或者老编译器又不支持,所以这种方法使用起来一定要小心,也就是你系统里不能有多个编译器。
2.使用绝对路径方法(最好的办法)
#/opt/FriendlyARM/toolschain/4.5.1/bin/arm-linux-gcc -o build 1.c
绝对路径的优缺点:它的缺点就是跟简单路径相反太复杂,但是我个人还是比较喜欢用绝对路径虽然麻烦点但是它不用每次都输入,而且这种方法绝对能保证你用的编译器是正确的。