猿问

使用 PyInstaller 将 Cython 编译的模块和 python 代码构建为可执行

我正在尝试使用CythonPyInstaller库将我的项目代码打包成可执行二进制文件。我的代码目录如下所示:

的main.py是从进口逻辑主代码program_a.py和program_b.py。


我成功地将我的program_a和program_b文件转换为可以由任何 python 代码导入的 .so 文件。我通过执行以下脚本来做到这一点。


from distutils.core import setup

from Cython.Build import cythonize


sourcefiles = ['program_a.py', 'program_b.py']


setup(

    name = "Hello World",

    ext_modules = cythonize(sourcefiles), 

)

通过执行 >python setup.py build_ext --inplace我得到.so如下所示的文件

http://img1.mukewang.com/61dd5594000123ba02940090.jpg

当我运行python main.py它时,它可以完美地与.so文件一起运行。这表明我可以将它们作为模块导入。


现在,我想将二进制 (.so) 文件打包main.py成单个二进制文件。为此,我使用了以下命令pyInstaller


pyinstaller "main.py" --onefile


它实际上在dist/文件夹中提供了一个二进制文件,但我无法导入某些模块并出现以下错误:


Traceback (most recent call last):

  File "main.py", line 1, in <module>

    import program_a as lisence_checker

  File "program_a.py", line 1, in init program_a

ModuleNotFoundError: No module named 'licensing'

[18032] Failed to execute script main

如何将库与 pyinstaller 链接或将库信息嵌入到我的二进制文件中?


我还发现了什么:


使用 PyInstaller 构建 Cython 编译的 python 代码


https://riptutorial.com/cython/example/21982/bundling-a-cython-program-using-pyinstaller


但是所有这些上面的链接都没有在 python 代码示例中使用任何外部包。我能够在没有外部模块的情况下编译代码


慕娘9325324
浏览 399回答 2
2回答

慕运维8079593

在熟悉 PyInstaller 包后,我能够找出问题所在。我按照以下步骤使其最终为我工作。现在,发布我的答案以帮助他人:)## Build *.so files from python modules&nbsp;&nbsp; &nbsp; 1. Execute "setup.py" file&nbsp; &nbsp; &nbsp; &nbsp;> python setup.py build&nbsp; &nbsp; 2. It will generate "*.so" modules inside "build/lib.linux-x86_64-3.6" dir.## Created binary from cython modules&nbsp; &nbsp; 1. Copy the binaries (i.e. *.so) files into binary folder&nbsp; &nbsp; 2. Get inside the binary folder 'cd binary'&nbsp; &nbsp; 3. Run Pyinstaller command inside binary directory: `python -O -m PyInstaller --clean --onefile idps.spec`&nbsp; &nbsp; 4. Your binary will be inside dist folder 'binary/dist/'&nbsp; &nbsp; 5. Execute the binary in linux using './dist/sample_app'&nbsp; &nbsp; 6. Your app is ready :)这是使它对我有用的规范文件:# -*- mode: python -*-block_cipher = Nonea = Analysis(['main.py'],&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;pathex=['cython_pyinstaller_sample/binary'],&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;binaries=[('program_a.cpython-36m-x86_64-linux-gnu.so', '.'),('program_b.cpython-36m-x86_64-linux-gnu.so', '.')],&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;datas=[('config_file.txt', '.')],&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hiddenimports=['licensing', 'licensing.methods', 'pandas'],&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;hookspath=[],&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;runtime_hooks=[],&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;excludes=[],&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;win_no_prefer_redirects=False,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;win_private_assemblies=False,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cipher=block_cipher,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;noarchive=False) pyz = PYZ(a.pure, a.zipped_data,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;cipher=block_cipher) exe = EXE(pyz,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a.scripts,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a.binaries,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a.zipfiles,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; a.datas,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [],&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name='sample_app',&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; debug=True,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bootloader_ignore_signals=False,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; strip=False,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; upx=True,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; runtime_tmpdir=None,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console=True )

胡说叔叔

以防万一有人在寻找快速解决方案。我遇到了同样的情况,并找到了一种快速/肮脏的方式来完成这项工作。问题是 pyinstaller 没有在 .exe 文件中添加运行程序所需的必要库。您需要做的就是将所需的所有库(和 .so 文件)导入 main.py 文件(调用 program_a.py 和 program_b.py 的文件)。例如,假设 program_a.py 使用 opencv 库 (cv2) 而 program_b.py 使用 matplotlib 库。现在在您的 main.py 文件中,您还需要导入 cv2 和 matplotlib。基本上,无论你在 program_a.py 和 program_b.py 中导入什么,你也必须在 main.py 中导入它。这告诉 pyinstaller 程序需要这些库,并将这些库包含在 exe 文件中。
随时随地看视频慕课网APP

相关分类

Python
我要回答