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

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

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

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


person obeattie    schedule 05.06.2014    source источник
comment
У вас есть решение для вашей проблемы? Я застрял с тем же вопросом и отчаянно нуждаюсь в ответе;)   -  person MrLeeh    schedule 15.07.2017
comment
Это было очень давно, но, похоже, я решил эту проблему, раскошелившись на make. Это setup.py из этой библиотеки: gist.github.com/obeattie/3d491ec4c29b1d4b46387b285c91ca89   -  person obeattie    schedule 17.07.2017
comment
Я пытался сделать то, что у вас есть в этой сути, но ... как вы получили .so, который вы выровняли, чтобы установить его в любом месте, где Python / ld будет его искать?   -  person wvxvw    schedule 24.01.2018


Ответы (3)


Учитывая, что вы следовали инструкциям по создавать расширения Python на C, вам следует просто подключите модули расширения, как в этой документации.< br> Итак, 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'])],
)

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

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

person ElmoVanKielmo    schedule 05.06.2014
comment
@ElmoVanKielvo, ты знаешь, как это сделать в distutils2? - person Mansueli; 05.06.2014
comment
Похоже... pythonhosted.org/Distutils2/distutils/ ... точно так же :) - person ElmoVanKielmo; 05.06.2014
comment
Это не расширение Python. Это чистая библиотека C (которая сама по себе не содержит кода для взаимодействия со средой выполнения Python), но Python обращается к ней через ctypes. Потенциально можно обернуть разделяемую библиотеку C в модуль расширения Python, но я бы предпочел сохранить текущий подход ctypes. - person obeattie; 05.06.2014

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

person Sam Hartman    schedule 05.06.2014

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

У меня есть библиотека ANSI C в каталоге src моего дистрибутива. В каталоге src находится Makefile, который создает файл с именем liblsd.so в моем каталоге пакетов (lsd). Я вызываю это в setup.py, а затем говорю программе установки включить файл библиотеки, используя аргумент 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',
      ],
 )
person Geoffrey Hing    schedule 12.06.2014
comment
Вы должны по крайней мере подкласс distutils.command.build и переопределить метод run, иначе вызов make будет происходить для каждого типа вызова setup.py, где вы можете не захотеть перекомпилировать библиотеку (например, «проверить» или «загрузить») - person Tom Close; 22.10.2016