我有一个项目取决于共享库。从头开始说明:共享库是纯C库而不是Python库。为简单起见,我创建了一个名为 pkgtest 的小型演示项目,我将参考该项目。
所以需要做的是:运行Makefile来编译库并将编译好的共享库(在此处称为libhello.so
)文件放在某个地方,可以从依赖的Python包中访问它。
到目前为止,我最好的猜测是将makefile作为预安装例程运行,将libhello.so
文件复制到packages目录中,并将其添加到安装脚本的package_data
参数中。安装后,共享库将被放置在site-packages/pkgtest/
目录中,并且可以从模块访问。
包目录的结构就像这样简单:
pkgtest/
src/
libhello.c
libhello.h
Makefile
pkgtest/
__init__.py
hello.py
setup.py
我的setup.py看起来像这样:
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实际上构建了库并将其复制到我的python包的目录中。
的src /生成文件
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 :(得分:3)
您可以创建一个包含共享库的Python包,并使用manylinux(几乎)在任何Linux发行版上工作。
manylinux项目的目标是提供一种方便的方法来将二进制Python扩展作为Linux上的轮子进行分发。这项工作产生了PEP 513,用于定义
manylinux1_x86_64
和manylinux1_i686
平台广告代码。
一般程序是:
auditwheel repair
将包所依赖的外部共享库复制到Python滚轮中,相应地设置RPATH。请参阅python-manylinux-demo
回购中的.travis.yml
和build-wheels.sh
作为示例。
答案 1 :(得分:0)
package_data
用于数据。 setup
可以编译成*.so
。
按照我在python setup.py build ctypes.CDLL: cannot open shared object file: No such file or directory中的解决方案,我认为您的setup
可以雇用ext_modules
和py_modules
,类似
setup(name='pkgtest',
py_modules=['pkgtest'],
ext_modules=[Extension('src.libhello', ['src/libhello.c'])]
)