Сборка Cython-скомпилированных модулей и кода Python в исполняемый двоичный файл с использованием PyInstaller - PullRequest
0 голосов
/ 16 апреля 2019

Я пытаюсь упаковать код моего проекта в исполняемый двоичный файл с использованием библиотек Cython и PyInstaller. Мой каталог кодов выглядит так:

Code Directory main.py - это основной код, который импортирует логику из program_a.py и program_b.py.

Я успешно могу конвертировать мои program_a и program_b файлы в .so файлы, которые могут быть импортированы любым кодом Python. Я сделал это, выполнив следующий скрипт.

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 файлов, как показано ниже

binaries with libraries Когда я запускаю 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 или вставить информацию библиотеки в мои двоичные файлы?

Что я нашел еще:

  1. Сборка Python-скомпилированного кода с PyInstaller

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

Но все эти ссылки выше не используют никаких внешних пакетов внутри примеров кода Python. Я могу скомпилировать код без внешних модулей

1 Ответ

0 голосов
/ 18 апреля 2019

После ознакомления с пакетом 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 )
...