简体   繁体   English

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

[英]Using Python setuptools to put Cython-compiled pyd files in their original folders?

I'm trying to build the setup.py package for my Python 3.4 app which contains a Cython module. 我正在尝试为我的Python 3.4应用程序构建setup.py程序包,其中包含Cython模块。 My plan is to have a setup.py file which requires Cython and compiles the .pyx file with the idea that typically I would just run that on Win32 (x86 & x64) and Mac and then generate platform wheels and upload them to PyPI, so regular users wouldn't need Cython or to compile anything. 我的计划是准备一个需要Cython的setup.py文件,并编译.pyx文件,其想法是通常只在Win32(x86和x64)和Mac上运行该文件,然后生成平台轮并将其上传到PyPI,因此普通用户不需要Cython或编译任何东西。

Currently I can get the setup.py script to build the .pyd file, but it doesn't put the built .pyd file in the same location as the original .pyx file which is where I need it to be. 目前,我可以使用setup.py脚本来构建.pyd文件,但是它不会将构建的.pyd文件与原始.pyx文件放在我需要的位置相同的位置。

I tried manually copying the .pyd file, but then when I generate the wheel via bdist_wheel I get a pure Python wheel which I think is wrong since there are different version of my built .pyx file depending on the platform. 我尝试手动复制.pyd文件,但是当我通过bdist_wheel生成转盘时,我得到了一个纯Python的转盘,我认为这是错误的,因为根据平台的不同,我构建的.pyx文件的版本也不同。 I also tried subclassing the Distribution class and forcing is_pure() to return False (as described here in the Building Wheels section ), but that doesn't work. 我还尝试了对Distribution类进行子类化,并强制is_pure()返回False(如“建筑车轮”部分所述 ),但这是行不通的。 (Still generates a pure Python wheel.) (仍然会生成一个纯Python轮子。)

I assume that if I can get the setup.py script to put the compiled file in the right location, then the wheel will not be pure Python and everything will be fine. 我假设如果可以获取setup.py脚本以将编译后的文件放置在正确的位置,那么方向盘将不是纯Python,一切都会很好。

So my questions are: 所以我的问题是:

  1. Is there some kind of setting in setup.py to tell it to put the compiled Cython files into the same locations as the source files? setup.py中是否有某种设置可以告诉它将已编译的Cython文件放入与源文件相同的位置?
  2. Or is there a way to copy the compiled files to the location I need them but for the wheel to still be built as non-pure? 还是有一种方法可以将编译后的文件复制到我需要的位置,但是仍然可以将车轮构建为非纯文件?
  3. Or am I going about this in the wrong way. 还是我以错误的方式来解决这个问题。 Should I change my Python code to pull the compiled packages from somewhere else? 我是否应该更改我的Python代码以从其他地方提取已编译的软件包? (That doesn't seem right to me.) (这对我来说似乎不正确。)
  4. [EDIT] Or should I put the compiled binary .pyd / .so / .dylib into the package, add logic to get the right .pyd based on architecture at runtime, and then have a pure Python wheel? [编辑]还是应该将已编译的二进制.pyd / .so / .dylib放入包中,添加逻辑以在运行时基于体系结构获取正确的.pyd,然后使用纯Python轮子? (That also doesn't seem right to me.) (在我看来,这也不对。)

More information on my setup: I'm using setuptools (not distutils) in my setup.py script. 有关安装程序的更多信息:我在setup.py脚本中使用setuptools(而不是distutils)。 A snippet of my setup.py is here (with a lot of stuff removed to keep it to the stuff that's relevant): 我的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},
      ...

Thanks! 谢谢! Brian 布赖恩

I had a similar issue, and I have found a solution that could work also for you. 我遇到了类似的问题,并且找到了一种对您也可行的解决方案。

From the official Python documentation for distutils.core.Extension , the name argument is: distutils.core.Extension的官方Python文档中, name参数为:

the full name of the extension, including any packages — ie. 扩展名的全名,包括任何软件包,即。 not a filename or pathname, but Python dotted name 不是文件名或路径名,而是Python点分名称

So, if you modify your setup.py to: 因此,如果将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),

...

you will have the compiled binary in the location that you want. 您将在所需的位置具有已编译的二进制文件。

I found a workaround which solves the immediate problem which is to add --plat-name to the python setup.py bdist_wheel command. 我发现了一个解决方法,可以解决当前的问题,即在python setup.py bdist_wheel命令中添加--plat-name (This was added in wheel 0.27.0. No idea why it didn't come up in all my searches before.) (这是在转轮0.27.0中添加的。我不知道为什么以前没有在所有搜索中都使用它。)

So this solves my problem via Item #2 on my list. 因此,这可以通过列表上的项目2解决我的问题。 I compile the pyx to .pyd or .so, copy it back to the proper location, and then use --plat-name to create a platform-specific wheel. 我将pyx编译为.pyd或.so,将其复制回正确的位置,然后使用--plat-name创建平台特定的轮子。

However my question still somewhat remains because if we add more Cython modules, do we compile and then just copy them all back to their original locations manually, or is there a way for them to be compiled and go automatically to their original locations? 但是,我的问题仍然存在,因为如果我们添加更多的Cython模块,我们是否会进行编译,然后将其全部手动复制回其原始位置,或者是否有办法对其进行编译并自动转到其原始位置? Also the way I'm doing it involves two different setup.py files--one to compile and a second to install the package. 我的操作方式还涉及到两个不同的setup.py文件-一个用于编译,另一个用于安装软件包。

So I'm adding this here for the benefit of future searchers but my original questions still remain. 因此,我在这里添加此内容是为了将来的搜索者受益,但我最初的问题仍然存在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM