为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕娘9325324 2022-01-11 18:01:19
我正在尝试使用Cython和PyInstaller库将我的项目代码打包成可执行二进制文件。我的代码目录如下所示:的main.py是从进口逻辑主代码program_a.py和program_b.py。我成功地将我的program_a和program_b文件转换为可以由任何 python 代码导入的 .so 文件。我通过执行以下脚本来做到这一点。from distutils.core import setupfrom Cython.Build import cythonizesourcefiles = ['program_a.py', 'program_b.py']setup(    name = "Hello World",    ext_modules = cythonize(sourcefiles), )通过执行 >python setup.py build_ext --inplace我得到.so如下所示的文件当我运行python main.py它时,它可以完美地与.so文件一起运行。这表明我可以将它们作为模块导入。现在,我想将二进制 (.so) 文件打包main.py成单个二进制文件。为此,我使用了以下命令pyInstallerpyinstaller "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_aModuleNotFoundError: 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 代码示例中使用任何外部包。我能够在没有外部模块的情况下编译代码
查看完整描述

2 回答

?
慕运维8079593

TA贡献1876条经验 获得超5个赞

在熟悉 PyInstaller 包后,我能够找出问题所在。我按照以下步骤使其最终为我工作。


现在,发布我的答案以帮助他人:)


## Build *.so files from python modules 

    1. Execute "setup.py" file

       > python setup.py build

    2. It will generate "*.so" modules inside "build/lib.linux-x86_64-3.6" dir.


## Created binary from cython modules

    1. Copy the binaries (i.e. *.so) files into binary folder

    2. Get inside the binary folder 'cd binary'

    3. Run Pyinstaller command inside binary directory: `python -O -m PyInstaller --clean --onefile idps.spec`

    4. Your binary will be inside dist folder 'binary/dist/'

    5. Execute the binary in linux using './dist/sample_app'

    6. Your app is ready :)

这是使它对我有用的规范文件:


# -*- mode: python -*-


block_cipher = None



a = Analysis(['main.py'],

             pathex=['cython_pyinstaller_sample/binary'],

             binaries=[('program_a.cpython-36m-x86_64-linux-gnu.so', '.'),('program_b.cpython-36m-x86_64-linux-gnu.so', '.')],

             datas=[('config_file.txt', '.')],

             hiddenimports=['licensing', 'licensing.methods', 'pandas'],

             hookspath=[],

             runtime_hooks=[],

             excludes=[],

             win_no_prefer_redirects=False,

             win_private_assemblies=False,

             cipher=block_cipher,

             noarchive=False) pyz = PYZ(a.pure, a.zipped_data,

             cipher=block_cipher) exe = EXE(pyz,

          a.scripts,

          a.binaries,

          a.zipfiles,

          a.datas,

          [],

          name='sample_app',

          debug=True,

          bootloader_ignore_signals=False,

          strip=False,

          upx=True,

          runtime_tmpdir=None,

          console=True )


查看完整回答
反对 回复 2022-01-11
?
胡说叔叔

TA贡献1804条经验 获得超8个赞

以防万一有人在寻找快速解决方案。

我遇到了同样的情况,并找到了一种快速/肮脏的方式来完成这项工作。问题是 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 文件中。


查看完整回答
反对 回复 2022-01-11
  • 2 回答
  • 0 关注
  • 396 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号