1、交叉编译是什么?为什么要交叉编译?
交叉编译 是在一个平台上生成另一个平台上的可执行代码
编译:在一个平台上生成该平台上的可执行代码
===================交叉编译是什么?====================
我们在windows上面编写c51代码,并编译成可执行代码,如xx.hex,
是在c51上面运行,不是在windows上面运行
我们在ubuntu 上面编写树莓派代码,并编译成可执行代码,如a.out,
是在树莓派上面运行,不是在 ubuntu linux上面运行
c51 交叉编译发生在keil(集成环境环境上面)
================为什么要交叉编译?====================
平台上不允许或不能够安装我们所需要的编译器,比如c51
1、因为目的平台上的资源匮乏,无法运行我们所需要的编译器
2、树莓派是不是就不需要交叉编译?
错。 也要。树莓派有时又是因为目的平台还没有建立,连操作系统都没有,根本谈不上运行什么编译器!
操作系统也是代码,也要编译!!!
平台运行至少需要两样东西:
bootloader(启动引导代码) ,以及操作系统核心
宿主机(host) :编辑和编译程序的平台,一般是基于x86的pc机,通常也被称为主机
目标机(target):用户开发的系统,通常都是非x86平台。host 编译得到的可执行代码在target上运行
简单来说:我们学习用的pc 机是宿主机,树莓派是目标机
===================交叉编译需要用到工具:===============
交叉编译器、交叉编译工具链
======================相关代码=======================
代码的编辑
代码的编译
编译出来的代码./a.out可以运行
==============2、交叉编译工具链的安装===================
(目标机是树莓派,用的工具链就是树莓派的)
https://github.com/raspberrypi/
在这个网址安装
他的界面是打开是这样的
点击这里,tools就是工具链的意思
进去了是这个样子的
然后我们点击克隆
再点击
点击最下面的
下载完就这样啦
解压
unzip tools-master.zip
2.1临时有效=======================================
PATH环境变量
export PATH=/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/CLC/lessonPI/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
从windows拷贝工作目录
用filezilla
解压
unzip tools-master.zip
pwd获得路径
echo $PATH 获得当前环境变量的值
2.2永久有效============================================
修改工作目录下的.bashrc 隐藏文件,配置命令终端的
vi /home/CLC/.bashrc
在文件 最后一行加入:
export PATH=/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/CLC/lessonPI/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
加载配置文件,马上生效配置
source /home/CLC/.bashrc
我们打开虚拟机,新建一个文件夹
然后用filezilla传输
再把它放到想要的地方
然后用这个指令解压
然后用这个指令解压
然后用这个指令解压
解压完成
打开看看里面都有什么
这有很多目录,我们需要的在哪里呢?
然后在bin 下面绿色的都是可执行文件
我们需要用到的是这个软链接
它实际用到的是后面的东西
我们取了一个名字指向4.8.3
这个软链接是不占内存的,只是一个符号,指向4.8.3
这两个是类似的
只是gcc -v 编译出来的东西在本电脑上面运行
如果我们要在树莓派上编译需要./arm-linux-gnueabihf-gcc -v
感觉到敲这么多指令是不是很麻烦?怎么办呢?
我们能不能像gcc 一样直接识别到呢?
这涉及到环境变量
如何显示当下的环境变量?
那么如何配环境变量呢?(临时环境变量)====================
pwd显示当面目录
export 是配置环境的意思
然后我们直接回到工作目录
现在就可以识别啦
环境变量的临时配置方式:
你在其他的窗口,不认识
那么如何配环境变量呢?(永久有效环境变量)=================
修改隐藏文件
然后再最后一行加入
export PATH=/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/CLC/lessonPI/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
然后让他生效
我们现在打开一个新的窗口试试
可以认识
而且里面的版本号 4.8.3
3、交叉编译服务客户端==================================
交叉编译:
检查下交叉编译工具对不对:
arm-linux-gnueabihf-gcc -v
4.8.3
如何交叉编译?
arm-linux-gnueabihf-gcc xxx.c -o xxxx
如何把编译生成的可执行文件下载到开发板:
scp test_2 pi@192.168.32.209:/home/pi
scp 是指令
test_2 是文件名
开发板用户名@开发板地址:开发板的绝对路径
=========================================================================
新建一个test.c的文件
里面的内容
给他命名test_1
file 用来查看文件的属性
executable,可执行的意思
x86-84,只能运行在x86的64位电脑上
你把这个test_1,放在树莓派上是跑不动的
那么如何把test.c放在树莓派底下运行呢?
我在再来看一下test_2的属性
可执行的,可以运行在ARM平台的
我们在linux平台上先运行一下两者
test_2不能解析,不能运行,因为我们编出来的要放在树莓怕下面跑
交叉编译的作用就产生啦,在x86平台上编译,在树莓派上面使用
那如何把他拷贝到树莓派下面呢?
那树莓派是否拿到这个代码了呢?
是的
那我们如何运行呢?
那我么如果把test_1也放到树莓派下能运行吗?
运行不了,格式错误
如果想要上位机编译的代码,能在树莓派上面运行,
前提是交叉编译过,交叉编译的工具链要对
4、带wiringPi库的交叉编译如何让进行=======================
1、正常我们先要交叉编译wiringPi库,编译出的库适合树莓派,这时候交叉编译可执行程序的时候,链接库的格式也是正确的。
2、通过 -I -L 来指定
因为链接库的格式不对,是宿主机的平台,出现以先下错误
arm-linux-gnueabihf-gcc demo2.c -I /home/CLC/lessonPI/WiringPi/wiringPi -lwiringPi
/home/CLC/lessonPI/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/../lib/gcc/arm-linux-gnueabihf/4.8.3/../../../../arm-linux-gnueabihf/bin/ld: cannot find -lwiringPi
collect2: error: ld returned 1 exit status
如何解决呢?
把树莓派的wiringPI库拿上来用
树莓派的wiringPi库在哪呢?‘
cd /usr/lib/
======================================================================
软链接:
参考文章:
http://www.cnblogs.com/zhangna1998517/p/11347364.html
ln -s 是linux中一个非常重要命令,一定要熟悉。它的功能是为某一个文件在另外一个位置建立一个同不的链接,这个命令最常用的参数是-s,
具体用法是:ln -s 源文件 目标文件。
当 我们需要在不同的目录,用到相同的文件时,我们不需要在每一个需要的目录下都放一个必须相同的文件,我们只要在某个固定的目录,放上该文件,然后在其它的 目录下 用ln命令链接 (link)它就可以,不必重复的占用磁盘空间。例如:ln -s /bin/less /usr/local/bin/less -s 是代号(symbolic)的意思。 这 里有两点要注意:第一,ln命令会保持每一处链接文件的同步性,也就是说,不论你改动了哪一处,其它的文件都会发生相同的变化;第二,ln的链接又软链接 和硬链接 两种,软链接就是 ln -s ** **,它只会在你选定的位置上生成一个文件的镜像,不会占用磁盘空间,硬链接ln ** **,没有参数-s, 它会在你选定的位置上生成一个和源文件大小相同的文件,无论是软链接还 是硬链接,文件都保持同步变化。
【硬连接】
硬连接指通过索引节点来进行连接。在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index)。在Linux中,多个文件名指向同一索引节点是存在的。一般这种连接就是硬连接。硬连接的作用是允许一个文件拥有多个有效路径名,这样用户就可以建立硬连接到重要文件,以防止“误删”的功能。其原因如上所述,因为对应该目录的索引节点有一个以上的连接。只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放。也就是说,文件真正删除的条件是与之相关的所有硬连接文件均被删除。
【软连接】
另外一种连接称之为符号连接(Symbolic Link),也叫软连接。软链接文件有类似于Windows的快捷方式。它实际上是一个特殊的文件。在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息。
======================================================================
软链接概念:
1.软链接文件有类似windows的快捷方式。
2.在符号连接中,文件实际上是一个文本文件。其中包含的有另一文件的位置信息。
3.你选定的位置上生成一个文件的镜像,不会占用磁盘空间
如何生成
ln -s libwiringPiDev.so.2.50 libwiringPiDev.so
ln 指令
-s 参数
libwiringPiDev.so.2.50要被链接的文件
ibwiringPiDev.so 软链接文件名字
硬链接概念:
ln libwiringPiDev.so.2.50 libwiringPiDev.so
1、他会在你选定的位置上生成一个和源文件大小相同的文件
===========相关代码================================
在我们之前写的demo2.c里面
他的头文件包含wiringPi.h
我们如果直接gcc 编译的话会出现错误,显示不认识这些函数
必须得链接上wiringPI的库才可以
如果在上位机进行交叉编译的时候,我们并没有wiringPI这个东西,如何办呢?
下载代码,在用filezilla传输
解压以后传输到Linux下面
传输完以后
记得解压完,看看里面的两个东西
然后我们./build输入一下试试
发现全是白的运行不了,必须是绿的才能运行,这时候
直接用chmod 就行啦
chmod +x 文件名
根据README.TXT和INSTALL
我们先./build
超级用户需要输入密码
然后告诉你安装完毕
然后我们看看他说的是不是在/usrlocal/lib/下面有
确实有这些东西,但是这些东西是不能用的
我们做个实验
把树莓派的demo2.c传输到linux 上面
用scp
记得Linux网络改成桥接模式
然后我们看看linux 有没有传过来的demo2.c
然后我们编译它
发现头文件不认识
如何办呢?
首先找到头文件
发现都运行不了
然后给他加上权限
解决方法
你会发现提示不一样了
刚才是这个文件找不到,现在是文件找到了,但是有问题
他的问题,跟我们在树莓派下面运行demo2.c 一样的
不认识这些函数
如何解决呢?
同样的我们在linux 下面试一下
报错了
因为我们的链是跑到去链他的
ls /usr/local/lib/
我们去看一下他的文件属性
他是个软链接看不了
要看他真正链的东西
这东西是x86的
arm-linux-gnueabihf-gcc是交叉编译工具链,编译的东西要适合树莓派的,你用的window的东西,用的是x86的东西,平台不兼容,你的编译器不认识wiringPi这个库
它编译出来的库都是适合x86平台的不是树莓派平台的
grep gcc * -nir
grep 在所有的文件中匹配gcc的字段
* 代表所有的文件
n 显示行号(常规文件显示行号)
i 是不区分大小写
r 是递归,一个个目录的找进去
给history 加一个管道 找数据源
敲过的指令和demo2有关的就过滤出来了
树莓派的wiringPi库在哪呢?
看见键号了吗?
->是软链接的意思,真正用到的库是.2.50
然后我们可以scp把需要的库传到linux上面
传的没有Dev的那个
看看linux是否拿到手了
这个库到手了
没有Dev
那我们能不能把软链接也拿过来
看看树莓派拿到软链接了吗?
是的
软连接消失了.so 不会指向.so.2.50
这种方式不行,我们要自己创建软链接
如何生成软链接?
ln -s 输入你要链接的文件
然后我们ls -l 查看一下
有一个箭头箭过来,说明创建成功
记得创建一个不带Dev的
软链接已经创建成功,可以用了
. L 用当前文件库
记得看看路径对不对
(记得看看链接的库,我传输错了,好久才找到原因,对惨痛教训,看见那个屁股带Dev的了吗?那个就是传输错的)
然后给他个名字
然后把他传到树莓派下面
然后我们去树莓派下面看一眼
可以正常运行
我们去代码看看,回忆回忆
功能是吧gpio继电器7的端口,输入1 的时候是低电平,输入0的时候是高电平
然后我们看看初始的时候
端口7是1
当我们输入0的时候
当我们输入1的时候
端口7就变成了0