Cythonを使用してメインのPythonプログラムをコンパイルする


81

Cythonを使用して.soファイルにコンパイルされたPythonモジュールをロードできるPython2.6プログラムがあります。Cythonを使用して.pyモジュールを.soファイルにコンパイルしましたが、すべて正常に動作します。

これは私がCythonで使用するsetup.pyファイルです:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

ext_modules = [
    Extension("ldap", ["ldap.pyx"]),
    Extension("checker", ["checker.pyx"]),
    Extension("finder", ["finder.pyx"]),
    Extension("utils", ["utils.pyx"]),
]

setup(
  name = 'bchecker',
  cmdclass = {'build_ext': build_ext},
  ext_modules = ext_modules
)

したがって、Cythonを使用してPythonモジュールをコンパイルできることはわかっています(CythonはPythonファイルから「C」ファイルを作成してからコンパイルします)が、メインのPythonプログラムをLinuxプラットフォームで実行できるものにコンパイルできますか?もしそうなら、Cythonコマンドラインの例をいただければ幸いです。ありがとう。


4
これらの回答のいずれかが役に立ちましたか?これは機能しましたか?もしそうなら、答えを受け入れてください
マイクペニントン

3
これがマークされることはないだろう-ユーザーは質問の編集日の翌日に最後に見られた。
壊れた男

回答:


152

Adam Matanや他の人が主張していることとは反対に、実際には、純粋なPython(.py)ファイルからCythonを使用して単一の実行可能バイナリファイルを作成できます。

はい、Cythonは、CPythonpythonランタイム用のC / C ++拡張モジュールの記述を簡素化する方法として前述のように使用することを目的としています。

ただし、nudzoがこのコメントでほのめかしているように--embed、コマンドラインプロンプトでスイッチを使用できます。

これは非常に簡単な例です。私はこれをDebianSidワークステーションからpython3とcython3を使用して実行しています。

事前にpython-devまたはpython3-devパッケージがインストールされていることを確認してください。

1)hello.pyという非常に単純なPythonプログラムを作成します

$ cat hello.py

print( "Hello World!")

2) Cythonを使用してPythonプログラムをCにコンパイルします...

cython3 --embed -o hello.c hello.py

3) GCCを使用して、hello.cをhello ...という実行可能ファイルにコンパイルします。

gcc -Os -I /usr/include/python3.3m -o hello hello.c -lpython3.3m -lpthread -lm -lutil -ldl

4)hello ...というファイルになります。

$ file hello

こんにちは:ELF 64ビットLSB実行可能ファイル、x86-64、バージョン1(SYSV)、動的リンク(共有ライブラリを使用)、GNU / Linux 2.6.32、BuildID [sha1] = 006f45195a26f1949c6ed051df9cbd4433e1ac23、ストリップされていません

$ ldd hello
linux-vdso.so.1 (0x00007fff273fe000)
libpython3.3m.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython3.3m.so.1.0 (0x00007fc61dc2c000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc61da0f000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc61d70b000)
libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007fc61d508000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc61d304000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc61cf5a000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007fc61cd52000)
libexpat.so.1 => /lib/x86_64-linux-gnu/libexpat.so.1 (0x00007fc61cb28000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fc61c90f000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc61e280000)

この場合、実行可能ファイルは私のDebianシステム上のPython3.3に動的にリンクされています。

5)こんにちはを実行します...

$ ./hello

"こんにちは世界"

ご覧のとおり、このメソッドを使用すると、基本的にCythonを使用して、純粋なPythonアプリケーションを実行可能なコンパイル済みオブジェクトコードに変換できます。

私はこのメソッドを非常に複雑なアプリケーション(たとえば、本格的なPython / PySide / Qtアプリケーション)に使用しています。

Pythonのさまざまなバージョンでは、gcc-I-lスイッチを適切に調整します。

