2017-07-15 8 views
3

私は共有ライブラリに依存してプロジェクトを持っています。最初から明確にするために、共有ライブラリは純粋なCライブラリであり、Pythonライブラリではありません。簡単にするために、私が参照するpkgtestと呼ばれる小さなデモプロジェクトを作成しました。共有CライブラリをPythonパッケージに含める方法

それでは、Makefileを実行してライブラリをコンパイルし、コンパイルされた共有ライブラリ(ここではlibhello.soという)ファイルを依存するPythonパッケージ内のどこかにアクセスできる場所に置きます。

メイクファイルをインストール前のルーチンとして実行するには、libhello.soファイルをパッケージディレクトリにコピーし、セットアップスクリプトのpackage_dataパラメータに追加してください。共有ライブラリをインストールすると、site-packages/pkgtest/ディレクトリに配置され、モジュールからアクセスできます。

パッケージディレクトリ構造である。このような単純なです:

setup.py

import subprocess 
from setuptools import setup 
from distutils.command.install import install as _install 


class install(_install): 
    def run(self): 
     subprocess.call(['make', 'clean', '-C', 'src']) 
     subprocess.call(['make', '-C', 'src']) 
     _install.run(self) 


setup(
    name='pkgtest', 
    version='0.0.1', 
    author='stefan', 
    packages=['pkgtest'], 
    package_data={'pkgtest': ['libhello.so']}, 
    cmdclass={'install': install}, 
) 

のMakefileを実際に構築します。

pkgtest/ 
    src/ 
    libhello.c 
    libhello.h 
    Makefile 
    pkgtest/ 
    __init__.py 
    hello.py 
    setup.py 

私のsetup.pyは、このようになりますライブラリをコピーしてpythonパッケージのディレクトリにコピーします。

のsrc/Makefileの

all: libhello.so 

libhello.o: libhello.c 
     gcc -fPIC -Wall -g -c libhello.c 

libhello.so: libhello.o 
     gcc -shared -fPIC -o libhello.so libhello.o 
     cp libhello.so ../pkgtest/libhello.so 

clean: 
     rm -f *.o *.so 

のでhello.pyが実際にやっているすべてのライブラリをロードし、いくつかのテキストを印刷しhello関数を呼び出しています。しかし、完全を期すために、私はここにコードが表示されます:

pkgtest/hello.pyを

import os 
import ctypes 

basedir = os.path.abspath(os.path.dirname(__file__)) 
libpath = os.path.join(basedir, 'libhello.so') 

dll = ctypes.CDLL(libpath) 

def say_hello(): 
    dll.hello() 

だから、これは実際に動作しますが、私はこのアプローチについては好きではないことで、共有ライブラリの命でありますPythonパッケージのディレクトリ。 /usr/lib/のような何らかの中央ライブラリディレクトリに置く方が良いかもしれないと思います。しかし、これはインストール時にroot権限が必要です。誰かがこのような問題を経験したことがあり、解決策や有益なアイデアを共有したいと思いますか?素晴らしいことだ。

+0

[conda](https://conda.io/miniconda.html)のようなパッケージマネージャを使用したことがありますか?ライブラリとPythonコード用に別々のパッケージを作成し、Pythonコードの依存関係としてライブラリを 'meta.yaml'ファイルに指定することができます。 – ostrokach

+0

私はまだコンドームは考えていませんでした。あなたは正しいですが、これは間違いなく選択肢になりますが、私の最初の選択肢ではなく、 'pip install ... 'を介してパッケージを利用できるようにしたいのです。 – MrLeeh

+0

その場合、私はあなたのpythonパッケージのフォルダ内にコンパイルされたライブラリファイルを持つことは問題だとは思わない。それは[Python拡張モジュール](https://docs.python.org/3/extending/building.html)と[Cython](http://docs.cython.org/ja/latest/index.html)モジュールです配置される。しかし、おそらくもっと良い解決策があります... – ostrokach

答えて

2

共有ライブラリを含むPythonパッケージを作成し、manylinuxを使用して(ほぼ)任意のLinuxディストリビューションで動作させることができます。

manylinuxプロジェクトの目標は、バイナリのPython拡張モジュールをLinux上でホイールとして配布する便利な方法を提供することです。この努力により、manylinux1_x86_64およびmanylinux1_i686のプラットフォームタグを定義するPEP 513が生成されました。

一般的な手順は以下のとおりです。

  1. が外部にコピーする
  2. python-manylinux-demoを参照)を実行しauditwheel repairをmanylinuxチーム が提供するドッキングウィンドウコンテナの1内部外部ライブラリとPythonパッケージをビルドしますあなたのパッケージが依存する共有ライブラリをPythonホイールに依存させ、それに応じてRPATHを設定します。

は、例えばpython-manylinux-demoレポに.travis.ymlbuild-wheels.shを参照してください。

+0

これはすばらしく見える。もし私が正しいとすれば、この例は、PythonのC拡張をビルドし、それをホイールに組み込む方法を示しています。質問に記載されているように、目的はPython C拡張をビルドするのではなく、純粋なC共有ライブラリをビルドしてインクルードすることです。私はまだそれを管理する方法を理解することはできません。 – MrLeeh

関連する問題