Czy istnieje sposób na skompilowanie aplikacji Pythona do statycznej postaci binarnej?


86

To, co próbuję zrobić, to wysłać mój kod na zdalny serwer, na którym może być zainstalowana inna wersja języka Python i / lub może nie mieć pakietów wymaganych przez moją aplikację.

W tej chwili, aby osiągnąć taką przenośność, muszę zbudować relokowalny virtualenv z interpreterem i kodem. Takie podejście ma pewne problemy (na przykład, musisz ręcznie skopiować kilka bibliotek do swojego virtualenv, ponieważ --always-copynie działa zgodnie z oczekiwaniami) i ogólnie powolne.

Istnieje (w teorii) sposób na statyczne zbudowanie samego Pythona.

Zastanawiam się, czy mógłbym spakować interpreter z moim kodem do jednego pliku binarnego i uruchomić moją aplikację jako moduł. Coś takiego: ./mypython -m myapp runlub ./mypython -m gunicorn -c ./gunicorn.conf myapp.wsgi:application.


Czy masz na myśli coś takiego jak cx_freeze?
TigerhawkT3

@ TigerhawkT3, do dzisiaj nie słyszałem o cx_freeze. Przejrzałem dokumenty, wydaje mi się, że tego właśnie chcę, ale nie udało mi się zbudować na Ubuntu 12.04.5 z python3.5.1. Szukam alternatywy, dzięki za kopnięcie we właściwym kierunku.
roboslone

