使用Python setuptools将Cython编译的pyd文件放在原始文件夹中?

时间:2016-02-19 04:53:22

标签: python cython setuptools pyd

我正在尝试为包含Cython模块的Python 3.4应用程序构建setup.py包。我的计划是有一个setup.py文件需要Cython并编译.pyx文件的想法通常我会在Win32(x86& x64)和Mac上运行它,然后生成平台轮并将它们上传到PyPI,所以普通用户不需要Cython或编译任何东西。

目前我可以获取setup.py脚本来构建.pyd文件,但它并没有将构建的.pyd文件放在与原始.pyx文件相同的位置,这是我需要它的地方

我尝试手动复制.pyd文件,但是当我通过bdist_wheel生成滚轮时,我得到一个纯Python轮,我认为这是错误的,因为我的内置.pyx文件有不同版本,具体取决于平台。我还尝试了对Distribution类进行子类化并强制is_pure()返回False(如here in the Building Wheels section所述),但这并不起作用。 (仍然生成纯Python轮。)

我假设如果我可以获得setup.py脚本将编译后的文件放在正确的位置,那么轮子将不是纯Python,一切都会好的。

所以我的问题是:

  1. setup.py中是否有某种设置告诉它将已编译的Cython文件放入与源文件相同的位置?
  2. 或者有没有办法将编译后的文件复制到我需要它们的位置,但仍然可以将轮子构建为非纯粹的?
  3. 或者我是以错误的方式解决这个问题。我应该更改我的Python代码以从其他地方提取已编译的包吗? (这对我来说似乎不对。)
  4. [编辑]或者我应该将已编译的二进制文件.pyd / .so / .dylib放入包中,在运行时根据体系结构添加逻辑以获得正确的.pyd,然后使用纯Python轮? (这对我来说也不合适。)
  5. 有关我的设置的更多信息: 我在setup.py脚本中使用setuptools(而不是distutils)。我的setup.py的片段就在这里(删除了大量内容以保留相关内容):

    from setuptools import setup, Extension
    from Cython.Build import cythonize
    from Cython.Distutils import build_ext
    
    ...
    
    extensions = [
        Extension(name='audio_interface',
                  sources=['mpf/mc/core/audio/audio_interface.pyx'],
                  include_dirs=include_dirs,
                  library_dirs=library_dirs,
                  libraries=libraries,
                  extra_objects=extra_objects,
                  extra_compile_args=extra_compile_args,
                  extra_link_args=extra_link_args),
    
    ...
    
    setup(
          ...
          ext_modules=cythonize(extensions),
          cmdclass= {'build_ext': build_ext},
          ...
    

    谢谢! 布赖恩

2 个答案:

答案 0 :(得分:3)

我有一个类似的问题,我找到了一个可以为你工作的解决方案。

distutils.core.Extension的官方Python文档中,name参数是:

  

扩展名的全名,包括任何包 - 即。不是   文件名或路径名,但Python点名称

因此,如果您将setup.py修改为:

...

extensions = [
    Extension(name='mpf.mc.core.audioaudio_interface',  # using dots!
              sources=['mpf/mc/core/audio/audio_interface.pyx'],
              include_dirs=include_dirs,
              library_dirs=library_dirs,
              libraries=libraries,
              extra_objects=extra_objects,
              extra_compile_args=extra_compile_args,
              extra_link_args=extra_link_args),

...

您将在所需的位置获得已编译的二进制文件。

答案 1 :(得分:2)

我找到了一种解决方法,解决了将--plat-name添加到python setup.py bdist_wheel命令的直接问题。 (这是在0.27.0轮中添加的。不知道为什么它之前没有出现在我的所有搜索中。)

所以这通过我的清单上的第2项解决了我的问题。我将pyx编译为.pyd或.so,将其复制回正确的位置,然后使用--plat-name创建特定于平台的轮。

然而,我的问题仍然有点遗憾,因为如果我们添加更多的Cython模块,我们是否可以编译然后将它们全部复制回原始位置,或者有没有办法将它们编译并自动转到原始位置?我这样做的方式还包括两个不同的setup.py文件 - 一个用于编译,另一个用于安装包。

所以我在这里添加此内容是为了未来搜索者的利益,但我原来的问题仍然存在。