Чи є спосіб скомпілювати додаток python у статичний двійковий файл?


89

Я намагаюся доставити свій код на віддалений сервер, на якому може бути встановлена ​​інша версія 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
інші варіанти - нуітка та цитон
denfromufa

Відповіді:


123

Існує два шляхи вирішення проблеми

  1. Використовуйте статичний конструктор, наприклад, freeze, або pyinstaller, абоpy2exe
  2. Складіть за допомогою cython

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

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

sudo pip install cython
mv test.py test.pyx

Потім ви можете використовувати cythonразом із GCC для його компіляції ( cythonстворює файл C з файлу Python .pyx, а потім 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

Тепер у вас буде «тест» двійкового файлу, що саме ви шукаєте

Інші речі, на які слід звернути увагу :

  1. Cython використовується для використання визначень змінних типу C для статичного розподілу пам'яті для прискорення програм Python. Однак у вашому випадку ви все одно будете використовувати традиційні визначення Python.
  2. Якщо ви використовуєте додаткові бібліотеки (наприклад opencv, наприклад), можливо, вам доведеться надати їм каталог за допомогою, -Lа потім вказати ім'я бібліотеки, використовуючи -lв GCC Flags. Для отримання додаткової інформації щодо цього, будь ласка, зверніться до прапорців GCC

20
Привіт, а якщо моя програма охоплює кілька файлів. Здається, такий підхід компілює лише поточний сценарій, а не всі залежності Python.
RChat

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. Однак у моїй цільовій системі немає 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
РС

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.
André Aulich

0

Варіанти заморожування:

Однак на вашому цільовому сервері має бути середовище, яке ви хочете -> ви повинні мати можливість його "створити". Якщо цього не сталося, вам слід створити програмне забезпечення, яке відповідає оточенню.

Я знайшов цей зручний посібник про те, як встановити власну версію python у virtualenv, якщо ви маєте доступ до ssh: https://stackoverflow.com/a/5507373/5616110

У virtualenv ви повинні мати можливість встановити будь-що, і вам не потрібно турбуватися про привілеї sudo. Звичайно, наявність таких і доступ до менеджера пакунків, як apt, робить все набагато простішим.


Я вже використовую virtualenv, це не так. Моє питання стосується статично скомпільованого python з необхідними модулями та програмами.
roboslone

Тоді вам доведеться заморозити його, інакше це не можна обійти.
iScrE4m
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.