【交叉编译】Python和C++程序的平台移植教程,x86-Linux到ARM-Linux_linux使用python需要交叉编译吗-程序员宅基地

技术标签: 交叉编译  arm-linux  移植  教程  

最近实验室在搞一个嵌入式开发的项目,需要将Linux上编写的程序移植到ARM开发板上,由于之前也并没有做过这个方面,所以踩了不少的坑,这里把完整过程记录下来,供后来人参考。

一、交叉编译原理

在本教程的开头,我先大致给大家说明一下交叉编译的原理以及为什么要进行交叉编译,为后来大家在看教程的时候做一个铺垫,当后面遇到问题的时候也会有解决的思路。

什么是交叉编译?

交叉编译说白了就是要在一个架构平台上编译另一个架构平台可以运行的可执行文件或者动态链接库。由于不同架构下的指令集不同,所以在这个平台下 编译出的机器代码在另一种指令集上是无法运行的,动态链接库也一样,所以这就需要用到交叉编译了。

为什么要有交叉编译

有人可能会说,直接在另一台机器上也安装一台编译器不就完事了。我只能说你很机智!但是这里需要考虑两个问题。

一个是开发板性能的问题,一般来说,我们用于嵌入式开发的开发板性能都是不如电脑主板的,有些大型的程序,比如机器学习的,在开发板上编译是要花费很长时间的,甚至开发板的配置不足以支持我们编译,这种时候就需要考虑交叉编译 了。

另一个就是编译难度的问题,众所周知,在Linux下进行大型C项目的开发是离不开Makefile的,如果你现在已经有了x86-Linux平台下的全部项目工程,想把他移植到ARM-Linux下,你要么选择重新编写ARM平台下的Makefile,要么选择进行交叉编译,对于小型项目当然重写一个没问题,但如果开发的是大型的项目的话,重新编写Makefile就得不偿失了。

交叉编译大体思路

对于交叉编译,不同的人可能有不同的做法。在我的项目中,我是选择用交叉编译工具链来进行,这样可以比较快速的对已有项目进行移植。

大体思路如下:首先阅读你的Makefile文件 ,找到其中定义编译器的地方,将其改为你需要用的交叉编译工具链(一定要全部改过来),然后参数可以先不动,运行相应make命令,得到可执行文件或动态链接库。

感觉好像听起来很简单的样子,但我估计大多数还在看教程的小伙伴还是不知道怎么做的,下面我就具体讲一下我这个项目中的做法以及中途遇到的一些坑。

二、利用交叉编译,移植Python和C工程

Python移植

首先我觉得有些人可能会对移植Python有疑问,这里我作简单的解释,在交叉编译的时候,其实Python就是一个用C/C++编写好的一个工程,不要把他看成Windows下的应用程序,这样的话你就好理解了,说是移植Python,其实就是把一大堆C/C++代码编译成ARM平台上可以使用的可执行文件而已。

关于Python的移植,我在这里就不多说了,因为我也是参照别人的博客来搞的(其实搞了半天,最后发现我的板子上本来就有自带的Python 3.5,哭辽)。博客链接如下:
                                                                ARM40之Python3.6.4移植

这里我要着重说一下交叉编译工具链的选择问题,这也是我踩过的一个坑,大家不要以为每一个工具链都是一样的,对不同的要求,是需要选择不同的工具链的。对于64位的ARM平台,可以使用aarch64-linux-gnu-gcc,对于32位的ARM平台,可以使用arm-linux-gnueabi-gcc,对于下面的过程也一样需要考虑工具链的选取!!!

哦哦,还有一个,如果你不会安装交叉编译工具链的话,可以参考以下博文,不需要考虑版本的问题,安装过程都一样!

C/C++工程移植

首先一个前提是,你需要提前编写好工程的Makefile文件,如果你的工程压根不需要编写Makefile进行编译,那就直接放到板子上编译就好了,也就不用往下看了(很皮)。

