交叉编译是什么,为什么要交叉编译
交叉编译是什么
- 交叉编译是在一个平台上生成另一个平台上的可执行代码
- 如在windows上写代码,放到keil上生成C51和stm32上可执行的代码
- 在ubuntu上面编写ARM架构的代码,并编译成相应ARM架构可执行的代码,是在对应架构上面运行,不是在Ubuntu Linux上面运行
- 编译:是在一个平台上生成在该平台上的可执行代码
为什么要交叉编译
- 平台上不允许或者不能够安装我们所需要的编译器,如C51
- 因为目的平台上资源匮乏,无法运行我们所需要的编译器
- 树莓派、香橙派等的资源充足,那么是不是就不需要交叉编译了?
- 错误的,也需要,因为其目的平台还没建立,连操作系统都没有,根本谈不上运行什么编译器。操作系统也是代码,也要编译
- 平台运行至少两样东西:bootloader(启动引导代码)和操作系统核心
宿主机和目标机
- 宿主机(host):编辑和编译程序的平台,一般是基于X86的PC机,也称为主机
- 目标机(host):用户开发的系统,通常是非X86平台,host编译得到的可执行代码会在target上运行
交叉编译需要用到工具
交叉编译器、交叉编译工具链
交叉编译工具链的安装
对于orangepizero2有两种方式:
- 直接从清华源下载相应的交叉编译工具
- 这一条路线中,Linux的系统版本一定要对上,否则会发生什么,我也不知道。通过香橙派官方给的手册,获取源码的方式进行下载:如果需要下载u-boot、相应Linux镜像、 和Linux内核的可以参考如下:以编译Linux内核为例子,同时,设定相应环境变量也可以参考,如下
http://t.csdn.cn/8PlVv
交叉编译例子:不带静态库
demo代码
#include <stdio.h>
int main()
{
printf("hello\n");
return 0;
}
编译
宿主机
- 宿主机编译:
gcc demo1.c -o x86demo1
- 目标机编译:
aarch64-none-linux-gnu-gcc demo1.c -o armdemo1
目标机
- 将宿主机中编译好的可执行代码通过
scp
命令发到目标机中:scp x86demo1 orangepi@192.168.31.75:/home/orangepi/test
scp
为命令x86demo1
为要发送的文件名称orangepi
为目标机用户名192.168.31.75
为目标机的IP地址/home/orangepi/test
:为要放到目标机的哪个文件夹下面- 通过 SSH 协议安全地将文件复制到远程系统和从远程系统复制文件到本地的命令。使用 SSH 意味着它享有与 SSH 相同级别的数据加密,因此被认为是跨两个远程主机传输文件的安全方式。
带静态库的交叉编译:以wiringPi
库和香橙派为例子
步骤
- 正常我们先要交叉编译
wiringPi
库,编译出适合香橙派的库,然后再进行编译- 通过
-I
指定先从哪一个文件夹中查找头文件;通过-L
指定库文件的搜索路径:链接了某一个三方库,那么就去-L指定的路径下搜索这个库
- 通过
- 为了方便,直接从香橙派中将库文件
scp
下来- 参考前面,将
libwiringPi.so
文件scp
到宿主机 ln -s libwiringPi.so.2.46 libwiringPi.so
:创建软连接(如果要创建硬链接,那么删掉-s就行)- 软链接创建的相当于是一个镜像,类似于win里面的快捷方式,不占内存空间
- 硬链接是会占据空间的,是在选定的位置上生成一个和源文件大小相同的文件
- 相同点在于,两者都会随着源文件同步变化
- 编写代码
- 交叉编译:
aarch64-none-linux-gnu-gcc relay.c -I ./WiringPi/wiringPi -L. -lwiringPi
- 这里注意宿主机上要有wiringPi库
scp
发到目标机上面运行即可
博主使用的wiringPi库
已经上传到了csdn,0积分下载
https://download.csdn.net/download/GS8FG/87818459
示例代码
#include <stdio.h>
#include <wiringPi.h>
#include <string.h>
#define IN1 8
#define IN2 7
#define IN3 5
#define IN4 2
int main(void)
{
if(wiringPiSetup() == -1){
printf("wiringPiSetup() error\n");
return -1;
}
char buf[20]={0};
pinMode(IN1,OUTPUT);
digitalWrite(IN1,HIGH);
pinMode(IN2,OUTPUT);
digitalWrite(IN2,HIGH);
pinMode(IN3,OUTPUT);
digitalWrite(IN3,HIGH);
pinMode(IN4,OUTPUT);
digitalWrite(IN4,HIGH);
while(1){
memset(buf,'\0',strlen(buf));
printf("输入控制:0 or 1\n");
gets(buf);
if(!strcmp(buf,"1 off")){
digitalWrite(IN1,HIGH);
}else if(!strcmp(buf,"1 on")){
digitalWrite(IN1,LOW);
}else if(!strcmp(buf,"2 off")){
digitalWrite(IN2,HIGH);
}else if(!strcmp(buf,"2 on")){
digitalWrite(IN2,LOW);
}else if(!strcmp(buf,"3 off")){
digitalWrite(IN3,HIGH);
}else if(!strcmp(buf,"3 on")){
digitalWrite(IN3,LOW);
}else if(!strcmp(buf,"4 off")){
digitalWrite(IN4,HIGH);
}else if(!strcmp(buf,"4 on")){
digitalWrite(IN4,LOW);
}else {
printf("cmd error\n");
}
}
return 0;
}