Pythonアプリケーションを静的バイナリにコンパイルする方法はありますか?


83

私がやろうとしているのは、コードをリモートサーバーに送信することです。リモートサーバーには、異なるPythonバージョンがインストールされているか、アプリに必要なパッケージがない可能性があります。

現在、このような移植性を実現するには、インタープリターとコードを使用して再配置可能なvirtualenvを構築する必要があります。このアプローチにはいくつかの問題があり(たとえば、--always-copy期待どおりに機能しないため、多数のライブラリを手動でvirtualenvにコピーする必要があります)、一般的に低速です。

(理論的には)Python自体を静的に構築する方法があります。

インタプリタとコードを1つのバイナリにパックして、アプリケーションをモジュールとして実行できるかどうか疑問に思います。そのようなもの:./mypython -m myapp runまたは./mypython -m gunicorn -c ./gunicorn.conf myapp.wsgi:application


cx_freezeのような意味ですか?
TigerhawkT3 2016年

@ TigerhawkT3、今日までcx_freezeのことを聞いたことがありません。ドキュメントを見ると、私が欲しいもののようですが、python3.5.1を使用したUbuntu12.04.5でのビルドに失敗します。正しい方向へのキックに感謝し、私は代替案を探しています。
roboslone 2016年

残念ながら、pyinstallerはDjango 1.9で動作せず、py2app / py2exeはLinuxをサポートしていません:(
roboslone 2016年

2
cx_Freezeとpyinstallerが機能しない場合でも、希望はあります。インストールへのすべての依存関係を解決するターゲットディストリビューションのパッケージを作成できます。または、dockerなどを使用してアプリを実行することもできます。
KeatsPeeks 2016年

1
他のオプションはnuitkaとcythonです
denfromufa

回答:


116

問題を解決する方法は2つあります

  1. 、フリーズのように、静的ビルダーを使用するかpyinstaller、またはpy2exe
  2. を使用してコンパイル cython

最初の方法はクロスプラットフォームとバージョンではなく、他の回答で説明されているため、2番目の方法を使用してそれを行う方法を説明します。また、pyinstallerのようなプログラムを使用すると、通常、ファイルサイズが大きくなりますが、cythonを使用すると、ファイルのサイズがKBになります。

まず、をインストールしcythonます。次に、Pythonファイル(たとえばtest.py)の名前をファイルに変更し.pyxます

sudo pip install cython
mv test.py test.pyx

次に、cythonGCCと一緒に使用してコンパイルできます(cythonPythonからCファイルを生成します).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

これで、探しているものであるバイナリファイル「test」が作成されます。

注意すべきその他の事項

  1. Cythonは、静的メモリ割り当てにCタイプ変数定義を使用して、Pythonプログラムを高速化するために使用されます。ただし、あなたの場合は、従来のPython定義を引き続き使用します。
  2. 追加のライブラリ(opencvたとえばなど)を使用している場合は、を使用してディレクトリを提供してから、GCCフラグで-Lを使用-lしてライブラリの名前を指定する必要があります。これについての詳細は、GCCフラグを参照してください。

19
こんにちは。アプリケーションが複数のファイルにまたがっている場合はどうなりますか。このアプローチは、現在のスクリプトのみをコンパイルし、すべてのPython依存関係をコンパイルするわけではないようです。
RChat 2016

2
今すぐPythonファイル(たとえばtest.py)の名前をpyxに変更する必要はありません
iMathJun

3
これは私にとって大きな助けになりました。複数のファイルに関する質問に答えるにはcythonize -i file_0.py [...] file_n.py、すべてのpythonモジュールにcythonize:を使用cython main_file.py --embedしてから、メインスクリプトに使用できます。最終的には、スタンドアロンソリューションとして一緒に使用できる実行可能ファイルと.soファイル(OSに応じて.dll、.dylib)が作成されます。
AFP

「エンコーディングという名前のモジュールはありません」というメッセージが表示されます。Pythonのインストールから特定のファイルが必要であることがわかりました。しかし、私のターゲットシステムにはPythonがありません。助けてください。
abhiarora

8

Nuitkaを調査することをお勧めしますます。Pythonのソースコードを受け取り、それをC ++ API呼び出しに変換します。次に、実行可能バイナリ(LinuxではELF)にコンパイルされます。数年前から存在しており、さまざまなPythonバージョンをサポートしています。

それを使用すると、おそらくパフォーマンスも向上します。推奨。


NuitkaをDjangoで使用することに関する情報が見つかりませんでした。万が一、そんな経験はありますか?
roboslone 2016年

@ roboslone、Prakhar Agarwal Cythonは、Nuitka PyPyの静的ビルダーと比較すると、外部ライブラリを非常によくサポートしています。たとえば、このコメントの最後にあるリンクから、「人々は問題の解決に役立つため、Cythonを使用しています。Pythonコードから外部の非Pythonライブラリに接続したい、または接続できるようにしたいということです。コードを手動で最適化するか、またはその両方を行います。」、リンクはblog.behnel.de/posts/indexp241.html
RS Nikhil Krishna

1
RS Nikhil Krishna、コードを高速化しようとはしていません。Pythonインタープリターを内部に組み込んだ1つのバイナリでコードを出荷しようとしています。
roboslone 2016年

ああ大丈夫。外部ライブラリとバインドしたいと思いました。私の悪い。
RS Nikhil Krishna 2016


0

フリーズオプション:

ただし、ターゲットサーバーには必要な環境が必要です->それを「作成」できるはずです。そうでない場合は、環境に合わせてソフトウェアを構築する必要があります。

sshアクセスがあると仮定して、Pythonのカスタムバージョンをvirtualenvにインストールする方法に関するこの便利なガイドを見つけました:https://stackoverflow.com/a/5507373/5616110

virtualenvでは、何でもpip installできるはずであり、sudo特権について心配する必要はありません。もちろん、それらとaptのようなパッケージマネージャーへのアクセスがあると、すべてがはるかに簡単になります。


私はすでにvirtualenvを使用していますが、そうではありません。私の質問は、静的にコンパイルされたpythonと必要なモジュールおよびアプリケーションについてです。
roboslone 2016年

次に、それをフリーズする必要があります。それを回避する方法は他にありません。
iScrE4m 2016年

0

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 2016年

この記事ではpy2appを使用していますが、pyinstallerを使用して行うこともできます。
アンドレ・Aulich
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.