一个例子了解交叉编译

2023-09-22 09:32:17

学习嵌入式Linux经常听到交叉编译这个名词,那到底什么是交叉编译,下面通过一个例子来介绍。
首先新建一个C文件,其代码如下。

#include "stdio.h"
void main()
{
    int a,b;
    int c;
    printf("请输入两个数:\n");
    scanf("%d%d",&a,&b);
    c=a+b;
    printf("a+b=%d\n",c);
}

这是一个很简单的C代码,下面通过GCC编译器先编译它,然后执行,结果如下图所示。
在这里插入图片描述
这个例子就是在X86架构的PC上新建了一个C文件并通过GCC编译器生成了一个在X86架构的PC上可以运行的可执行文件。
通过file命令查看这个可执行文件依赖的架构是X86,也就是说,这个可执行文件在X86架构下才能正确的执行。
在这里插入图片描述


接下来,如果我想在开发板上运行上面的文件,那么该怎么办呢?由于开发板是ARM架构的,而GCC编译器只能生成在X86架构上运行的可执行文件,因此要想在开发板上运行这个文件,就得在X86架构的PC上通过其他编译器生成可以在ARM架构下可以执行的文件。
首先下载安装交叉编译器,常用的Linaro GCC编译器下载:点此跳转
在这里插入图片描述
下载上面的交叉编译器后解压,然后修改环境变量,环境变量在/etc下的profile文件里修改,切换到root在该文件的最后添加下面的路径。
在这里插入图片描述
注意上面划红线的部分是我交叉编译器解压后的存放路径,你存放在哪替换就行,然后保存该文件退出,重启系统,交叉编译器就安装成功了。
使用交叉编译器之前还需要安装一下其它的库,使用到的命令如下。

sudo apt-get install lsb-core lib32stdc++6

查看交叉编译器的版本号如下图所示,说明安装成功了。
在这里插入图片描述


有了交叉编译器,就可以在X86架构的PC上生成可以在ARM架构上运行的可执行文件了,使用下面的指令实现这一功能。

arm-linux-gnueabihf-gcc a.c -o a_arm

指令中,arm表示这是编译arm架构代码的编译器,linux表示运行在linux环境下,gnueabihf表示嵌入式二进制接口,gcc表示编译工具。
使用上面的命令生成可执行文件后,在PC上运行后显示格式错误,如下图所示。
在这里插入图片描述
查看一下其可以运行的架构是ARM,如上图所示。
接下来把这个由交叉编译器生成的可执行文件通过网口连接发送到开发板,如下图所示。
在这里插入图片描述
为了验证,我把X86的可执行文件也一并发送到了开发板,执行的结果如下图所示。
在这里插入图片描述
可以看到,通过交叉编译器编译的可执行文件在开发板上成功的运行了,而通过GCC编译器编译的可执行文件在运行时也出现了格式错误。
看到这里相信大家看明白了什么是交叉编译,就是在一个架构上编译另外一个架构的代码。

更多推荐

对IP协议概念以及IP地址的概念进行简单整理

网络层重要协议参考模型和协议栈IP协议IPv4数据报IP数据报格式IPv4地址特殊IP地址私有IP地址和公有IP地址子网划分参考模型和协议栈IP协议IP协议定义了网络层数据传送的基本单元,也制定了一系列关于网络层的规则。IPv4数据报网络层的协议数据单元PDU叫做分组;网络层的传输单位叫做数据报。协议数据单元PDU是对

【Java】泛型 之 擦拭法

