我正在尝试使用PyInstaller
构建Python多文件代码。为此,我使用Cython
编译了代码,并使用生成的.so
文件代替.py
个文件。
假设第一个文件是main.py
且导入的文件是file_a.py
和file_b.py
,我在Cython编译后得到file_a.so
和file_b.so
。
当我将main.py
,file_a.so
和file_b.so
放入文件夹并按"python main.py"
运行时,它可以正常工作。
但是当我使用PyInstaller
构建它并尝试运行生成的可执行文件时,它会导致file_a
和file_b
中完成的导入错误。
如何解决这个问题?一种解决方案是导入main.py
中的所有标准模块,这是有效的。但如果我不想改变我的代码,可以解决什么问题呢?
答案 0 :(得分:15)
所以我让这个为你工作。
请查看Bundling Cython extensions with Pyinstaller
快速入门:
git clone https://github.com/prologic/pyinstaller-cython-bundling.git
cd pyinstaller-cython-bundling
./dist/build.sh
这会生成一个静态二进制文件:
$ du -h dist/hello
4.2M dist/hello
$ ldd dist/hello
not a dynamic executable
并产生输出:
$ ./dist/hello
Hello World!
FooBar
基本上,这产生了一个简单的setup.py
,用于构建扩展file_a.so
和file_b.so
,然后使用pyinstaller将扩展应用程序捆绑到单个executebla中。
示例setup.py
:
from glob import glob
from setuptools import setup
from Cython.Build import cythonize
setup(
name="test",
scripts=glob("bin/*"),
ext_modules=cythonize("lib/*.pyx")
)
构建扩展程序:
$ python setup.py develop
捆绑应用程序:
$ pyinstaller -r file_a.so,dll,file_a.so -r file_b.so,dll,file_b.so -F ./bin/hello
答案 1 :(得分:0)
以防万一有人在寻找快速解决方案。
我遇到了同样的情况,发现一种快速/肮脏的方式来完成这项工作。问题是pyinstaller没有在.exe文件中添加运行程序所需的必需库。
您需要做的就是将所有需要的库(和.so文件)导入到main.py文件(调用file_a.py和file_b.py的文件)中。例如,假设file_a.py使用opencv库(cv2),而file_b.py使用matplotlib库。现在,在main.py文件中,您还需要导入cv2和matplotlib。基本上,无论您在file_a.py和file_b.py中导入什么内容,都必须在main.py中也导入它。这告诉pyinstaller该程序需要这些库,并且在exe文件中包括这些库。