然后,就是需要把你原来的gcc or g++编译器,修改为相应的交叉编译链命令,直接make,如果你是个lucky dog的话,那恭喜你,交叉编译已经完成了!但是一般情况下是不会那么顺利的。下面我就只给大家指出几个坑点,如果有人踩坑了,可以照着检查修改以下。

  • 第一个可能会出错的地方,编译选项。对于编译选项的问题,一般情况下,是不需要考虑的,因为编写交叉编译工具链的人都给你考虑过了,但有些也不行,比如x86平台下gcc的-m64选项,可以将程序编译为64位平台下运行的程序,但它就无法用于arm-linux-gnueabi-gcc中。但遇到这种问题也不要慌,一般你去stack overflow上,总有人会和你遇到同样的问题。
  • 第二个可能会出错的地方,开发板位数的问题。上面也提到过,这里再次强调一下,一定要注重交叉编译工具链的选择,如果选择不对,不仅会浪费你大量的时间,而且还会把你心态搞崩…我就是一个很好的例子。
  • 第三个可能会出错的地方,makefile隐藏规则的问题。用过makefile的人都知道,makefile为了让人们可以省一点力气,有一些隐藏规则,但在交叉编译的时候,可就难受了,这里我仅举一个例子:对于makeifle,如果你不写 %.o : %.c的话,其默认会将.c或者.cpp文件编译成同名的目标文件.o文件,但这个过程,如果使用默认编译的话,在你不指明的情况下,其用的是系统默认的gcc编译,所以在你交叉编译的时候,就会看到你虽然为其他编译制定了使用交叉编译器,但还是有那么一些命令运行的是gcc编译的,也就会导致之后的错误。

我暂时遇到的坑点也就这些了,如果大家遇到什么其他问题,欢迎在评论区和我讨论,我也会尽力去帮助大家的!!

三、更高级的工具–cmake

话说到了这里应该就要结束了,但是我还是不甘心,为什么这个东西要这么费劲,就没有一种省事的办法吗?

经过我百般调研,功夫不负有心人,我了解到一个工具,好像确实可以解决跨平台编译的问题,那就是cmake,有兴趣的同学可以自行了解一下,这里我就大致进行一下解释,谁让我都提出来了呢!(虽然我也是刚入门)

cmake就是一种可以自行生成Makefile的脚本语言,可想而知,我之前提到的第二个问题就可以解决了!对于不同平台,你只需要安装cmake,然后编写一个CMakeLists.txt,就可以在不同的平台下,生成对应的Makefile文件,是不是很6?当然前提是你要把cmake写的好。

但如果板子的性能不足的话,那也没办法,还是老老实实地交叉编译吧!!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_38055352/article/details/89055159

智能推荐

Android音视频技术1--Android SurfaceView使用_surfaceview 首帧渲染回调-程序员宅基地

文章浏览阅读283次。开篇提到视频数据源渲染提到过SurfaceView,SurfaceView是Android提供的渲染图形类。一.SurfaceView简介Android平台图形渲染类。 主要由于游戏场景,适合频发绘制刷新的View。 Surfaceview可用于工作线程刷新View。 普通View为被动刷新,主动刷新则选择SurfaceView。二.SurfaceView与View的区别Sur..._surfaceview 首帧渲染回调

SpringMVC_@ControllerAdvice_springmvc controlleradvice-程序员宅基地

文章浏览阅读133次。SpringMVC_@ControllerAdvice一.全局异常处理二.全局数据绑定三.全局数据预处理新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表F..._springmvc controlleradvice

[LQR简要快速入门]+[一级倒立摆的LQR控制]-程序员宅基地

