将C源文件与Python软件包一起打包

时间:2020-06-21 04:58:02

标签: python python-packaging python-extensions

我有一个正在编写的C库,我的目标是能够通过PyPI上的python包打包和分发该C库。这个概念是Python代码,扩展模块和C库的组合。我希望用户在安装软件包后能够使用distutils.ccompiler通过特定的Python函数在运行时安装和构建C库。但是,我遇到一个问题,即使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/srcpackage/include下的文件。

当用户从pip安装我的软件包时,我希望将这些C源代码和头文件嵌入到已安装的python软件包中。我怎样才能使它正常工作?

需要明确的是,我想使用build命令的结果来创建与源package相同的布局。

1 个答案:

答案 0 :(得分:-1)

这可以通过distutils.core.setup函数的data_files参数来完成。此关键字参数包含一个元组列表,其中每个元组的第一个参数是所需的安装位置的部分路径,第二个参数是所需在第一个元素的目录名称下安装的文件的路径的最后一个。尽管名称为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.prefixsite.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选项。