avatar👨‍💻
BestGuo2020BestGuo 的小窝

face-lift

一个人的世界是如此安静

银河麒麟arm版v10系统打包pyqt程序

项目背景

最近公司要做一个桌面端应用,并且该应用要在 win10,win7 和 银河麒麟 v10 银河麒麟 arm 版 v10系统中,这里主要细说 银河麒麟 arm 版 v10 操作系统,使用 nuitka 打包 python 程序至可执行文件。

该操作系统虽然自带 python3.8 和 Qt 组件,但是没有 QtWebEngine 这个组件,自己尝试用 pip 安装 PyQtWebEngine,但是卡在 qmake 一直安装失败,因此最后我们使用 anaconda 来打包这个项目。

开始打包

我的 anaconda 虚拟环境是 python 3.10,安装的依赖有以下

bash
conda install -c conda-forge openpyxl pyqt5-sip pyqtwebengine requests jieba

然后使用 pip 安装 nutika

bash
pip install Nuitka

开始打包

bash
nuitka3 --standalone --show-progress --show-memory --enable-plugin=pyqt5,glfw,dll-files --include-package-data=package_name=data --windows-icon-from-ico=./icon/pc.ico --static-libpython=no --output-dir=out/release1.0.87_kylin main_ui.py
first

项目打包完成后,由于 Nuitka 打包不会很完整,直接运行会报错。

后续补充

报错1:缺少 libsmime3.so 文件

bash
huawei@huawei-L410-KLVU-WDU0:~/xxxx/out/release1.0.87_kylin/main_ui.dist$ ./main_ui.bin 

Traceback (most recent call last):

 File "/home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/main_ui.py", line 4, in <module>

 File "/home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/xxxx.py", line 12, in <module xxxxxx>

ImportError: /lib/aarch64-linux-gnu/libnss3.so: version `NSS_3.65' not found (required by /home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/PyQt5/../libsmime3.so)

解决办法:复制anaconda虚拟环境下的libnss3.so文件

bash
cp ~/.conda/envs/py_wjp/lib/libnss3.so .

报错2:缺少 libnssutil3.so 文件

bash
huawei@huawei-L410-KLVU-WDU0:~/xxxx/out/release1.0.87_kylin/main_ui.dist$ ./main_ui.bin 

Traceback (most recent call last):

 File "/home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/main_ui.py", line 4, in <module>

 File "/home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/xxxxxx.py", line 12, in <module xxxxxx>

ImportError: /lib/aarch64-linux-gnu/libnssutil3.so: version `NSSUTIL_3.82' not found (required by /home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/PyQt5/../libnss3.so)

解决办法:复制anaconda虚拟环境下的libnssutil3.so文件

bash
cp ~/.conda/envs/py_wjp/lib/libnssutil3.so .

报错3:缺少 jieba 的 dict.txt 文件:

这个报错在 windows 系统上也会出现

bash
Traceback (most recent call last):

 File "/home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/main_ui.py", line 4, in <module>

 File "<frozen importlib._bootstrap>", line 1027, in _find_and_load

 File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked

 File "<frozen importlib._bootstrap>", line 688, in _load_unlocked

 File "/home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/xxxxxx.py", line 17, in <module xxxxxx>

 File "<frozen importlib._bootstrap>", line 1027, in _find_and_load

 File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked

 File "<frozen importlib._bootstrap>", line 688, in _load_unlocked

 File "/home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/check_industry_name.py", line 5, in <module check_industry_name>

 File "<frozen importlib._bootstrap>", line 1027, in _find_and_load

 File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked

 File "<frozen importlib._bootstrap>", line 688, in _load_unlocked

 File "/home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/extract_word.py", line 4, in <module extract_word>

 File "<frozen importlib._bootstrap>", line 1027, in _find_and_load

 File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked

 File "<frozen importlib._bootstrap>", line 688, in _load_unlocked

 File "/home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/jieba/posseg/__init__.py", line 258, in <module jieba.posseg>

 File "/home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/jieba/posseg/__init__.py", line 82, in __init__

 File "/home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/jieba/__init__.py", line 376, in get_dict_file

 File "/home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/jieba/_compat.py", line 20, in <lambda>

 File "/home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/pkg_resources/__init__.py", line 1219, in resource_stream

 File "/home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/pkg_resources/__init__.py", line 1497, in get_resource_stream

 File "/home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/pkg_resources/__init__.py", line 1500, in get_resource_string

 File "/home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/pkg_resources/__init__.py", line 1671, in _get

