Python 如何在安装包时包含(脚本构建的)库?

Python 如何在安装包时包含(脚本构建的)库?,python,pip,setuptools,setup.py,python-c-api,Python,Pip,Setuptools,Setup.py,Python C Api,我正在制作一个Python包,它有一个C++扩展模块和它所需要的其他人的共享库。我希望所有东西都可以通过pip安装。当我使用pip install-e.时,我当前的setup.py文件可以工作,但当我不使用开发模式(即省略-e)时,在Python中导入模块时,我会得到“无法打开共享对象文件”。我相信原因是StuuTooPoT不认为共享库是我的包的一部分,所以当文件被复制到安装目录时,在安装过程中与库的相对链接被破坏。 下面是我的setup.py文件的外观: from setuptools imp

我正在制作一个Python包,它有一个C++扩展模块和它所需要的其他人的共享库。我希望所有东西都可以通过
pip
安装。当我使用
pip install-e.
时,我当前的
setup.py
文件可以工作,但当我不使用开发模式(即省略
-e
)时,在Python中导入模块时,我会得到“无法打开共享对象文件”。我相信原因是StuuTooPoT不认为共享库是我的包的一部分,所以当文件被复制到安装目录时,在安装过程中与库的相对链接被破坏。 下面是我的
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
是一个bash脚本,它在本地下载并在
/clib
中构建共享库,创建头文件(在
/clib/include
中)和.so文件(在
/clib/lib
中)。为了解决链接到共享库依赖项的问题,我使用
$ORIGIN/./clib/lib
作为链接参数,这样就不需要指向
clib
的绝对路径

不幸的是,
/clib
目录没有复制到安装位置。我试图修补
包的数据
,但它没有复制我的目录。事实上,我甚至不知道pip/setuptools在调用脚本后对
/clib
做了什么,我猜它是在某个临时构建目录中创建的,之后会被删除。我不知道制作后如何将
/clib
放到需要的位置

package_data={
    'mypack': [
        'clib/include/*.h',
        'clib/lib/*.so',
        'docs/*md',
    ]
},