2017-09-20 11 views
0

私は、C++拡張モジュールと必要な他の誰かの共有ライブラリを持つPythonパッケージを作っています。私はすべてpip経由でインストール可能にしたい。現在のsetup.pyファイルは、pip install -e .を使用しているときに動作しますが、開発モード(e.i. -eを省略)を使用しないときは、を取得します。モジュールをPythonでインポートするときにはです。その理由は、setuptoolsが共有ライブラリを私のパッケージの一部と見なさないため、ファイルがインストールディレクトリにコピーされるときに、ライブラリへの相対リンクがインストール中に壊れるからです。ここでパッケージインストールで(スクリプト作成の)ライブラリを含めるにはどうすればいいですか?

は私setup.pyファイルは次のようになります。

from setuptools import setup, Extension, Command 
import setuptools.command.develop 
import setuptools.command.build_ext 
import setuptools.command.install 
import distutils.command.build 
import subprocess 
import sys 
import os 

# This function downloads and builds the shared-library 
def run_clib_install_script(): 
    build_clib_cmd = ['bash', 'clib_install.sh'] 
    if subprocess.call(build_clib_cmd) != 0: 
     sys.exit("Failed to build C++ dependencies") 

# I make a new command that will build the shared-library 
class build_clib(Command): 
    user_options = [] 
    def initialize_options(self): 
     pass 
    def finalize_options(self): 
     pass 
    def run(self): 
     run_clib_install_script() 

# I subclass install so that it will call my new command 
class install(setuptools.command.install.install): 
    def run(self): 
     self.run_command('build_clib') 
     setuptools.command.install.install.run(self) 

# I do the same for build... 
class build(distutils.command.build.build): 
    sub_commands = [ 
     ('build_clib', lambda self: True), 
     ] + distutils.command.build.build.sub_commands 

# ...and the same for develop 
class develop(setuptools.command.develop.develop): 
    def run(self): 
     self.run_command('build_clib') 
     setuptools.command.develop.develop.run(self) 

# These are my includes... 
# note that /clib/include only exists after calling clib_install.sh 
cwd = os.path.dirname(os.path.abspath(__file__)) 
include_dirs = [ 
    cwd, 
    cwd + '/clib/include', 
    cwd + '/common', 
] 

# These are my arguments for the compiler to my shared-library 
lib_path = os.path.join(cwd, "clib", "lib") 
library_dirs = [lib_path] 
link_args = [os.path.join(lib_path, "libclib.so")] 

# My extension module gets these arguments so it can link to clib 
mygen_module = Extension('mygen', 
        language="c++14", 
        sources=["common/mygen.cpp"], 
        libraries=['clib'], 
        extra_compile_args=['-std=c++14'], 
        include_dirs=include_dirs, 
        library_dirs=library_dirs, 
        extra_link_args=link_args 
         + ['-Wl,-rpath,$ORIGIN/../clib/lib']) 

# I use cmdclass to override the default setuptool commands 
setup(name='mypack', 
     cmdclass = {'install': install, 
        'build_clib': build_clib, 'build': build, 
        'develop': develop}, 
     packages=['mypack'], 
     ext_package='mypack', 
     ext_modules=[mygen_module], 
     # package_dir={'mypack': '.'}, 
     # package_data={'mypack': ['docs/*md']}, 
     include_package_data=True) 

それは拡張子をコンパイルする前に、私は共有ライブラリを構築するためにsetuptoolsのコマンドの一部をサブクラス化。 clib_install.shは、ローカルで/clibに共有ライブラリをダウンロードしてビルドし、ヘッダー(/clib/include)と.soファイル(/clib/lib)を作成するbashスクリプトです。共有ライブラリの依存関係へのリンクに関する問題を解決するために、私は$ORIGIN/../clib/libをリンク引数として使用し、絶対パスをclibにする必要はありません。

残念ながら/clibディレクトリはインストール先にコピーされません。 package_dataで試してみましたが、私のディレクトリをコピーしませんでした。実際には、スクリプトが呼び出された後にpip/setuptoolsが/clibで何をするのかわからない、私はそれがいくつかの一時的なビルドディレクトリで作られた後に削除されると思います。私はどのように/clibをそれが作られた後にする必要があるに取得するか分からない。

答えて

0
package_data={ 
    'mypack': [ 
     'clib/include/*.h', 
     'clib/lib/*.so', 
     'docs/*md', 
    ] 
}, 
関連する問題