简体   繁体   English

打包包含C共享库的Python库的最佳方法是什么?

[英]Best way to package a Python library that includes a C shared library?

I have written a library whose main functionality is implemented in C (speed is critical), with a thin Python layer around it to deal with the ctypes nastiness. 我编写了一个库,其主要功能是用C实现的(速度很关键),周围有一个很薄的Python层来处理ctypes肮脏。

I'm coming to package it and I'm wondering how I might best go about this. 我要打包它,我想知道我最好怎么做。 The code it must interface with is a shared library. 它必须与之交互的代码是一个共享库。 I have a Makefile which builds the C code and creates the .so file, but I don't know how I compile this via distutils. 我有一个Makefile,它构建C代码并创建.so文件,但我不知道如何通过distutils编译它。 Should I just call out to make with subprocess by overriding the install command (if so, is install the place for this, or is build more appropriate?) 我是不是应该叫出来makesubprocess通过覆盖install命令(如果是这样, install的地方这一点,或者是build更合适?)

Update : I want to note that this is not a Python extension. 更新 :我想要注意,这不是 Python扩展。 That is, the C library contains no code to itself interact with the Python runtime. 也就是说,C库不包含自己与Python运行时交互的代码。 Python is making foreign function calls to a straight C shared library. Python正在对直接C共享库进行外部函数调用。

Given that you followed the instructions on how to create Python extensions in C , you should just enlist the extension modules like in this documentation . 鉴于您遵循了有关如何在C中创建Python扩展的说明,您应该像本文档中那样登记扩展模块。
So the setup.py script of your library should look like this: 因此,库的setup.py脚本应如下所示:

from distutils.core import setup, Extension
setup(
   name='your_python_library',
   version='1.0',
   ext_modules=[Extension('your_c_extension', ['your_c_extension.c'])],
)

and distutils knows how to compile your extension to C shared library and moreover where to put it. distutils知道如何编译扩展到C共享库,以及在哪里放置它。

Of course I have no further information about your library, so you probably want to add more arguments to setup(...) call. 当然我没有关于你的库的更多信息,所以你可能想要为setup(...)调用添加更多参数。

I'd consider building the python module as a subproject of a normal shared library build. 我会考虑将python模块构建为普通共享库构建的子项目。 So, use automake, autoconf or something like that to build the shared library, have a python_bindings directory with a setup.py and your python module. 因此,使用automake,autoconf或类似的东西来构建共享库,有一个带有setup.py的python_bindings目录和你的python模块。

I had a similar need and found this answer helpful: Python setup.py call makefile don't include binaries . 我有类似的需求,发现这个答案很有用: Python setup.py调用makefile不包含二进制文件

I have an ANSI C library in the src directory of my distribution. 我的发行版的src目录中有一个ANSI C库。 In the src directory is a Makefile that builds a file called liblsd.so in my package directory ( lsd ). src目录中有一个Makefile, liblsd.so在我的包目录( lsd )中构建一个名为liblsd.so的文件。 I call this in setup.py and then tell setup to include the library file using the package_data argument. 我在setup.py中调用它,然后告诉setup使用package_data参数包含库文件。

import os.path
import subprocess

from setuptools import setup

with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as f:
    readme = f.read()

subprocess.call(['make', '-C', 'src'])

setup(name='LSD',
  version='0.0.1',
  description='Python bindings for the LSD line segment detector.',
  long_description=readme,
  author='Geoff Hing',
  author_email='geoffhing@gmail.com',
  url='https://github.com/ghing/python-lsd',
  packages=['lsd'],
  package_data={'lsd': ['liblsd.so']},
  include_package_data=True,
  classifiers=[
      'Development Status :: 1 - Planning',
      'Intended Audience :: Developers',
      'License :: OSI Approved :: MIT License',
      'Operating System :: OS Independent',
      'Programming Language :: Python',
      'Programming Language :: C',
      ],
 )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM