1. ホーム
  2. python

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

2022-10-15 17:14:19

質問

私は自分のコードをリモートサーバーに送信しようとしています。リモートサーバーは異なるバージョンの python をインストールしているかもしれませんし、私のアプリが必要とするパッケージを持っていないかもしれません。

現在、そのような移植性を達成するために、私はインタプリタとコードで再配置可能な仮想環境を構築する必要があります。このアプローチにはいくつかの問題があります (例えば、多くのライブラリを手動で仮想環境にコピーする必要があります、なぜなら --always-copy は期待通りには動作しないので)、一般的に遅いです。

そこには (理論的には) を使えば、python 自体を静的にビルドすることができます。

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

どのように解決するのですか?

問題を解決するには、2つの方法があります。

  1. freeze のような静的ビルダーを使用するか、または pyinstaller のような静的ビルダーを使うか、あるいは py2exe
  2. を使ってコンパイルします。 cython

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

まず、インストールします。 cython . そして、Python ファイルの名前を変更します。 test.py とします) を .pyx ファイル

sudo pip install cython
mv test.py test.pyx

次に cython と共に GCC を使ってコンパイルします ( cython は Python の .pyx ファイルからCファイルを生成し、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は、Pythonプログラムを高速化するために、静的なメモリ割り当てのためのC-Type変数定義を使用するために使用されます。しかし、あなたのケースでは、まだ伝統的な Python 定義を使用することになります。
  2. もし、追加のライブラリ (例えば opencv のような) 追加のライブラリを使用する場合、そのディレクトリを -L でディレクトリを指定し、ライブラリ名を -l を GCC Flags で指定します。これについては、GCC flagsを参照してください。