Niestety, pyinstaller nie działa z Django 1.9, a py2app / py2exe nie obsługuje linuxa :(
roboslone

2
jeśli cx_Freeze i pyinstaller nie działają, wciąż jest nadzieja. Możesz utworzyć pakiety dla dystrybucji docelowych, które rozwiążą wszystkie zależności związane z instalacją. A może użyj czegoś takiego jak docker, aby uruchomić aplikację.
KeatsPeeks,

1
inne opcje to nuitka i cython
denfromufa

Odpowiedzi:


121

Istnieją dwa sposoby rozwiązania problemu

  1. Użyj konstruktora statycznego, takiego jak zamrażanie lub pyinstaller, lubpy2exe
  2. Skompiluj za pomocą cython

Wyjaśnię, jak możesz to zrobić za pomocą drugiej, ponieważ pierwsza metoda nie jest wieloplatformowa i wersja, i została wyjaśniona w innych odpowiedziach. Ponadto używanie programów takich jak pyinstaller zwykle powoduje ogromne rozmiary plików, przy czym użycie cythona spowoduje powstanie pliku o rozmiarze KB

Najpierw zainstaluj cython. Następnie zmień nazwę pliku Pythona (powiedzmy test.py) na .pyxplik

sudo pip install cython
mv test.py test.pyx

Następnie możesz użyć cythonrazem z GCC do skompilowania go ( cythongeneruje plik C z pliku Python .pyx, a następnie GCC kompiluje plik C)

(w odniesieniu do 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

UWAGA : W zależności od wersji Pythona może być konieczna zmiana ostatniego polecenia. Aby dowiedzieć się, której wersji Pythona używasz, po prostu użyj

$ python -V

Będziesz mieć teraz plik binarny „test”, którego szukasz

Inne uwagi :

  1. Cython jest używany do używania definicji zmiennych typu C do statycznej alokacji pamięci w celu przyspieszenia programów w Pythonie. Jednak w twoim przypadku nadal będziesz używać tradycyjnych definicji Pythona.
  2. Jeśli używasz dodatkowych bibliotek (jak opencvna przykład), może być konieczne dostarczenie im katalogu za pomocą, -La następnie określenie nazwy biblioteki używanej -lwe flagach GCC. Więcej informacji na ten temat można znaleźć w sekcji Flagi GCC

20
Cześć, co jeśli moja aplikacja obejmuje wiele plików. To podejście wydaje się kompilować tylko bieżący skrypt, a nie wszystkie zależności Pythona.
RChat

2
nie ma potrzeby zmieniania nazwy pliku Pythona (powiedzmy test.py) na pyx w tej chwili
iMath

3
To było dla mnie bardzo pomocne. Aby odpowiedzieć na pytanie dotyczące wielu plików, możesz użyć cythonize: cythonize -i file_0.py [...] file_n.pydla wszystkich modułów Pythona, a następnie cython main_file.py --embeddla głównego skryptu. Otrzymasz pliki wykonywalne i .so (.dll, .dylib w zależności od systemu operacyjnego), których możesz używać razem jako samodzielne rozwiązanie.
afp

Otrzymuję komunikat „Brak modułów o nazwie kodowania”. Dowiedziałem się, że potrzebuję pewnych plików z instalacji Pythona. Jednak mój system docelowy nie ma języka Python. Proszę pomóż.
abhiarora

9

Możesz chcieć zbadać Nuitka . Pobiera kod źródłowy Pythona i konwertuje go na wywołania API C ++. Następnie kompiluje się do wykonywalnego pliku binarnego (ELF w systemie Linux). Istnieje już od kilku lat i obsługuje szeroką gamę wersji Pythona.

Prawdopodobnie uzyskasz również poprawę wydajności, jeśli go użyjesz. Zalecana.


Nie mogłem znaleźć żadnych informacji o używaniu Nuitka z Django. Czy masz przypadkiem takie doświadczenie?
roboslone

@roboslone, Prakhar Agarwal Cython bardzo dobrze obsługuje zewnętrzne biblioteki w porównaniu do statycznego kreatora Nuitka PyPy. Na przykład z linku na końcu tego komentarza wynika, że ​​„ludzie używają Cythona, ponieważ pomaga im to w rozwiązaniu problemu. Oznacza to, że chcą połączyć się z zewnętrznymi bibliotekami innymi niż Python z kodu Pythona lub chcą mieć możliwość ręcznie zoptymalizować ich kod lub jedno i drugie. ”, link to blog.behnel.de/posts/indexp241.html
RS Nikhil Krishna

1
RS Nikhil Krishna, nie próbuję przyspieszyć mojego kodu, próbuję wysłać go w jednym pliku binarnym z wbudowanym interpretera Pythona.
roboslone

No dobrze. Myślałem, że chcesz go powiązać z jakąś zewnętrzną biblioteką. Mój błąd.
RS Nikhil Krishna


1

Jeśli korzystasz z komputera Mac, możesz użyć py2app, aby utworzyć pakiet .app, który uruchamia aplikację Django po dwukrotnym kliknięciu.

Opisałem, jak połączyć Django i CherryPy w taki pakiet na https://moosystems.com/articles/14-distribute-django-app-as-native-desktop-app-01.html

W artykule używam pywebview do wyświetlania Twojej strony Django w lokalnym oknie aplikacji.


Moja aplikacja działa głównie na Linuksie, więc py2app nie działa
roboslone

Chociaż artykuł używa py2app, można to zrobić również za pomocą pyinstaller.
André Aulich

0

Opcje zamrażania:

Jednak serwer docelowy powinien mieć żądane środowisko -> powinieneś być w stanie je „stworzyć”. Jeśli tak się nie stanie, powinieneś zbudować oprogramowanie tak, aby pasowało do środowiska.

Znalazłem ten przydatny przewodnik, jak zainstalować niestandardową wersję Pythona na virtualenv, zakładając, że masz dostęp do ssh: https://stackoverflow.com/a/5507373/5616110

W virtualenv powinieneś być w stanie zainstalować wszystko za pomocą pip i nie powinieneś martwić się o uprawnienia sudo. Oczywiście posiadanie ich i dostęp do menedżera pakietów, takiego jak apt, znacznie ułatwia wszystko.


Używam już virtualenv, tak nie jest. Moje pytanie dotyczy statycznie skompilowanego Pythona z wymaganymi modułami i aplikacjami.
roboslone

Następnie musisz go zamrozić, nie ma innego wyjścia.
iScrE4m
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.