无极网站网站涉案多少人被抓,网站投票系统怎么做,成都建筑公司排名前十,长沙网站建设及推广公司目录
交叉编译的初认识QA
Q1: 编译是什么#xff1f;
Q2: 交叉编译是什么#xff1f;
Q3: 为什么要交叉编译
Q3.1#xff1a;树莓派相对于C51大得多#xff0c;可以集成编译器比如gcc#xff0c;那么树莓派就不需要交叉编译了吗#xff1f;
Q4: 什么是宿主机和…目录
交叉编译的初认识QA
Q1: 编译是什么
Q2: 交叉编译是什么
Q3: 为什么要交叉编译
Q3.1树莓派相对于C51大得多可以集成编译器比如gcc那么树莓派就不需要交叉编译了吗
Q4: 什么是宿主机和目标机
Q5: 如何进行交叉编译 交叉编译器/工具链 的安装 将交叉编译器/工具链添加到环境变量
临时有效的添加环境变量
永久有效的添加环境变量
交叉编译实战
使用以下指令交叉编译客户端的代码 使用以下指令将交叉编译生成的可执行文件下载到开发板
实现效果
带wiringPi库的交叉编译实战
方法1交叉编译wiringPi库
方法2把树莓派的wiringPi库拿来
创建软链接
软硬链接概念补充
交叉编译 交叉编译的初认识QA
Q1: 编译是什么
A: 在一个平台上生成该平台的可执行代码 Q2: 交叉编译是什么
A: 交叉编译是在一个平台上生成另一个平台上的可执行代码 其实在之前学习C51的时候就需要交叉编译。只不过对于C51交叉编译的发生在keil集成环境上。其 实质就是在windows平台上编译C51平台的可执行代码。 Q3: 为什么要交叉编译
A: 因为平台上不允许或不能够安装所需要的编译器比如C51很小如果再集成编译器会浪费大量资源甚至根本就无法安装。 Q3.1树莓派相对于C51大得多可以集成编译器比如gcc那么树莓派就不需要交叉编译了吗 A并不是树莓派也需要交叉编译。因为树莓派也是从无到有的在树莓派的操作系统还不存在的时候根本就无法运行什么编译器但是操作系统的本质也是代码所以操作系统也是需要通过编译才能在树莓派上运行的这就不得不在另一个平台编译生成树莓派的可执行代码而这就是交叉编译。接下来的学习中我即将在Linux平台上编译可以在树莓派中执行的代码 PS平台运行至少需要两样东西bootloader 启动引导代码以及 操作系统核心 Q4: 什么是宿主机和目标机
A: 简单来说比如在UBUNTU-Linux平台交叉编译树莓派的可执行代码那么UBUNTU就是宿主机树莓派就是目标机。
宿主机host编辑和编译程序的平台一般是基于X86的PC机通常也被称为主机目标机target用户开发的系统通常都是非X86平台。host编译得到的可执行代码在target上运行 Q5: 如何进行交叉编译
A: 交叉编译需要用到工具一般称作交叉编译器或交叉编译工具链 交叉编译器/工具链 的安装 现在我的目的是在Ubuntu-Linux平台上交叉编译生成树莓派平台上的可执行代码 由于树莓派是作为目标机的所以安装树莓派相对应的交叉编译器/工具链而安装的平台则应该是宿主机也就是Linux虚拟机 在这个网址下载工具链GitHub - raspberrypi/tools 复制网址然后打开虚拟机使用以下命令用git clone来下载
git clone https://github.com/raspberrypi/tools.git 我尝试过直接“Download ZIP” ,但是下载下来的内容是缺少的且windows会报同名文件的错我猜测是因为windows系统下对大小写的文件名不敏感导致的总之就是很麻烦还是使用git clone省心。 下载好之后依次进入tools - arm-bcm2708 - gcc-linaro-arm-linux-gnueabihf-raspbian-x64 - bin 图中浅蓝色文件代表的是“软链接”我们需要用到的交叉编译器就是浅蓝色的“arm-linux-gnueabihf-gcc”通过“ls -l” 可见这个“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” 将交叉编译器/工具链添加到环境变量
现在已经拥有了交叉编译器并且知道了大概如何编译。
但是每次使用这个编译器都需要cd到“/home/mjm/ras_CrossCompile/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin”下或在编译的时候就把这个路径加在编译器前面非常的繁琐复杂我希望在使用交叉编译器的时候能和使用gcc一样不管在什么路径都可以直接打出来这就要使用到环境变量了。 临时有效的添加环境变量
临时的添加环境变量其实在前几节学习动态库的制作时就有提到过那就是使用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/mjm/ras_CrossCompile/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin 运行后退回工作目录输入“arm-linux-gnueabihf-gcc -v”:“-v”查看编译器信息 可见此时在其他目录下也可以暂时使用交叉编译器了
此时新开一个终端再次输入“arm-linux-gnueabihf-gcc -v” 可见无法识别所以export确实只能临时有效。 永久有效的添加环境变量
临时有效虽然一句命令就能搞定但是有风险因为终端随时可能关闭然后添加的临时环境变量就失效了所以还是学习一下如何一劳永逸的修改环境变量
修改工作目录下的 .bashrc 隐藏文件该文件用于配置命令终端的
vi /home/mjm/.bashrc 然后在文件的最后一行加上刚刚的export指令 其实bashrc隐藏文件 就是一个脚本永久有效的核心思路就是通过脚本自动运行export和动态库写脚本写export的思路是一样的。
然后运行“source /home/mjm/.bashrc” 加载配置文件生效配置 此时再开一个新的终端并运行“arm-linux-gnueabihf-gcc -v” 可见这样就永久有效的将交叉编译器的目录添加到了环境变量中去了 交叉编译实战
现在尝试将之前博文实现的服务器客户端聊天代码中的服务器端代码交叉编译到树莓派平台 Linux socket网络编程实战tcp实现双方聊天_linux网络编程 聊天_mjmmm的博客-CSDN博客 服务器和客户端的代码分别是“/home/mjm/NET”下的“server_final.c”和“client_final.c” 使用以下指令交叉编译客户端的代码
arm-linux-gnueabihf-gcc server_final.c -o server_from_linux 在一开始编译的时候报了巨量的错误 经过查证我认为主要是头文件的重定义在server_final.c中将“netinet/in.h”和“linux/in.h”两个头文件注释掉就好了 然后可以执行“file server_from_linux” 来查看文件属性 可见相比于原来ubuntu下的可执行文件经过交叉编译后的可执行文件的属性发生了改变 使用以下指令将交叉编译生成的可执行文件发送到开发板
scp server_from_linux pi192.168.2.26:/home/pi/mjm_code
//指令 文件名 开发板用户名开发板地址开发板的绝对路径 然后使用Moba连接到树莓派 可见文件成功发送到了树莓派 实现效果
//在树莓派上
./server_from_linux 192.168.2.26 8888//在ubuntu-linux虚拟机上
./client 192.168.2.26 8888可见经过交叉编译的可执行代码成功在树莓派平台运行 但是我发现如果把客户端交叉编译发送到树莓派虽然也可以运行但是无法和虚拟机的服务端连接。也就是说树莓派只能做服务端不能做客户端因为树莓派没法连接到虚拟机的IP。 所以我尝试了ping发现 虚拟机可以ping通树莓派和主机树莓派可以ping通主机主机可以ping通树莓派和虚拟机唯独树莓派没法ping通虚拟机 解决办法 断开电脑的宽带连接局域网能Ping通之后可以改回来将虚拟机的网络设置从NAT改为桥接在VMWare左上的“编辑”里选择“虚拟网络编辑器”然后修改“已桥接到”后的选项框选择我电脑的网络“Media Tek WI-FI 6 MT7921 Wireless LAN Card” 此时再次打开虚拟机先输入ifconfig来查看IP切换网络设置之后IP会变 然后在树莓派尝试ping这个地址 成功ping通此时将虚拟机linux平台的client端代码交叉编译并上传到树莓派试运行 成功运行此时树莓派成功作为客户端连接到了虚拟机的ubuntu-linux平台并且此时可以断开电脑的局域网换回宽带了 带wiringPi库的交叉编译实战
在刚刚的交叉编译实例中成功的将ubuntu-linux环境下的代码交叉编译成为了可以在树莓派上运行的arm-linux可执行文件。
但是刚刚交叉编译的代码在编译时不需要链库如果代码包含wiringPi或线程库里的函数那么在gcc编译时就需要链库对于这种需要链库的C代码进行交叉编译不能直接无脑的在“arm-linux-gnueabihf-gcc XXX.c”后加上“-lwiringPi”其原因是库文件也是当前平台下的文件并不能被树莓派平台所识别
先将wiringPi库下载到/home/mjm下 然后运行“./build”安装 然后再“/usr/local/lib” 下就可以看到这个wiringPi的动态库 通过“file /usr/local/lib/libwiringPi.so”查看文件属性 发现是个软链接指向“libwiringPi.so.2.46” 那就对它再file一下 可见的确是当前平台下的格式显然在树莓派上是无法运行的。 方法1交叉编译wiringPi库
既然这个库文件无法被树莓派平台识别那就先交叉编译库文件再链库并交叉编译代码。
但是对于动态库的交叉编译和之前的方法可能不同所以这种方法暂时不展开。 方法2把树莓派的wiringPi库拿来
直接把能在树莓派平台上使用的wiringPi库拿来也可以解决问题。
在树莓派中的依次从/lib--/usr/lib--/usr/local/lib找wiringPi库然后在/usr/lib下找到了 有了刚刚的经验这个估计也是个软链接使用file看一下 果然是指向libwiringPi.so.2.52的软链接所以应该发送到虚拟机的是这个库文件。
通过scp命令发送给虚拟机
scp ./usr/lib/libwiringPi.so.2.52 mjm192.168.2.27:/home/mjm/ras_CrossCompile 虚拟机要先“sudo apt-get install openssh-server”安装ssh服务才能支持scp文件传输 创建软链接
在得到wiringPi的动态库后我们也可以学着对其创建一个名称更加简洁的软链接 软硬链接概念补充 参考https://www.cnblogs.com/zhangna1998517/p/11347364.html 软链接的创建通常使用“ln -s 被链接对象 软链接文件名”指令会在选定的位置上生成一个被链接对象的镜像且不会占用磁盘空间类似于Windows下的快捷方式。软链接也叫符号连接在符号连接中文件实际上是一个文本文件其中包含的有另一文件的位置信息软链接相对应的就是硬链接通常使用“ln 被链接对象 硬链接文件名”指令创建没有参数-s会在选定的位置上生成一个和被链接对象大小相同的文件不管是软链接还是硬链接创建的镜像/文件都会随着链接对象的变化而同步变化 使用以下指令创建软链接
ln -s libwiringPi.so.2.52 libwiringPi.so
//指令 参数 要被链接的文件 软链接文件名字
创建好之后可以file一下 可见软链接创建成功
再使用file查看一下 确实是树莓派平台下的wiringPi动态库 交叉编译
现在有了树莓派平台下的wiringPi库可以开始尝试交叉编译带有wiringPi库的C代码了
先写一段符合要求的即带wiringPi库的代码
beep.c
#include stdio.h
#include wiringPi.h#define BEEP 7int main (void)
{wiringPiSetup () ; //初始化wiringPi库pinMode (BEEP, OUTPUT); //配置输入输出模式while(1){digitalWrite (BEEP, LOW) ; //蜂鸣器响delay (1000) ; // mSdigitalWrite (BEEP, HIGH) ; //蜂鸣器不响delay (1000) ;}return 0;
}然后使用以下指令交叉编译
arm-linux-gnueabihf-gcc blink.c -L ./ -lwiringPi -I /home/mjm/WiringPi/wiringPi -o blink_from_linux
使用“-L ”指定动态库的优先查找目录为当前目录使用“-I”大写i指定头文件的优先查找目录为/home/mjm/WiringPi/wiringPi 编译时报错 解决办法 重新向虚拟机导入版本2.50的wiringPi动态库 删除之前的软链接然后重新设置软链接 再次尝试编译 成功编译没有报错 最后使用scp发送到树莓派
scp blink_from_linux pi192.168.2.26:/home/pi/mjm_code 然后在树莓派尝试运行
成功运行蜂鸣器以固定间隔开始发出声音。