Python交叉编译与移植到DVB平台

因为是在Hisi主芯片上移植Python,即主要在ARM嵌入式设备上运行Python,所以需要考虑交叉编译的问题,参考了网络上的一篇帖子《交叉编译Python3.6.2,使用海思arm-hisiv200-linux-gcc,移植到arm开发板上》

http://blog.csdn.net/zhy755788055/article/details/78001909

使用的是Python3.6.3压缩包,可到https://www.python.org/downloads/source/下载源码。

1、配置相关参数

因make编译完成后需运行make
install 把相关库与头文件及可执行程序放入目标目录,先建立一个文件夹用于存放最后生成的文件,也就是最后需要复制到开发板的所有内容。/home/lilm/Python3.6.3/arm_python,也就是为Python存放交叉编译结果的路径。

2、指定编译器及配置参数

当前Hisi3798平台使用SDK使用的相关编译器arm-histbv320-linux

完整的配置参数:

./configure CC=arm-histbv320-linux-gcc
CXX=arm-histbv320-linux-g++ AR=arm-histbv320-linux-ar
RANLIB=arm-histbv320-linux-ranlib

–host=arm-histbv320-linux

–build=arm

–disable-ipv6

ac_cv_file__dev_ptmx=no

ac_cv_file__dev_ptc=no
–prefix=/home/lilm/Python3.6.3/arm_python

3、编译Python3.6.3

执行make进行编译。编译成功后执行make
install,可在arm_python文件夹下看到bin include lib share四个文件夹。

当然,肯定没这么顺利的,下面就列举一系列编译时遇到的问题:

问题1:python3: error
while loading shared libraries: libpython3.6m.so.1.0: cannot open shared object
file

解决方法:

①编辑 vi
/etc/ld.so.conf

如非root权限帐号登录,使用 sudo vi /etc/ld.so.conf

添加上python3.6的lib库地址,如我的/usr/local/Python3.6/lib,保存文件

②执行 /sbin/ldconfig -v命令,如非root权限帐号登录,使用
sudo /sbin/ldconfig -v。

这样 ldd 才能找到这个库,执行python3.6就不会报错了

/etc/ld.so.conf:
这个文件记录了编译时使用的动态链接库的路径。

默认情况下,编译器只会使用/lib和/usr/lib这两个目录下的库文件。

如果你安装了某些库,没有指定 –prefix=/usr 这样lib库就装到了/usr/local下,而又没有在/etc/ld.so.conf中添加/usr/local/lib,就会报错了

③执行/sbin/ldconfi

ldconfig是个什么东东呢:

它是一个程序,通常它位于/sbin下,是root用户使用的东东。具体作用及用法可以man ldconfig查到,简单的说,它的作用就是将/etc/ld.so.conf列出的路径下的库文件 缓存到/etc/ld.so.cache 以供使用,因此当安装完一些库文件,(例如刚安装好glib),或者修改ld.so.conf增加新的库路径后,需要运行一下/sbin/ldconfig使所有的库文件都被缓存到ld.so.cache中,如果没做,即使库文件明明就在/usr/lib下的,也是不会被使用的,结果编译过程中抱错,缺少xxx库。

问题2:make install时”arm-linux-ranlib command not found”

解决方法:

执行make install之前,先用下sudo -i命令取得root权限。然后再执行make install。

su 和 sudo 的区别:

共同点:都是root用户的权限;

不同点:su仅仅取得root权限,工作环境不变,还是在切换之前用户的工作环境;

sudo是完全取得root的权限和root的工作环境。

注意:sudo su切换到root时原用户的环境变量也一并丢失。应使用sudo –i

问题3:subprocess.CalledProcessError:
Command ‘lsb_release -a’ returned non-zero exit status 1.

此问题一直没有找到解决方案,但在Ubuntu中安装Python3.6.3时没有遇到这样的问题,个人认为是与pip及setuptool安装相关的,但是这个报错暂时不会影响到ARM中Python的使用,后续再研究下如何处理。

4、移植到DVB工程

要使的DVB工程至少Python,对Hisi方案来说,有3种方式:

① Hisi STB SDK增加Python模块;

② 文件系统文件挂载方式挂载交叉编译出来的Python模块;

③ DVB应用工程直接整合Python模块;

第一种,从专业角度上讲,肯定是最合理最正确的,这也是最终应该采取的方案!但此方式暂时还没有正式实施,具体过程待后续实践完善,应该不难,就是要调整SDK,这个没有Hisi官方支持,只能自己玩了。

第二种,把Python模块打包成文件系统文件,系统启动后挂载使用,好处是分区独立,不影响原来的SDK,打包成文件系统还可以有效压缩Python模块的大小,如果对SDK不太熟悉的而且硬件平台Flash空间有限的话,可以这样使用。

第三种,是最简单方便但是最不合理的,就是利用应用工程来直接编译打包Python模块,打包后的文件整整大了160多M,坑吧!

