因为是在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咯,一步一个脚印!