Лучший способ упаковать библиотеку Python, которая включает в себя общую библиотеку C?

Я написал библиотеку, основная функциональность которой реализована на C (скорость критическая), с тонким слоем Python вокруг нее, чтобы справиться с ctypes nastiness.

Я приду, чтобы упаковать его, и мне интересно, как мне лучше всего поступить по этому поводу. Код, с которым он должен взаимодействовать, является общей библиотекой. У меня есть Makefile, который создает код C и создает файл .so, но я не знаю, как это сделать с помощью distutils. Должен ли я просто вызвать make с помощью subprocess, переопределив команду install (если это так, install место для этого или более build?)

Обновить. Я хочу отметить, что это не расширение Python. То есть, библиотека C не содержит кода для взаимодействия с временем выполнения Python. Python вызывает вызовы внешних функций в прямую C-библиотеку.

Ответ 1

Учитывая, что вы выполнили инструкции о том, как создать расширения Python в C, вам нужно просто заручиться модулями расширения, например, в эта документация.
Таким образом, setup.py script вашей библиотеки должен выглядеть следующим образом:

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

и distutils знает, как скомпилировать расширение в C-библиотеку и, кроме того, куда его поместить.

Конечно, у меня нет дополнительной информации о вашей библиотеке, поэтому вы, вероятно, захотите добавить больше аргументов в вызов setup(...).

Ответ 2

Я бы подумал о создании модуля python в качестве подпроекта обычной сборной библиотеки. Итак, используйте automake, autoconf или что-то в этом роде для создания общей библиотеки, создайте каталог python_bindings с помощью setup.py и вашего модуля python.

Ответ 3

У меня была аналогичная потребность и нашла этот ответ полезным: Python setup.py make make make не содержит бинарные файлы.

У меня есть библиотека ANSI C в каталоге src моего дистрибутива. В каталоге src находится файл Makefile, который создает файл с именем liblsd.so в моем каталоге пакетов (lsd). Я вызываю это в 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='[email protected]',
  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',
      ],
 )