FileNotFoundError: [Errno 2] No such file or directory: '/home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/jieba/dict.txt'

解决办法:找到 site-package 目录下的jieba,复制到项目下的 jieba 目录里。

bash
huawei@huawei-L410-KLVU-WDU0:~/xxxx/out/release1.0.87_kylin/main_ui.dist$ mkdir jieba
huawei@huawei-L410-KLVU-WDU0:~/xxxx/out/release1.0.87_kylin/main_ui.dist$ cp ~/.conda/envs/py_wjp/lib/python3.10/site-packages/jieba/dict.txt ./jieba/dict.txt

报错4(PyQtWebEngine报错的问题):

这个报错在 windows 系统上也会出现

bash
Qt WebEngine resources not found at /home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/PyQt5/Qt5/resources. Trying parent directory...

Qt WebEngine resources not found at /home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/PyQt5/Qt5. Trying application directory...

Qt WebEngine resources not found at /home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist. Trying fallback directory... The application MAY NOT work.

Path override failed for key base::DIR_QT_LIBRARY_DATA and path '/home/huawei/.main_ui.bin'

Installed Qt WebEngine locales directory not found at location /home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/PyQt5/Qt5/translations/qtwebengine_locales. Trying application directory...

Qt WebEngine locales directory not found at location /home/huawei/xxxx/out/release1.0.87_kylin/main_ui.dist/qtwebengine_locales. Trying fallback directory... Translations MAY NOT not be correct.

Path override failed for key ui::DIR_LOCALES and path '/home/huawei/.main_ui.bin'

[0917/234306.100254:ERROR:icu_util.cc(251)] Couldn't mmap icu data file

解决办法:复制 resource,translation到PyQt5/Qt5 目录下

bash
huawei@huawei-L410-KLVU-WDU0:~/xxxx/out/release1.0.87_kylin/main_ui.dist$ cp -rf ./translations/ ./PyQt5/Qt5/
huawei@huawei-L410-KLVU-WDU0:~/xxxx/out/release1.0.87_kylin/main_ui.dist$ cp -rf ./resources/ ./PyQt5/Qt5/

这样子,一个带PyQtWebEngine的项目就可以启动了。

但是,还有一种情况,在不是Python3.9的项目中就会提示以下错误,这个问题是由PyQtWebEngine引起的。

报错 5:No suitable graphics backend found

anaconda 指定的 python3.9 虚拟环境不会出现问题

No suitable graphics backend found

解决办法:

python
# Linux 平台暂时使用软件OpenGL渲染
if sys.platform == 'linux':
  QCoreApplication.setAttribute(Qt.AA_UseSoftwareOpenGL)

在窗口打开之前,加入以上代码,项目就可正常启动,设置这个参数的目的在Linux上使用软件OpenGL渲染。

运行闪退

闪退后报 NSS 错误: NSS error code: -8023

bash
[411062:419788:0917/235959.246870:ERROR:nss_util.cc(166)] Error initializing NSS with a persistent database (sql:/home/huawei/.pki/nssdb):
[411062:419788:0917/235959.247066:ERROR:nss_util.cc(124)] Error initializing NSS without a persistent database: NSS error code: -8023
[411062:419788:0917/235959.247083:FATAL:nss_util.cc(126)] nss_error=-8023, os_error=0

追踪与中断点陷阱 (核心已转储)

解决办法:这个我参考了一篇Qt的博客。

Qt添加QWebEngine模块后打包在无Qt的环境上运行出错的问题 - 一笔一世界 - 博客园 (cnblogs.com)

他是直接复制nss文件夹到他的项目中,不过我们要复制nss文件夹里的文件到我们的项目中。

bash
cp /usr/lib/aarch64-linux-gnu/nss/* .

这样的话,就不会报错闪退了。

关于和小 vup 互动的一些感受和想法
设计模式之生成器(建造者)模式