但是呢,我们当前最主要的目的是在DVB程序上能运行Python测试Code,先不管三七二十一,合理不合理,先捡简单的上!按第三种来:

执行解压缩命令tar czvf arm_python.tar.gz
arm_python压缩文件夹,把arm_python.tar.gz复制DVB工程目录下使用tar zxvf arm_python.tar.gz解压,然后调整makefile,使python编译到DVB文件系统中。

PYTHON_DIR = $(PROJECT_DIR)/python

PYTHON_INC_DIR = $(PYTHON_DIR)/include

INCFLAGS += -I $(PYTHON_INC_DIR)/python3.6m

LIBPATH = -L
$(PYTHON_DIR)/lib

HI_LIBS += -lutil -lpython3.6m

编译DVB工程时,如果出现如下错误:

undefined reference to `openpty’

解决方法:

DVB应用工程makefile中,添加util链接库 -lutil

DVB工程打包镜像时,需要把Python模块拷贝到镜像中:

$(AT)cp
-rf $(PYTHON_DIR)/bin/* $(ROOTBOX_DIR)/home/python/bin/

$(AT)cp
-rf $(PYTHON_DIR)/include/* $(ROOTBOX_DIR)/home/python/include/

$(AT)cp
-rf $(PYTHON_DIR)/lib/* $(ROOTBOX_DIR)/home/python/lib/

$(AT)cp
-rf $(PYTHON_DIR)/share/* $(ROOTBOX_DIR)/home/python/share/

$(AT)chmod
777 $(ROOTBOX_DIR)/home/python/bin/* -R

$(AT)chmod
777 $(ROOTBOX_DIR)/home/python/include/* -R

$(AT)chmod
777 $(ROOTBOX_DIR)/home/python/lib/* -R

$(AT)chmod
777 $(ROOTBOX_DIR)/home/python/share/* -R

同时在DVB代码中增加Python测试代码:

static void Python_Test(void)

{

Py_Initialize();

PyRun_SimpleString(“print
(‘hello,python!’)”);

Py_Finalize();

//return
0;

}

编译通过后,make image打包的镜像大了160多M,啧啧,如果Flash空间不够大,果然不能任性!把生成的镜像烧录到盒子,运行到Python测试代码时,出现如下错误:

Could not find platform independent
libraries <prefix>

Could not find platform dependent libraries
<exec_prefix>

Consider setting $PYTHONHOME to
<prefix>[:<exec_prefix>]

Fatal Python error: Py_Initialize: Unable
to get the locale encoding

ModuleNotFoundError: No module named
‘encodings’

解决方法:

修改开发板/etc/profile中添加

export PYTHONHOME=/home/python

export PYTHONPATH=$PYTHONHOME:$PYTHONHOME/lib/python3.6:$PYTHONHOME/lib:$PYTHONHOME/lib/python3.6/site-packages

export PATH=$PATH:$PYTHONHOME:$PYTHONPATH

还是通过调整makefile

$(AT)if
[ -f $(ROOTBOX_DIR)/etc/profile ]; then \

echo
“export PYTHONHOME=$(PYTHON_BASE)” >>
$(ROOTBOX_DIR)/etc/profile;\

echo
“export PYTHONPATH=$(PYTHONPATH_BASE)” >>
$(ROOTBOX_DIR)/etc/profile;\

echo
“export PATH=$(PATH):$(PYTHON_BASE):$(PYTHONPATH_BASE)” >>
$(ROOTBOX_DIR)/etc/profile;\

echo
“” >> $(ROOTBOX_DIR)/etc/profile; \

fi

记住一定是放在在hiapp.elf运行之前哦!再次编译打包烧录运行……

hello,python!

杠杠的hello,python!

Ctrl+C中断,增加python软链接

# ln -s /home/python/bin/python3.6
/usr/bin/python

# python

Python 3.6.3 (default, Dec 14 2017,17:51:31)

[GCC 4.9.4 20151028 (prerelease)] on linux

Type “help”,
“copyright”, “credits” or “license” for more
information.

>>> exit()

OK,DVB上运行Python测试Code完毕……

额外的Bug:

Ubuntu上安装Python3.6.3时,先执行默认./configure安装,此时Python默认安装在/usr/local目录,后面又重新安装Python3.6.3在/usr/local/python3.6目录,但之前安装未删除,以为不会冲突,但是肯定是不行滴,在Ubuntu上运行Python3.6时,就会出现奇怪的问题,如下:

*** glibc detected *** python: free():
invalid pointer: 0x00007f6060182558 ***

原因就是Python版本冲突了,此时删掉其中一个Python就OK啦。

好了,下一步:要继续深入学习Python咯,一步一个脚印!

    原文作者:我是黎明
    原文地址: https://zhuanlan.zhihu.com/p/32115419
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