Пакет C исходных файлов вместе с пакетом Python - PullRequest
0 голосов
/ 21 июня 2020

У меня есть библиотека C, которую я пишу, и моя цель - иметь возможность упаковывать и распространять эту C библиотеку через пакет python на PyPI. Концепция состоит в том, что это комбинация кода Python, модуля расширения и библиотеки C. Я хочу, чтобы пользователь мог установить и собрать библиотеку C во время выполнения с помощью определенных функций c Python, используя distutils.ccompiler, после установки пакета. Однако я столкнулся с проблемой, когда, хотя исходные файлы C перечислены в MANIFEST.in, они не отображаются, когда я запускаю команду python setup.py build.

Вот макет моего каталога

home -
     setup.py
     MANIFEST.in
     package -
             ctools  -
                     __init__.py
             src     -
                     some_funcs.c
             include -
                     some_funcs.h
     pyext -
            pymain.c

Мой файл MANIFEST.in выглядит так

recursive-include package *.c *.h
include LICENSE.txt
include README.md

мои настройки distutils выглядят как

macro_defs = []

if os.name == 'nt':
  macro_defs.append(('_CRT_SECURE_NO_WARNINGS', '1'))

# This goes under the main package
# Will be linked with the C library later on 
core_module = distutils.core.Extension('package.core',
                    define_macros = macro_defs,
                    include_dirs = ['include'],
                    sources = ['pyext/pymain.c'])

distutils.core.setup(name='package',
      version='0.0.1',
      description='A library for searching and analyzing  data',
      author='Me',
      author_email='me@home.come',
      url='https://github.com/some/repo',
      download_url='https://github.com/some/repo/archive/master.zip',
      license = 'MIT',
      keywords = keyword_list,
      classifiers = classifers_list,
      long_description = open('README.md').read(),
      packages=['package', 'package.ctools'],
      ext_modules=[core_module],
     )

python setup.py sdist работает нормально, как и предполагалось, но когда я запускаю команду build, она не копирует файлы под package/src или package/include.

Когда пользователь устанавливает мой пакет из pip, мне нужны эти C источник и заголовок файлы для встраивания в их установленный python пакет. Как я могу заставить это работать?

Для ясности, я хотел бы, чтобы результат моей команды build создавал макет, идентичный моему исходному package.

1 Ответ

0 голосов
/ 28 июня 2020

Это можно сделать с помощью аргумента data_files функции distutils.core.setup. Этот аргумент ключевого слова принимает список кортежей, где первый аргумент каждого кортежа - это желаемый частичный путь к установленному местоположению, а второй аргумент - это последний из путей к файлам, которые необходимо установить под именем каталога первого элемента. Несмотря на название data_files, его можно использовать для установки любых файлов, которые не участвуют в процессе сборки распространяемого пакета python.

Например, использование data_files может выглядеть как

from distutils.core import setup

setup(
   ...,
   data_files=[("csrc", ["src/main.c", 
                         "src/helper.c"]),
               ("cinclude", ["include/helper.h"])]
)

каталоги и файлы, указанные в data_files, будут установлены в sys.prefix или в site.USER_BASE. Например, в случае windows, они могут выглядеть следующим образом:

>>> import sys
>>> sys.prefix
'C:\\Users\\foobar\\AppData\\Local\\Programs\\Python\\Python37'
>>> import site
>>> site.USER_BASE
'C:\\Users\\foobar\\AppData\\Roaming\\Python'

Какой из двух data_files будет установлен, зависит от того, указан ли параметр --user при использовании pip.

...