如何在Python包中包含共享C库

如何在Python包中包含共享C库,python,makefile,setuptools,Python,Makefile,Setuptools,我有一个依赖于共享库的项目。从一开始就要说明:共享库是一个纯C库,而不是Python库。为了简单起见,我创建了一个名为pkgtest的小演示项目,我将参考它 因此,需要做的是:运行一个Makefile来编译库,并将编译后的共享库(称为libhello.Sohere)文件放在某个可以从Python包中访问的地方 到目前为止,我的最佳猜测是将makefile作为预安装例程运行,复制packages目录中的libhello.so文件,并将其添加到安装脚本的package\u data参数中。安装后,共

我有一个依赖于共享库的项目。从一开始就要说明:共享库是一个纯C库,而不是Python库。为了简单起见,我创建了一个名为pkgtest的小演示项目,我将参考它

因此,需要做的是:运行一个Makefile来编译库,并将编译后的共享库(称为
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
平台标记的

一般程序是:

  • 在manylinux团队提供的docker容器中构建外部库和Python包 (见附件)
  • 运行以将包所依赖的外部共享库复制到Python控制盘中,并相应地设置RPATH

  • 有关示例,请参见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'])]
         )