交叉编译
交叉编译是什么
-
是在一个平台上生成另一个平台上的可执行代码。
-
例如我们在windows上面编写C51代码,并编译成可执行代码,如xx.hex,是在c51上面运行,不是在windows上面运行
-
例如我们在ubuntu上面编写树莓派的代码,并编译成可执行代码,如a.out,是在树莓派上面运行,不是在ubuntu linux上面运行
-
C51、stm32 交叉编译的发生在keil(集成环境上面),选芯片的过程就是选交叉编译器,不同的平台用的交叉编译链不一样
本地编译
- 是指编译源代码的平台和执行源代码编译后程序的平台是同一个平台。
为什么要交叉编译
平台上不允许或不能够安装我们所需要的编译器
- 因为目的平台上的资源贫乏,无法运行我们所需要编译器,无法完成本地编译【不允许】
- 目的平台没有建立(连操作系统都没有),根本谈不上运行什么编译器【不能够】
2. 树莓派虽然可以安装编译器gcc,但是树莓派有时又是因为目的平台还没有建立(操作系统都没有),根本谈不上运行什么编译器。因为同时操作系统也是代码,也要编译!
平台运行至少需要两样东西:bootloader(启动引导代码)以及操作系统核心【后面会学习如何需要在ubuntu上为树莓派的内核编译】
宿主机与目标机:
- 宿主机(host) :编辑和编译程序的平台,一般是基于X86的PC机,通常也被称为主机。
- 目标机(target):用户开发的系统,通常都是非X86平台。host编译得到的可执行代码在target上运行。
交叉编译工具链:
-
要进行交叉编译,我们需要在主机平台上安装对应的交叉编译工具链(cross compilation tool chain),然后用这个交叉编译工具链编译我们的源代码,最终生成可在目标平台上运行的代码。
-
例如:在Linux PC上,利用arm-linux-gcc编译器,可编译出针对Linux ARM平台的可执行代码。
交叉编译工具链的安装
-
arm-linux-gcc编译链地址:Raspberry Pi,下载tools工程到windows主机
-
将压缩包从windows主机传送到ubuntu虚拟机中:windows主机和ubuntu互传文件的4种方法
- 解压:
unzip tools-master.zip
- 进入:
cd tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
- 输入ls: 查看当前目录文件,可以看到一个软链接(linux下是蓝色的,软连接不占用内存)arm-linux-gnueabihf-gcc ,这就是我们需要用的工具
- 检查下交叉编译工具对不对:
arm-linux-gnueabihf-gcc -v
是4.8.3(和树莓派的版本要一致) - ps:
gcc -v
是查看当前工具的版本,gcc是编译本地的可执行文件。 - 编译的命令是:
arm-linux-gnueabihf-gcc xxx.c -o xxx
- 解压:
-
由于该编译工具路径较为繁琐,将该路径添加到系统环境变量中:
-
临时有效,配置环境变量(在其他窗口无法使用)
echo $PATH:获得当前环境变量的值 pwd:查看的路径 输入该命令将当前路径添加到环境变量中:export PATH=echo $PATH :pwd
-
永久有效,配置环境变量
- 修改工作目录下的.bashrc 隐藏文件,配置命令终端的
vi /home/fangjiarong/.bashrc
- 在文件最后一行加入:
export PATH=echo $PATH : pwd
- 加载配置文件,马上生效配置。
source /home/fangjiarong/.bashrc
- 此时多个窗口都有该指令。检查下交叉编译工具对不对:arm-linux-gnueabihf-gcc -v 是4.8.3
-
交叉编译工具的使用
arm-linux-gnueabihf-gcc xxx.c -I ./
- 和本地编译器gcc一样,参数也一样,可以指定头文件位置
查看交叉编译文件属性
-
file 可执行文件名
:查看文件属性,可以知道该文件在什么平台可以运行 -
chmod +x 文件名
使文件可以直接执行的命令
交叉编译文件发送到目标机
scp clientInPi pi@192.168.43.30:/home/pi
- 指令 文件名 开发板用户名@开发板地址:开发板的绝对路径
- 若编译有头文件,不用传递
- 输入树莓派密码raspberry
带wiringPi库的交叉编译如何进行
问题:树莓派才有wiringPi库,而编译带头文件<wiringPi.h>的c文件需要链接动态库才能编译成功
1. 将wiringPi文件夹放到ubuntu
2. 安装第三方库
./build
3.执行编译,报错:不认识wiringPi库
arm-linux-gnueabihf-gcc demo.c -I /home/fangjiarong/Desktop/lessonPI/WiringPi -lwiringPi
【
通过wiringPi文件夹里面的install文件可知安装后,动态库文件存储在/usr/local/lib下,
libwiringPi.so是软连接,真实动态库是libwiringPi.so.2.46,
执行file libwiringPi.so.2.46可得知该动态库文件是在x86系统下执行的,
而使用arm-linux-gnueabihf-gcc需要的动态库文件是arm属性的,所以需要先交叉编译wiringPi库
】
方法一:
-
正常情况下我们先要交叉编译wiringPi库,编译出的库适合树莓派,这时候交叉编译可执行程序的时候,链接库的格式也是正确的。【下载的第三方库有config文件,设置在执行./build的时候采用的arm-linux-gnueabihf-gcc去编译wiringPi,生成的文件才是正确的格式】
-
L :告诉gcc编译器从-L制定的路径去找动态库。默认是从/usr/lib 或 /usr/local/lib去找,此处修改为当前路径下
-
l:(小写的l)是指定要用的动态库名称,库名砍头去尾(去掉lib和.a)
-
o:指定生成的最终应用程序的名字
-
I(大写i):指定头文件的路径
方法二:
- 可以把树莓派的wringPI库里面的动态库文件拿上来用,打开树莓派的/usr/lib 目录,因为树莓派./build执行后wiringPi库所安装的动态库在/usr/lib目录下,该目录下包含软连接libwiringPi.so(软连接)和库文件libwiringPi.so.2.50,将两个文件保存到ubuntu编译文件所在的文件夹,`
- 此时软连接与源文件没有建立联系,需要使用
ln -s libwiringPi.so.2.50 libwiringPi.so
arm-linux-gnueabihf-gcc demo.c -I /home/fangjiarong/Desktop/lessonPI/WiringPi -lwiringPi -L. -o crossCompBinDemo2
软链接:
如何生成:
- ln -s libwiringPi.so.2.50 libwiringPi.so
- 指令 参数 要被链接的文件 软链接文件名字
- 指令 参数 源文件 目标文件
作用:
- 当我们需要在不同的目录,用到相同的文件时,我们不需要在每一个需要的目录下都放一个必须相同的文件,我们只要在某个固定的目录,放上该文件,然后在其它的目录下用ln命令链接(link)它就可以,不必重复的占用磁盘空间
特点:
- ln命令会保持每一处链接文件的同步性,也就是说,不论你改动了哪一处,其它的文件都会发生相同的变化
- 软链接文件有类似于Windows的快捷方式。
- 你选定的位置上生成一个文件的镜像,不会占用磁盘空间
- 符号连接(Symbolic Link),也叫软连接。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息。
硬链接:
特点:
- 命令中没有-s
- 它会在你选定的位置上生成一个和源文件大小相同的文件
- 不论你改动了哪一处,其它的文件都会发生相同的变化
- 硬连接指通过索引节点来进行连接。在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。在Linux中,多个文件名指向同一索引节点是存在的。一般这种连接就是硬连接。硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。其原因如上所述,因为对应该目录的索引节点有一个以上的连接。只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。也就是说,文件真正删除的条件是与之相关的所有硬连接文件均被删除。