当前位置: 首页 > article >正文

树莓派交叉编译

目录

一、交叉编译的认知

1.1 本地编译:

1.2 交叉编译是什么:

1.3 为什么要交叉编译:

1.4 什么是宿主机?什么是目标机?

1.5 如何进行交叉编译:

二、交叉编译工具链的安装

2.1 下载交叉编译工具:

2.2 将交叉编译工具链添加到环境变量:

2.2.1 临时有效的添加环境变量:

2.2.2 永久有效的添加环境变量:

三、交叉编译实战

3.1 交叉编译实战(一):

3.2 交叉编译实战(二):

四、带WiringPi库的交叉编译实战

4.1 交叉编译WiringPi库:

4.2 把树莓派的WiringPi库拿来

4.2.1 将树莓派的libwiringPi.so.2.52上传到虚拟机:

4.2.2 创建软链接:

4.2.3 交叉编译:


一、交叉编译的认知

编译是指将源代码文件(如C/C++文件)经过预处理、编译、汇编和链接等步骤,转换为可执行文件的过程将源代码转换成机器代码的过程称为编译(Compile),编译的工作需要编译器(Complier)来完成。

1.1 本地编译:

  • 本地编译是指在当前的编译平台上,生成能在当前平台上运行的可执行文件。

例如,在x86平台上,使用 x86平台上的工具,开发针对x86平台本身的可执行程序,这个编译过程称为本地编译。 以一个简单的例子来说明本地编译,假设有一个hello.c文件,它包含以下内容:

#include <stdio.h>

int main()
{
	printf("Hello World\n");
	return 0;
}

我们想要在x86平台上进行本地编译,并在x86平台上运行这个程序。可以使用以下命令:

gcc hello.c -o hello

1.2 交叉编译是什么:

  • 交叉编译 是在一个平台上生成另一个平台上的可执行代码。例如:

  1. 我们再windows上面编写C51代码,并编译成可执行代码,如xx.hex,是在c51上面运行,不是在windows上面运行

  2. 我们在ubuntu上面编写树莓派的代码,并编译成可执行代码,如a.out,是在树莓派上面运行,不是在ubuntu linux上面运行

1.3 为什么要交叉编译:

  1. 平台上不允许或不能够安装我们所需要的编译器,比如C51,因为目的平台上的资源贫乏,无法运行我们所需要编译器

  2. 树莓派比C51内存大的多,是不是就不需要交叉编译了?错,也要!树莓派有时又是因为目的平台还没有建立,连操作系统都没有,根本谈不上运行什么编译器。操作系统也是代码,也要编译!因为平台运行需要两样至少东西:bootloader(启动引导代码)以及操作系统核心

1.4 什么是宿主机?什么是目标机?

  • 宿主机(host) :编辑和编译程序的平台,一般是基于X86的PC机,通常也被称为主机。

  • 目标机(target):用户开发的系统,通常都是非X86平台。host编译得到的可执行代码在target上运行。

1.5 如何进行交叉编译:

  • 交叉编译需要用到工具,一般称作为:交叉编译器或者交叉编译工具链

二、交叉编译工具链的安装

