Создание Cython-скомпилированного кода на Python с помощью PyInstaller

Я пытаюсь создать многофакторный код Python с PyInstaller. Для этого я скомпилировал код с Cython и использую .so файлы, созданные вместо файлов .py.

Предполагая, что первый файл main.py, а импортированные - file_a.py и file_b.py, я получаю file_a.so и file_b.so после компиляции Cython.

Когда я помещаю main.py, file_a.so и file_b.so в папку и запускаю ее "python main.py", она работает.

Но когда я создаю его с помощью PyInstaller и пытаюсь запустить сгенерированный исполняемый файл, он выдает ошибки для импорта, сделанные в file_a и file_b.

Как это можно зафиксировать? Одним из решений является импорт всех стандартных модулей в main.py, и это работает. Но если я не хочу менять свой код, каково может быть решение?

Ответы

Ответ 1

Итак, я получил это, чтобы работать на вас.

Пожалуйста, посмотрите Объединение расширений Cython с помощью 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 чтобы связать приложение с расширениями в один исполняемый файл.

Пример 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