如何在Python包中包含共享C库
我有一个依赖于共享库的项目。从一开始就要说明:共享库是一个纯C库,而不是Python库。为了简单起见,我创建了一个名为pkgtest的小演示项目,我将参考它 因此,需要做的是:运行一个Makefile来编译库,并将编译后的共享库(称为如何在Python包中包含共享C库,python,makefile,setuptools,Python,Makefile,Setuptools,我有一个依赖于共享库的项目。从一开始就要说明:共享库是一个纯C库,而不是Python库。为了简单起见,我创建了一个名为pkgtest的小演示项目,我将参考它 因此,需要做的是:运行一个Makefile来编译库,并将编译后的共享库(称为libhello.Sohere)文件放在某个可以从Python包中访问的地方 到目前为止,我的最佳猜测是将makefile作为预安装例程运行,复制packages目录中的libhello.so文件,并将其添加到安装脚本的package\u data参数中。安装后,共
libhello.So
here)文件放在某个可以从Python包中访问的地方
到目前为止,我的最佳猜测是将makefile作为预安装例程运行,复制packages目录中的libhello.so
文件,并将其添加到安装脚本的package\u data
参数中。安装后,共享库将被放置在site packages/pkgtest/
目录中,并可从模块中访问
包目录的结构如下所示:
pkgtest/
src/
libhello.c
libhello.h
Makefile
pkgtest/
__init__.py
hello.py
setup.py
我的setup.py如下所示:
setup.py
Makefile实际上构建了库并将其复制到python包的目录中
src/Makefile
因此,hello.py
实际上所做的就是加载库并调用打印一些文本的hello
函数。但为了完整起见,我将在此处显示代码:
pkgtest/hello.py
这实际上是可行的,但我不喜欢这种方法,因为共享库位于Python包的目录中。我认为最好将它放在某种中央库目录中,比如/usr/lib/。但对于这个,安装时需要root权限。是否有人对此类问题有一些经验,并愿意分享解决方案或有用的想法。那太好了。您可以创建一个包含共享库的Python包,并使用它在(几乎)任何linux发行版上工作 manylinux项目的目标是提供一种方便的方法,在Linux上以轮子的形式分发二进制Python扩展。这项工作产生了定义
manylinux1_x86_64
和manylinux1_i686
平台标记的
一般程序是:
有关示例,请参见python manylinux演示中的和。
包数据
用于数据<代码>设置可以编译成*。因此
按照我在中的解决方案,我认为您的设置
可以使用ext\u模块
和py\u模块
,类似于
setup(name='pkgtest',
py_modules=['pkgtest'],
ext_modules=[Extension('src.libhello', ['src/libhello.c'])]
)
您是否考虑过使用类似的包管理器?您可以为库和Python代码创建一个单独的包,并在
meta.yaml
文件中将库指定为Python代码的依赖项。您是对的,这肯定是一个选项,但不是我的第一选择,因为我希望通过pip install…
提供该软件包。在这种情况下,我不认为在python软件包文件夹中有编译过的库文件是一个问题。这是放置和模块的位置。但也许有更好的解决方案……我看不出有什么理由首先要有一个Makefile。简单的C对象文件可以通过setuptools等自动编译和安装。看见[.我仅以上面的库为例。实际的库更复杂,有多个源文件和链接。我没有看到如何使用setuptools实现这一点。这看起来很棒。如果我做对了,这个示例将展示如何构建Python C扩展并将其包含在程序中。正如问题中所述,目标不是构建Python C扩展ion但构建并包含一个纯C共享库。我仍然不知道如何管理它。@Mrleh:我还在搜索几乎相同的解决方案(Fortran而不是C)。您找到解决方法了吗?包含内部[而不是外部]的过程是什么bdist\u wheel中的共享库
?为什么要使用py\u模块
?它不应该是包
?
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
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()
setup(name='pkgtest',
py_modules=['pkgtest'],
ext_modules=[Extension('src.libhello', ['src/libhello.c'])]
)