2.1 下载交叉编译工具:

  • 我们交叉编译工具链的安装应该是在宿主机上,也就是我们的Linux虚拟机,在宿主机上编译出能在树莓派ARM平台上运行的程序

  • 树莓派交叉编译工具链下载地址:[GitHub - raspberrypi/tools](https://github.com/raspberrypi/tools)

https://github.com/raspberrypi/tools

然后把我们下载下来的压缩文件通过FileZilla上传到我们的虚拟机上面:

 然后使用下面指令解压:

unzip tools-master.zip

解压之后我们进入下面这个路径下:

进入到该路径后我们可以看到:arm-linux-gnueabihf-gcc这个软链接是指向arm-linux-gnueabihf-gcc-4.8.3的,软链接是不占内存的,作用就是指向真正的可执行程序,在使用中就可以使用软链接的名字来调用真正的可执行程序。  

 所以arm-linux-gnueabihf-gcc就是我们树莓派的交叉编译工具链,使用和gcc是一样的,比如:XXX.c,编译的语句是:

./arm-linux-gnueabihf-gcc XXX.c 	//只不过把“gcc”替换成了“./arm-linux-gnueabihf-gcc”

2.2 将交叉编译工具链添加到环境变量:

现在我们已经拥有了交叉编译工具链,我们知道我们的交叉编译工具链在下面这个路径下:

/home/shiyahao/lessonPi/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin

我们在编译的时候还要将这么长的路径加到我们交叉编译之前,就会让我们的编译变得非常的繁琐和麻烦,我希望我们在使用这个交叉编译工具链的时候可以像gcc那样,不管在什么路径下都可以编译,这样就得配置环境变量了

2.2.1 临时有效的添加环境变量:

临时的添加环境变量,其实在前几节学习动态库的制作时就有提到过,那就是使用export,临时的意思就是“仅在添加完环境变量后的当前窗口有效”,也就是说如果再开一个窗口就又识别不到新添加的环境变量了。

  • 使用下面指令查看当前的环境变量:

echo $PATH

这一长串中:前面的/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games: 是不变的,然后使用下面指令来添加我们新的环境变量:

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:想要添加的路径
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/home/shiyahao/lessonPi/tools-master/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin

运行之后我们退回到根目录下,也就是/home/shiyahao下,然后输入下面指令:

arm-linux-gnueabihf-gcc-4.8.3 -v		//-v查看编译信息

我们可以看到在其他路径下我们可以暂时使用交叉编译器了,此时我们新开一个终端窗口,再次输入arm-linux-gnueabihf-gcc -v就无法识别了,所以这个环境变量只能临时有效。

2.2.2 永久有效的添加环境变量:

临时有效虽然一句命令就能搞定,但是有风险,因为终端随时可能关闭,然后添加的临时环境变量就失效了,所以还是学习一下如何一劳永逸的修改环境变量:

  • 修改工作目录下的 .bashrc 隐藏文件(该文件用于配置命令终端的

vi /home/shiyahao/.bashrc

然后在文件的末尾添加我们的交叉编译工具链的路径:

其实,bashrc隐藏文件 就是一个脚本,永久有效的核心思路就是通过脚本自动运行export,和动态库写脚本写export的思路是一样的。

  • 然后运行下面指令,用于加载配置文件,生效配置

source /home/shiyahao/.bashrc

 此时我们再开一个新的终端,并运行arm-linux-gnueabihf-gcc-4.8.3 -v

可见,这样就永久有效的将交叉编译器的目录添加到了环境变量中去了!

三、交叉编译实战

3.1 交叉编译实战(一):

现在在我们的宿主机的根目录下有一个hello.c文件,我们通过gcc编译器编译出可以在本机X86平台上运行的程序,我们可以通过下面指令查看:

file 程序名

我们可以看到这个程序只能在X86-64平台上运行,是不能在我们的树莓派ARM平台上运行的,我们想要在我们的树莓派ARM平台上运行,我们就得用基于树莓派ARM平台的交叉编译器来编译arm-linux-gnueabihf-gcc-4.8.3

 我们看到编译出来的程序是在ARM平台上运行的,我们把它拷贝到树莓派上,指令如下:

scp hello_2 pi@192.168.31.123:/home/pi

可以看到我们交叉编译的程序成功在树莓派上运行

3.2 交叉编译实战(二):

  • 现在我们尝试把我们之前的FTP云盘项目中的客户端交叉编译到我们的树莓派上运行,我们的虚拟机运行服务器程序,让宿主机和树莓派实现FTP通信。

  • 这是我们之前的FTP云盘的项目:

    [Linux系统编程项目——FTP网盘](https://blog.csdn.net/weixin_54859557/article/details/139939604?spm=1001.2014.3001.5502)

arm-linux-gnueabihf-gcc-4.8.3 clientFTP.c -o RaspberryclientFTP		//交叉编译FTP客户端代码
file RaspberryclientFTP												//产看文件属性
scp RaspberryclientFTP pi@192.168.31.123:/home/pi					//将我们交叉编译出来的程序上传到树莓派

 可以看到我们成功的交叉编译了FTP的客户端程序,并成功在树莓派上运行,实现了宿主机和树莓派之间的FTP通信

四、带WiringPi库的交叉编译实战

在之前的交叉编译实战中,成功的将Ubuntu虚拟机上面的代码交叉编译成了能够在树莓派上运行的程序,但是之前的交叉编译代码不需要链接库,如果代码包含了WiringPi库或者线程库,那么在gcc编译时就需要链接库,对于这种需要链库的C代码进行交叉编译不能直接无脑的在“arm-linux-gnueabihf-gcc XXX.c”后加上“-lwiringPi”,其原因是库文件也是当前平台下的文件,并不能被树莓派平台所识别!

  • 首先先将我们的WiringPi库上传或者下载到我们的根目录(home/CLC)下:

  • 然后进入这个文件夹后,运行build安装:

  • /usr/local/lib/路径下就可以看到这个wiringPi的动态库:

  • 通过file指令查看文件属性:

可以看到这个动态库只能在当前平台(X86-64)上运行,是不能在我们的ARM树莓派平台上运行的,所以我们这里有两种方法:

4.1 交叉编译WiringPi库:

既然这个库文件无法被树莓派平台识别,那就先交叉编译库文件,再链库并交叉编译代码,但是对于动态库的交叉编译和之前的方法可能不同,所以这种方法暂时不展开。

4.2 把树莓派的WiringPi库拿来

4.2.1 将树莓派的libwiringPi.so.2.52上传到虚拟机:

直接把树莓派上面使用的WiringPi拿过来也可以解决我们的问题:

cd /usr/lib		//进入树莓派/usr/lib目录下
ls				//查看当前目录下的文件

然后通过file指令查看该文件的属性:

 然后通过下面指令发送到我们的虚拟机上面:

scp /usr/lib/libwiringPi.so.2.52 CLC@192.168.31.90:/home/CLC/lessonPi

4.2.2 创建软链接:

参考文章:Linux创建连接命令 ln -s创建软连接 - 张娜nana - 博客园 (cnblogs.com)

  • 软链接的概念:

  1. 软链接文件有类似于Windows的快捷方式。

  2. 在符号连接中,文件实际上是一个文本文件,其中包含的有另一文件的位置信息。

  3. 你选定的位置上生成一个文件的镜像,不会占用磁盘空间

  • 硬链接的概念:

  1. 它会在你选定的位置上生成一个和源文件大小相同的文件

  • 硬链接如何生成:

ln libwiringPi.so.2.52 libwiringPi.so
  • 软链接如何生成:

ln -s libwiringPi.so.2.52 libwiringPi.so 
指令 参数   要被链接的文件    软链接文件名字

然后再通过file命令查看一下虚拟机的libwiringPi.so.2.52的文件属性:

确实是树莓派ARM平台上的WiringPi动态库

4.2.3 交叉编译:

现在有了树莓派ARM平台上的WiringPi库,可以尝试交叉编译带有WiringPi库的C代码了,比如下面这个代码:

#include <stdio.h>
#include <wiringPi.h>
 
#define BEEP 7
 
int main (void)
{
 
	wiringPiSetup () ; //初始化wiringPi库
 
	pinMode (BEEP, OUTPUT); //配置输入输出模式
 
	while(1){
		digitalWrite (BEEP, LOW) ;	//蜂鸣器响
		delay (1000) ;		// mS
 
		digitalWrite (BEEP, HIGH) ;	//蜂鸣器不响
		delay (1000) ;
	}
 
	return 0;
}

 然后使用下面指令进行交叉编译:

arm-linux-gnueabihf-gcc beep.c -L ./ -lwiringPi -I /home/CLC/WiringPi/wiringPi -o BEEP
  • 使用“-L ”:指定动态库的优先查找目录为当前目录

  • 使用“-I”(大写i):指定头文件的优先查找目录为/home/mjm/WiringPi/wiringPi

我们在编译的时候出错了,然后重新向虚拟机导入版本2.50的wiringPi动态库,然后重新生成软链接,然后在编译就OK了

使用下面指令将交叉编译出来的BEEP程序上传到树莓派:

scp BEEP pi@192.168.31.123:/home/pi/waishe

然后在树莓派上成功运行,蜂鸣器开始了滴滴声


http://www.kler.cn/news/304757.html

相关文章:

  • 【Web】URI和URL的介绍
  • STM32CubeIDE关于printf()串口输出重定向的问题
  • 『功能项目』项目优化 - 框架加载资源【41】
  • 在 macOS 上管理 Node版本
  • 计算机存储概念
  • python numpy pytorch tensorlfow list 转tenser float 32的方法,模型计算基本用的都是float32,需要转换
  • 常见本地大模型个人知识库工具部署、微调及对比选型
  • mac上Charles怎么配置,可以抓取浏览器/IDEA的接口
  • 【getshell】phpmyadmin后台getshell(4.8.5)
  • springboot+security为什么@ControllerAdvice自定义的异常处理没有生效
  • 怎么去浮毛比较高效?热门除浮毛宠物空气净化器希喂、范罗士、有哈测评推荐
  • Linux与Ubuntu:内核与发行版的关系
  • MinGW-w64全面讲解:Windows平台的C/C++编译利器
  • Qt控制开发板的LED
  • openCV的python频率域滤波
  • 唯品会大数据面试题及参考答案(3万字长文)
  • C到C++入门基础知识
  • Linux环境基础开发工具---yum
  • Numpy 单位矩阵创建 eye()函数详解
  • 如何管理付费媒体预算:分配、风险与扩展
  • 企业数字化转型建设方案(数据中台、业务中台、AI中台)(可编辑的188页WORD)
  • 助力汽车半导体产业发展,2025 广州国际新能源汽车功率半导体技术展览会与您相约“羊城”广州
  • pm2 进程守护python flask
  • 《订单来了2024中秋预订趋势报告》发布:截至9月13日,商家中秋预订率上涨42.73%,山西文化巡礼成顶流
  • 2024年8月HarmonyOS鸿蒙应用开发者高级认证全新题库
  • JavaScript --函数的作用域(全局和局部)
  • Java面试篇基础部分-垃圾回收算法
  • 科研定制化无人机硬件技术详解
  • Leetcode面试经典150题-141.环形链表
  • CSP-J 算法基础 深度优先搜索