2013-06-07 19 views
30

私はを使用してpythonアプリケーションとCで書かれたサードパーティライブラリを統合しようとしています。私はテストのために書かれたすべてのPythonコードを持っています。これを設定する例が見つからない。Cythonを使用してPythonを共有ライブラリにリンクする

手動で作成したpyd/pyxファイルがあります。第三者が私にheader file (*.h)shared library (*.so)を与えました。私が知る限り、他の依存関係はありません。誰かがCythondisutilsを使用してこれを設定する方法の例を提供できますか?

ありがとうございました

答えて

48

確かに!

(以下では、私はあなたがすでにcimport.pxd.pyxの間の相互作用に対処する方法を知っていることを前提としています。これは完全に当​​てはまらない場合は、ちょうど尋ねると、私もその部分を開発します)

サンプル(私のC++プロジェクトからつかんだが、Cのプロジェクトはほとんど同じ動作します):

1. Distutilsのセットアップファイル:作成する拡張機能をbになると仮定すると

:あなた外部 .soファイル librariesオプションを介して連結されている:注は

# setup.py file 
import sys 
import os 
import shutil 

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

# clean previous build 
for root, dirs, files in os.walk(".", topdown=False): 
    for name in files: 
     if (name.startswith("myext") and not(name.endswith(".pyx") or name.endswith(".pxd"))): 
      os.remove(os.path.join(root, name)) 
    for name in dirs: 
     if (name == "build"): 
      shutil.rmtree(name) 

# build "myext.so" python extension to be added to "PYTHONPATH" afterwards... 
setup(
    cmdclass = {'build_ext': build_ext}, 
    ext_modules = [ 
     Extension("myext", 
        sources=["myext.pyx", 
          "SomeAdditionalCppClass1.cpp", 
          "SomeAdditionalCppClass2.cpp" 
         ], 
        libraries=["externlib"],   # refers to "libexternlib.so" 
        language="c++",     # remove this if C and not C++ 
        extra_compile_args=["-fopenmp", "-O3"], 
        extra_link_args=["-DSOME_DEFINE_OPT", 
            "-L./some/extra/dependency/dir/"] 
      ) 
     ] 
)   

...(ここで、*プレフィックスをLIBに注意してください)eはmyextと呼ばれ、サードパーティの共有ライブラリがlibexternlib.soです

libraries=["externlib"] # Without the 'lib' prefix and the '.so' extension... 

注:sourcesオプションを使用して、追加のソースファイルをコンパイルすることができます。

重要myext.pxd.pydと混同していない - Windowsのものを)とmyext.pyxは同じディレクトリにある必要があります。コンパイル時に、定義ファイルが存在する場合、最初に処理されます(more)。

2。次のようにそれを実行します。あなたのmyext.pxd、あなたのmyext.pyx、並びに上のsetup.pyスクリプトを含む1にディレクトリを変更した後

を:

# setup.sh 
# Make the "myext" Python Module ("myext.so") 
CC="gcc" \ 
CXX="g++" \ 
CFLAGS="-I./some/path/to/includes/ -I../../../DEPENDENCIES/python2.7/inc -I../../../DEPENDENCIES/gsl-1.15" \ 
LDFLAGS="-L./some/path/to/externlib/" \ 
    python setup.py build_ext --inplace 

どこ:

  • libexternlib.soがあります./some/path/to/externlib/
  • yourheader.hに位置するものとする。

注:CFLAGSextra_compile_argsオプションを使用して設定されている可能性が:

extra_compile_args=["-I./some/path/to/includes/", "-fopenmp", "-O3"] 

注:LDFLAGSextra_link_argsオプションを使用して設定されている可能性が:

extra_link_args=["-L./some/path/to/externlib/", "-DSOME_DEFINE_OPT", "-L./some/extra/dependency/dir/"] 

ビルドでdistutilsを実行すると、新しいファイル、特にmyext.cpp,myext.hがあり、最も重要なのはmyext.soです。その後

3.、あなたが行ってもいいです:あなたのたて作成したPythonの拡張は、その名前でインポートすることができます

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./some/path/to/externlib/ 
export PYTHONPATH=$PYTHONPATH:./some/path/to/myext/ 

# Run some script requiring "myext.so" 
python somescript.py 

# somescript.py 
import myext 
from myext import PySomeFeature 
... 

の最適化について:デフォルトでは、拡張子のコンパイルには-O2が使用されていますが、これはオーバーロードする可能性があります(上の設定を参照してください。-O3が指定されています)。 Cythonパスに関する

:Cythonは、カスタムディレクトリにインストールした場合、あなたが前にすべて、ご使用の環境に追加する場合があります

PYTHONPATH=$PYTHONPATH:../../../DEPENDENCIES/Cython-0.18 export PYTHONPATH; 
PATH=$PATH:../../../DEPENDENCIES/Cython-0.18/bin; export PATH; 

まあ、私は要点をカバー願っています。..

+0

お世話になりました。私は次のエラーが表示されます:ld:ライブラリが見つからない-lMYLIB MYLIB.soがリンクしようとしているファイルです - 任意のアイデアですか? – josephmisiti

+0

これを忘れてしまいました。gcc -lコマンドはあなたの* .soがlibで始まると仮定しているので、これを削除して見つけたので、動作しているようです。 – josephmisiti

+0

それを聞いてうれしい。乾杯;-) –

関連する問題