Есть ли способ скомпилировать приложение Python в статический двоичный файл?

87

Я пытаюсь отправить свой код на удаленный сервер, на котором может быть установлена ​​другая версия Python и / или может не быть пакетов, необходимых для моего приложения.

Прямо сейчас для достижения такой переносимости мне нужно создать перемещаемый virtualenv с интерпретатором и кодом. У этого подхода есть некоторые проблемы (например, вам нужно вручную скопировать кучу библиотек в свой virtualenv, поскольку он --always-copyработает не так, как ожидалось) и обычно медленный.

Есть (теоретически) способ построить сам Python статически.

Интересно, смогу ли я упаковать интерпретатор со своим кодом в один двоичный файл и запустить приложение как модуль. Что-то вроде этого: ./mypython -m myapp runили ./mypython -m gunicorn -c ./gunicorn.conf myapp.wsgi:application.

одинокий робот
источник
Вы имеете в виду что-то вроде cx_freeze?
TigerhawkT3
@ TigerhawkT3, до сегодняшнего дня я никогда не слышал о cx_freeze. Просмотрел документы, похоже, это то, что я хочу, но он не может быть построен на Ubuntu 12.04.5 с python3.5.1. Ищу альтернативы, спасибо за пинок в нужную сторону.
roboslone
К сожалению, pyinstaller не работает с Django 1.9, а py2app / py2exe не поддерживают linux :(
roboslone
2
если cx_Freeze и pyinstaller не работают, надежда еще есть. Вы можете создать пакет (ы) для целевого дистрибутива (ов), который разрешит все зависимости от установки. Или, может быть, использовать что-то вроде докера для запуска вашего приложения.
KeatsPeeks,
1
другие варианты - nuitka и cython
denfromufa

Ответы:

122

Есть два способа решить вашу проблему

  1. Используйте статический строитель, например заморозку, или pyinstaller, илиpy2exe
  2. Скомпилировать с использованием cython

Я объясню, как вы можете это сделать, используя второй, поскольку первый метод не является кросс-платформой и версией и был объяснен в других ответах. Кроме того, использование таких программ, как pyinstaller, обычно приводит к огромным размерам файлов, тогда как использование cython приведет к созданию файла размером в КБ

Сначала установите cython. Затем переименуйте свой файл python (скажем test.py) в .pyxфайл

sudo pip install cython
mv test.py test.pyx

Затем вы можете использовать cythonвместе с GCC для его компиляции ( cythonгенерирует файл C из .pyxфайла Python , а затем GCC компилирует файл C)

(ссылка на https://stackoverflow.com/a/22040484/5714445 )

cython test.pyx --embed
gcc -Os -I /usr/include/python3.5m -o test test.c -lpython3.5m -lpthread -lm -lutil -ldl

ПРИМЕЧАНИЕ . В зависимости от вашей версии python вам может потребоваться изменить последнюю команду. Чтобы узнать, какую версию Python вы используете, просто используйте

$ python -V

Теперь у вас будет двоичный файл test, который вы ищете.

Еще на заметку :

  1. Cython используется для использования определений переменных C-типа для выделения статической памяти для ускорения программ Python. Однако в вашем случае вы по-прежнему будете использовать традиционные определения Python.
  2. Если вы используете дополнительные библиотеки (например opencv, например), вам, возможно, придется предоставить им каталог, -Lа затем указать имя используемой библиотеки -lв флагах GCC. Для получения дополнительной информации см. Флаги GCC.
RS Никхил Кришна
источник
20
Привет, а что, если мое приложение распространяется на несколько файлов. Этот подход, похоже, компилирует только текущий скрипт, а не все зависимости Python.
Rhat
2
не нужно прямо сейчас переименовывать ваш файл python (скажем, test.py) в pyx
iMath
3
Это мне очень помогло. Чтобы ответить на вопрос о нескольких файлах, вы можете использовать cythonize: cythonize -i file_0.py [...] file_n.pyдля всех ваших модулей Python, а затем cython main_file.py --embedдля вашего основного скрипта. В итоге вы получите исполняемый файл и файлы .so (.dll, .dylib в зависимости от вашей ОС), которые вы сможете использовать вместе как отдельное решение.
afp
Я получаю сообщение «Нет модулей с именами кодировок». Я узнал, что мне требуются определенные файлы из установки python. Однако в моей целевой системе нет питона. Пожалуйста помоги.
abhiarora
9

Возможно, вы захотите исследовать Нуйтку . Он берет исходный код Python и преобразует его в вызовы API C ++. Затем он компилируется в исполняемый двоичный файл (ELF в Linux). Он существует уже несколько лет и поддерживает широкий спектр версий Python.

Вы, вероятно, также получите улучшение производительности, если воспользуетесь им. Рекомендуемые.

Пракхар Агарвал
источник
Я не смог найти никакой информации об использовании Nuitka с Django. У вас, случайно, есть такой опыт?
roboslone
@roboslone, Prakhar Agarwal Cython очень хорошо поддерживает внешние библиотеки по сравнению со статическим построителем Nuitka PyPy. Например, по ссылке в конце этого комментария «люди используют Cython, потому что это помогает им решить проблему. Либо они хотят подключиться к внешним библиотекам, отличным от Python, из кода Python, либо они хотят иметь возможность оптимизировать их код вручную или и то, и другое », ссылка: blog.behnel.de/posts/indexp241.html
RS
1
RS Nikhil Krishna, я не пытаюсь сделать свой код быстрее, я пытаюсь отправить его в одном двоичном файле с интерпретатором Python внутри.
roboslone
Ааа ладно. Я думал, вы хотите связать его с какой-то внешней библиотекой. Виноват.
RS Nikhil Krishna
1

Если вы работаете на Mac, вы можете использовать py2app для создания пакета .app, который запускает ваше приложение Django при двойном щелчке по нему.

Я описал, как объединить Django и CherryPy в такой комплект, на https://moosystems.com/articles/14-distribute-django-app-as-native-desktop-app-01.html.

В этой статье я использую pywebview для отображения вашего сайта Django в окне локального приложения.

Андре Олич
источник
Мое приложение в основном работает в Linux, поэтому py2app не применяется
roboslone
Хотя в статье используется py2app, это можно сделать и с помощью pyinstaller.
Андре Олич
0

Варианты заморозки:

Однако на вашем целевом сервере должна быть желаемая среда -> у вас должна быть возможность «создать» ее. Если это не так, вам следует создать свое программное обеспечение, соответствующее среде.

Я нашел это удобное руководство о том, как установить пользовательскую версию python в virtualenv, если у вас есть доступ по ssh: https://stackoverflow.com/a/5507373/5616110

В virtualenv вы должны иметь возможность установить что угодно, и вам не нужно беспокоиться о привилегиях sudo. Конечно, их наличие и доступ к диспетчеру пакетов, например, к apt, значительно упрощают работу.

iScrE4m
источник
Я уже использую virtualenv, это не так. Мой вопрос касается статически скомпилированного Python с необходимыми модулями и приложениями.
roboslone
Тогда вы должны его заморозить, иначе никак.
iScrE4m