泛型是一种类似”模板代码“的技术,不同语言的泛型实现方式不一定相同。Java语言的泛型实现方式是擦拭法(TypeErasure)。所谓擦拭法是指,虚拟机对泛型其实一无所知,所有的工作都是编译器做的。例如,我们编写了一个泛型类Pair<T>,这是编译器看到的代码:publicclassPair<T>{privateTfi

分布式系统的 38 个知识点

天天说分布式分布式,那么我们是否知道什么是分布式,分布式会遇到什么问题,有哪些理论支撑,有哪些经典的应对方案,业界是如何设计并保证分布式系统的高可用呢?1.架构设计这一节将从一些经典的开源系统架构设计出发,来看一下,如何设计一个高质量的分布式系统;而一般的设计出发点,无外乎冗余:简单理解为找个备胎,现任挂掉之后,备胎顶

Layui快速入门之第十一节 弹出层

目录一:基本用法API打开弹层基础属性弹出信息框弹出询问框弹出提示框弹出加载层弹出贴士层弹出输入框弹出图片层弹出标签层关闭弹层关闭所有层关闭最近一次打开的层2.8+全局配置默认属性样式初始化就绪重新设置弹层样式设置弹层的标题获取iframe页中的元素在iframe页中获取弹层索引设置iframe层高度自适应重新设置if

go-GC垃圾回收

GCGC是自动化内存管理回收机制虚拟内存函数栈的数据是会根据函数返回而自动销毁的,而堆上的数据是不会随着函数自动销毁的,堆内数据会随着程序运行而逐渐变大,从而导致内存OOM,Go语言就用了GC来清理堆上的内存数据。如何区分垃圾堆上内存数据不在被栈上和数据段上的引用变量所指向,那就一定是内存垃圾。这个原理称为"可达性",

PostgreSql 统一修改date字段为timestamp

在《Powdersigner+PostgreSql同步表结构到pg数据库》中,导入表结构到pg数据后,发下时间对不上了。mysql的datetime转换后pg的变成了date了。再同步到数据后,就变成日期类型了。因为表中基本都有创建时间和修改时间,两个相对固定的字段,因此想做一个统一的处理。把《postgreSql使用

租用好服务器后怎么操作?

很多企业咨询完租用好服务器后都会有一些不知所措,不知道改如何操作,今天小编就跟大家讲一讲租用好服务器后要进行以下几个注意事项。修改系统以后要尽快修改服务器的密码,租用服务器后正规的IDC服务器商是会自主完成这一步骤的,重做系统后修改好的服务器密码一定要保存好。不随意下载。不能像普通电脑一拿到手就开始立刻下载各种软件、A

Lua学习笔记:词法分析

前言本篇在讲什么Lua的词法分析本篇需要什么对Lua语法有简单认知对C++语法有简单认知依赖VisualStudio工具本篇的特色具有全流程的图文教学重实践,轻理论,快速上手提供全流程的源码内容★提高阅读体验★👉♠一级标题👈👉♥二级标题👈👉♣三级标题👈👉♦四级标题👈目录♠前言♠luaL_dofile♠保

【STL容器】list

文章目录一、list定义二、list的迭代器三、list的元素操作四,list的优缺点一、list定义list本质是一个双向带头循环链表template<classT>structlist_node{list_node*prev;Tval;list_node*next;};template<classT>classli

数据结构与算法(C语言版)P3.2---链表之带头双向循环链表的实现

1、前言前面一章详细介绍了链表的概念、结构以及分类。并且实现了无头单向非循环链表。这一篇主要实现带头双向循环链表的。由于需要串联前面的知识,把上一篇至此:链表之无头单向非循环链表的实现2、带头双向循环链表的特性和结构2.1、结构(1)、每个结点有两个指针域(next,prev),一个数据域(data)。(2)前面结点的

cms之帝国cms安装

内容摘要帝国网站管理系统,英文名称为EmpireCMS,简称“帝国CMS”,本文将介绍帝国网站管理系统的安装方法。前言:本文安装教程是以帝国CMS7.5版本为基础进行图文讲解。各位看官,一定要按照每个步骤去执行,技术是以熟能生巧为主,在学习的过程中,要认真仔细的去做好每一步。关注我,手把手帮你搭建自己的小窝一、安装前准

热文推荐