文章浏览阅读8k次,点赞34次,收藏127次。[LQR简要快速入门]+[一级倒立摆的LQR控制]1. 什么是LQR2. 公式含义3. 倒立摆的建模3.1 线性化3.2 状态空间建立4. LQR算法实现5. MATLAB代码仿真6. 优缺点1. 什么是LQRLQR是一种最优控制算法,简要讲即为寻求一种算法,使得在满足系统稳定性能的同时,系统在达到稳定的过程中消耗的能量也最少(具有实际意义)。利用最优控制理论的知识可以知道,既然要达到两个指标(1. 性能;2. 能量)的最优,可以很容易列出积分形式的最优指标:J=∫0∞(xTQx+uTRu)dt(1_lqr

anaconda: import numpy报错:ImportError: DLL load failed: 找不到指定的模块_anaconda import numpy 模块错误-程序员宅基地

文章浏览阅读795次。anaconda: import numpy报错:ImportError: DLL load failed: 找不到指定的模块在使用vscode 和anaconda时,在vscode中 import numpy,出现了以上报错可以查看是否未添加anaconda的环境变量具体参考如下文章,如何配置环境变量https://blog.csdn.net/Buster001/article/details/90025712..._anaconda import numpy 模块错误

c钩子库Minhook的使用_minihook使用 vs-程序员宅基地

文章浏览阅读5.4k次。简述最近在学习钩子库,逛了一下gay hub,发现了一个项目minhook,纯钩子库,甚合我意,就研究了一下,写了2个例子。后续打算研究一下这个钩子库的源代码,了解一下具体怎么实现的。例子例子就不贴到这上面了,给出github地址:minhook钩子库的使用示例例子vs2008编译通过,使用的dll,lib文件都是从minhook项目编译而来。minhook项目github地址..._minihook使用 vs

python 发布包_如何将自己的Python包发布到PyPI-程序员宅基地

文章浏览阅读150次。以前写过一篇类似的文章: 如何打包自己的项目并且发布到pypi上,不过由于PyPI进行了一些更新,因此旧方法不大适用了。趁端午有时间,想把haipproxy的客户端发布到PyPI,以改进用户体验,因此这次又尝试了如何将Python包发布到新版本的PyPI上。编写setup.py以haipproxy为例,它的setup.py如下from os import path as os_pathfrom s..._如何将python包推送到pipy

随便推点

RCE远程命令执行漏洞挖掘思路_rce漏洞挖掘-程序员宅基地

文章浏览阅读3.2k次,点赞3次,收藏19次。RCE漏洞存在的地方包括:在url参数上,文件下载处,在查看图片,查看文件等地方在文件删除上,SSRF可能存在的地方,变量参数提交的地方等_rce漏洞挖掘

[数据仓库]分层概念,ODS,DM,DWD,DWS,DIM的概念_ods层-程序员宅基地

文章浏览阅读10w+次,点赞118次,收藏518次。ODS是什么?ODS 全称是 Operational Data Store,操作数据存储.“面向主题的”,数据运营层,也叫ODS层,是最接近数据源中数据的一层,数据源中的数据,经过抽取、洗净、传输,也就说传说中的 ETL 之后,装入本层。本层的数据,总体上大多是按照源头业务系统的分类方式而分类的。但是,这一层面的数据却不等同于原始数据。在源数据装入这一层时,要进行诸如去噪(例如有一条数据中人的年龄是 300 岁,这种属于异常数据,就需要提前做一些处理)、去重(例如在个人资料表中,同一 ID 却有两条重复_ods层

Lucene介绍与使用-程序员宅基地

文章浏览阅读9.1w次,点赞237次,收藏928次。1、了解搜索技术1.1 什么是搜索简单的说,搜索就是搜寻、查找,在IT行业中就是指用户输入关键字,通过相应的算法,查询并返回用户所需要的信息。1.2 普通的数据库搜索类似:select * from 表名 where 字段名 like ‘%关键字%’例如:select * from article where content like ’%here%’结果: where here..._lucene

一个简单的协议定制_parseline-程序员宅基地

文章浏览阅读262次,点赞8次,收藏4次。socket、序列化和反序列化、自定义协议、一般服务器设计原则和各种场景_parseline

【RT-Thread】学习日记之系统节拍Tick_rt_tick_get-程序员宅基地

文章浏览阅读715次。RT-Thread 学习日记之系统节拍Tick_rt_tick_get

MySQL数据库——高级查询语句_mysql高级查询语句-程序员宅基地

文章浏览阅读5k次,点赞17次,收藏94次。数据库是用来存储数据,更新,查询数据的工具,而查询数据是一个数据库最为核心的功能,数据库是用来承载信息,而信息是用来分析和查看的。例:SELECT A.Store_Name Store, SUM(A.Sales) “Total Sales” FROM fxk003 A GROUP BY A.Store_Name;例:SELECT Store_Name, SUM(Sales) FROM fxk003 GROUP BY Store_Name HAVING SUM(Sales) > 1500;_mysql高级查询语句

推荐文章

热门文章

相关标签