[TOC]
背景
机器人快速迭代开发场景下主要使用python进行开发,为了避免交付产品暴露python源码,以及能快速打包应用在不同设备上分法安装,因此需要调研一套打包python代码的工具,需要具备如下能力:
- 可以对python源码进行处理,避免源码暴露。
- 可以方便在不同设备上进行分发。
方案选择
python 部署方案主要集中在源码混淆后部署及源码编译后部署两种方案。以下作简单介绍。
方案对比(cython 与 nuitka )
打包后目录结构
目前语音cython 打包方案,打包目录如下所示。由于是使用 cython 是将目录下所有文件打包成动态库,由于文件内 import 会包含路径因此文件目录无法隐藏,入口文件也无法编译成可执行文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
├── kaiwu_agent_result
│ └── kaiwu_agent
│ ├── examples
│ ├── kaiwu_agent
│ │ ├── __init__.py
│ │ ├── __pycache__
│ │ │ └── __init__.cpython-310.pyc
│ │ ├── agents
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ └── agent
│ │ ├── configs
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ ├── base.so
│ │ │ ├── brain_agent_react_chat.so
│ │ │ ├── brain_agent_react_lego_ur.so
│ │ │ ├── brain_agent_react_lego.so
│ │ │ ├── brain_agent_react_v1_demo3.so
│ │ │ ├── brain_agent_react_v2_franka.so
│ │ │ ├── brain_agent_react.so
│ │ │ ├── brain_agent_v1v2.so
│ │ │ ├── brain_agent_v3.so
│ │ │ ├── chat_agent.so
│ │ │ ├── commons.so
│ │ │ ├── config.so
│ │ │ ├── control_agent.so
│ │ │ ├── interact_agent.so
│ │ │ ├── robot_mcts.so
│ │ │ └── visual_brain_agent.so
│ │ ├── tools
│ │ │ ├── __init__.py
│ │ │ ├── __pycache__
│ │ │ ├── block_tools.so
│ │ │ ├── interact_agent_server.so
│ │ │ ├── interact_tools.so
│ │ │ ├── langgraph_tools.so
│ │ │ ├── openai_tools.so
│ │ │ └── search_tools.so
│ │ └── utils
│ │ ├── __init__.py
│ │ ├── __pycache__
│ │ ├── common.so
│ │ ├── env.so
│ │ ├── image_process.so
│ │ ├── kaiwu_message.so
│ │ ├── lego
│ │ ├── logger.so
│ │ ├── openai_support.so
│ │ ├── orbbec_camera.so
│ │ └── voice.so
│ ├── main_release.py
│ ├── main_release.so
│ ├── main.so
│ ├── requirements_interact.txt
│ ├── requirements.txt
│ └── setup.so
└── robot_voice_result
└── robot_voice
├── configs
├── fake_server.so
├── README_RELEASE.md
├── requirements
│ ├── develop.txt
│ └── install.txt
├── requirements.txt
├── robot_voice
│ ├── __init__.py
│ ├── __pycache__
│ │ └── __init__.cpython-310.pyc
│ ├── listener
│ │ ├── __init__.py
│ │ ├── __pycache__
│ │ ├── sbus_controler.so
│ │ └── xf_voice
│ ├── tool
│ │ ├── __init__.py
│ │ ├── __pycache__
│ │ ├── audioPlayer.so
│ │ ├── cosyvoice_pb2_grpc.so
│ │ ├── cosyvoice_pb2.so
│ │ ├── tencent
│ │ ├── tts_player.so
│ │ ├── xf_translate.so
│ │ ├── xf_tts.so
│ │ └── xunfei
│ └── utils
│ ├── __init__.py
│ ├── __pycache__
│ ├── check_xf.so
│ ├── common.so
│ ├── log.so
│ └── voice_server.so
├── server_ros2.py
├── server_ros2.so
└── server.so
|
以下使用 nuitka 打包(使用accelerated模式,相关优劣后面会有介绍),可以打包为一个可执行文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
├── kaiwu_agent_result
│ ├── examples
│ │ ├── music
│ │ └── rag
│ ├── main_release.bin
│ └── requirements.txt
├── requirements-all.txt
└── robot_voice_result
├── configs
│ ├── __init__.py
│ ├── server_cfg.py
│ └── voice
├── requirements.txt
└── server_ros2.bin
|
Nuitka 方案存在问题和风险
动态加载文件无法识别编译
-
动态修改Python的模块搜索路径
1
2
3
4
5
|
import os,sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
import grpc
import cosyvoice_pb2 as cosyvoice__pb2
|
需要改为如下方式:
1
2
|
import grpc
import robot_voice.tool.cosyvoice_pb2 as cosyvoice__pb2
|
-
gi 动态调用C库需要在运行时指定动态库路径
1
2
3
|
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst
|
运行时需要指定
1
|
export GST_PLUGIN_PATH=/home/ps/miniconda3/envs/rtp_player/lib/gstreamer-1.0/
|
standalone&onefile 模式编译问题
standalone&onefile 模式会将Python 应用程序及其所有依赖项打包到一个独立的文件夹中。这个文件夹包含了运行应用程序所需的所有内容,包括 Python 解释器、库文件和你的代码。
Standalone:生成一个包含多个文件的文件夹,直接从文件夹中运行,无需解压。
One-file:生成一个单独的可执行文件,运行时会解压到临时目录。
accelerated 模式编译问题
accelerated 模式 会在你的 Python 安装环境中运行,并依赖于该环境。
-
依然面临python环境管理问题
-
accelerated 模式数据需要用户手动拷贝
Nuitka 使用
Nuitka 常用编译指令介绍
设置编译模式
编译模式: 默认模式是 accelerated。
-
accelerated 模式会在你的 Python 安装环境中运行,并依赖于它。
-
standalone 模式会创建一个包含可执行文件的文件夹来运行它。
-
onefile 模式会生成一个单独的可执行文件以便部署。
-
app 模式类似于 onefile,但在 macOS 上不推荐使用。
-
module 模式会生成一个模块
-
package 模式还会包含所有子模块和子包。
-
Dll 模式目前正在开发中,尚未对用户开放。
查看使用插件
某些复杂的第三方库(如 PyQt5、TensorFlow、PyTorch 等)需要特殊的处理才能正确打包。插件可以自动处理这些库的依赖关系,减少打包问题。
以下仅列出部分。
控制导入的模块
以下仅列出部分。
-
--follow-imports
导入所有被导入的模块。在standalone&onefile模式下默认开启,否则关闭。
-
--nofollow-imports
不递归深入(导入)到任何导入的模块,这将覆盖所有其他包含选项,并且不能用于standalone&onefile模式。默认关闭。
-
--follow-import-to=MODULE/PACKAGE
可以多次给出。默认为空。
-
--nofollow-import-to=MODULE/PACKAGE
可以多次给出。默认为空。
数据文件
accelerated 模式下只有商业版才能使用。
以下仅列出部分。
-
--include-package-data=PACKAGE
-
--include-data-files=DESC
-
--include-data-dir=DIRECTORY
nuitka编译打包demo
独立安装包(standalone&onefile 模式)
依赖环境安装包 (accelerated 模式)
后续计划
- 先在语音软件包上进行部署尝试后续扩展到300#其他软件包。
- python 依赖冲突问题解决? (是否基于nuitka 将有版本冲突的包编译到可执行文件中)。