その後、Python / PySide / Qtファイルをパッケージ化することなく、実行可能ファイルをディストリビューション(.debなど)ファイルとしてパッケージ化できます。これには、ディストリビューションを同じファイルに更新した後でも、アプリケーションを実行できるという利点があります。そのディストリビューションのPythonなどのバージョン。


この埋め込みメソッドを使用して、実行可能ファイルの代わりにダイナミックライブラリを生成できますか?
denfromufa 2014年

5
モジュールを実行可能ファイルにコンパイルしません。ポータブル実行可能ファイルを持つことは可能ですか?つまり、ソースコードにインポートされたすべてのモジュールがその実行可能ファイルにコンパイルされます。@BrokenMan
Devesh Saini

1
@DeveshSaini私はそのビットを理解しようとして時間を費やしていません。本格的なpython + Pysideアプリケーションを上記のようにコンパイルすることができた唯一の方法は、通常の方法でプログラムを開発することでした-多くのインクルード<mymodule>ステートメント+インタープリターによるテスト。次に、すべての準備ができたら、含まれているすべてのコードを手動で貼り付け、置き換えられた関連するincludeステートメントをコメントアウトします。はい、それは望ましくありませんが、最初に言ったように、メインルーチンだけをコンパイルして、含まれているモジュールをリンクする方法を確認するために時間を費やしていません。
壊れた男

3
libpythonの静的リンクはどうですか?
James Mills

4
Python 2.7cython --embed -o /tmp/a.c a.pyおよびgcc -Os -I /usr/include/python2.7 -o /tmp/a/tmp/a.c -lpython2.7 -lpthread -lm -lutil -ldl
dsaydon 2018

17

CythonをEXEにコンパイルできますか?の回答をご覧ください。これは、ここでの他のすべての回答とは異なり、「はい」と言っていますが、実行可能ファイルにコンパイルすることは可能です。

Embedding Cythonのリンクから始めるのは良いようですが、Cythonの主な目的ではないため、どれほど簡単かはわかりません。


1
リンクをありがとう。また、Pythonを使用して実行可能コードを含む.soファイルを作成することも可能だと思います。
mozza 2011

4

これが役立つかどうかはわかりませんが、Nudzoは正しいです。あなたはそれを手に入れることができますcython --embed -o main.o main.pyそしてそれから私はcl / EHscで結果をコンパイルしようとします


-21

CythonはPythonをコンパイルしたり、実行可能ファイルに変換したりするようには作られていません。

.exeファイルを生成するには、py2exeを使用します。

MacまたはLinux用のパッケージを作成するには、Unix envのスクリプト言語プログラムに固有のものがないため、通常のパッケージングシステムプロセスを使用します。


2
それで、.pyファイルを.soファイルに変えることができます。私が使用している上記のスクリプトを参照してください。.soファイルに実行可能コードが含まれていませんか?
mozza 2011

それは目的ではありません。Cythonは、C / C ++ Python拡張機能をコンパイルするためのものであり、Pythonスクリプトを実行可能ファイルにするためのものではありません。
e-

10
誤報。cython --embedPythonを埋め込んで実行可能ファイルを生成できるものがあります。
nudzo 2014年

結果の実行可能ファイルは、静的にリンクしない限り、libpythonに依存します。さらに、すべてのファイルから1つの実行可能ファイルを生成するのではなく、エントリポイントから1つの実行可能ファイルを生成します。
e-satis 2014年

2
@ e-satisはい、実行可能ファイルは、その時点でコンパイルされたlibpythonのバージョンに動的にリンクされます。何が問題なのですか?Linux用であり、アプリケーションの配布を計画している場合は、他のすべてのバイナリパッケージと同じように、ターゲットとするLinux配布形式にパッケージ化するだけです。たとえば、myapp_1_wheezy_amd64.debは、そのディストリビューションのpython2またはpython3のいずれかに対してリンクされたコンパイル済みのPythonアプリになります。Windowsの場合は、必要なPythonを提供するだけです。繰り返しますが、私はここで問題や異議を見ることができません。
壊れた男
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.