Упакуйте исходные файлы C вместе с пакетом Python

У меня есть библиотека C, которую я пишу, и моя цель — иметь возможность упаковывать и распространять эту библиотеку C через пакет python на PyPI. Идея состоит в том, что это комбинация кода Python, модуля расширения и библиотеки 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='[email protected]',
      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.


person Josh Weinstein    schedule 21.06.2020    source источник


Ответы (1)


Этого можно добиться с помощью аргумента 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. Например, в случае с окнами они могут выглядеть следующим образом.

>>> 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.

person Josh Weinstein    schedule 27.06.2020
comment
Используйте package_data, а не data_files. - person sinoroc; 28.06.2020