一、目的:
将项目所有的代码,编译成一个独立的二进制文件包,并防止反编译。
二、示例项目结构:
➜ cpdemo tree
.
|-- libs
| |-- A
| | `-- a.py
| `-- B
| `-- b.py
`-- setup
|-- build_pyd.py
`-- main.py
4 directories, 4 files
总共四个文件,A 和 B分别是两个类,其中mian.py 引用a, a引用b:
三、先使用Cython编译:
#build_pyd.py文件内容如下,自行添加要编译的文件路径到cythonize的第一个参数列表里。每个文件会单独编译成一个.so文件。
from distutils.core import setup
from Cython.Build import cythonize
setup(
name='Anything you want',
ext_modules=cythonize(["../libs/A/*.py", "../libs/B/*.py"
], language_level=3
),
)
在setup文件夹下,执行python3 build_pyd.py build_ext --inplace 命令,
执行成功后在setup文件夹里生成两个文件:
a.cpython-36m-x86_64-linux-gnu.so b.cpython-36m-x86_64-linux-gnu.so
执行出错,参考issues-1
四、使用Pyinstaller 打包
执行pyinstaller -F main.py 命令,执行成功在dist目录先生成main文件。执行结果如下:
如果包No module named xxx的错误,参考 issues-3
五、issues:如果出现如下:
Fatal error: can't create build/temp.linux-x86_64-3.6/../libs/A/a.o: No such file or directory
error: command 'gcc' failed with exit status 1
自行在build目录下创建,temp.linux-x86_64-3.6,文件夹,什么原因导致的,不知道。
2. 如果提示pyinstaller未安装,自行使用pip安装:
pip3 install pyinstaller
3. 重点来了,如果出现了ModuleNotFoundError: No module named 'b'
ps:基本都会出现,如果你直接执行python main.py正常的话,这里并不表示你的代码有问题。只是pyinstaller默认不会引入导入再导入的文件,即b.py。因此只需要修改生成的main.spec文件,修改如下,如果有其他文件缺失,自行天街:
然后执行: pyinstaller main.spec
即可:
5241 INFO: Building EXE from EXE-00.toc completed successfully.
六、demo代码rmokerone/cpdemogithub.com
七、参考链接https://stackoverflow.com/questions/25733467/no-module-named-when-using-pyinstallerstackoverflow.com