我有个问题。我想分发我的由cython驱动的包,但我认为在setup.py中构建它们并不容易。我希望setup.py:
目前,在我的“痒包”中,我使用了以下非常复杂的代码:
import os
from glob import glob
from distutils.command.build_ext import build_ext as _build_ext
from distutils.command.sdist import sdist as _sdist
from distutils.core import setup
from distutils.core import Extension
def generate_extensions():
return [
# Compile cython-generated .c files into importable .so libraries.
Extension(os.path.splitext(name)[0], [name])
for name in C_FILES
]
# In distribution version, there are no pyx files, when you clone package from git, there will be no c files.
CYTHON_FILES = glob('itchy/*.pyx')
C_FILES = glob('itchy/*.c')
extensions = generate_extensions()
class build_ext(_build_ext):
def run(self):
# Compile cython files (.pyx, some of the .py) into .c files if Cython is available.
try:
from Cython.Build import cythonize
if CYTHON_FILES:
cythonize(CYTHON_FILES)
# Update C_FILES in case they were originally missing.
global C_FILES, extensions
C_FILES = glob('itchy/*.c')
extensions = generate_extensions()
else:
print('No .pyx files found, building extensions skipped. Pre-built versions will be used.')
except ImportError:
print('Cython is not installed, building extensions skipped. Pre-built versions will be used.')
assert C_FILES, 'C files have to be present in distribution or Cython has to be installed'
_build_ext.run(self)
class sdist(_sdist):
def run(self):
# Make sure the compiled Cython files in the distribution are up-to-date
self.run_command("build_ext")
_sdist.run(self)
setup(
(...)
ext_modules = extensions,
cmdclass = {
'build_ext': build_ext,
'sdist': sdist,
},
)
发布于 2017-10-17 09:53:34
通常通过尝试导入cython并调整扩展到
例如:
try:
from Cython.Distutils.extension import Extension
from Cython.Distutils import build_ext
except ImportError:
from setuptools import Extension
USING_CYTHON = False
else:
USING_CYTHON = True
ext = 'pyx' if USING_CYTHON else 'c'
sources = glob('my_module/*.%s' % (ext,))
extensions = [
Extension(source.split('.')[0].replace(os.path.sep, '.'),
sources=[source],
)
for source in sources]
cmdclass = {'build_ext': build_ext} if USING_CYTHON else {}
setup(<..>, ext_modules=extensions, cmdclass=cmdclass)
source.split
的内容是必需的,因为source.split
扩展名需要以my_module.ext
的形式出现,而glob则需要路径名,比如my_module/ext
。
请参阅此存储库用于一个真实世界的例子。
但是,您应该将.c
文件包括在git中以及可发行版中,否则,当需要构建发行版时,.c
文件将被重新构建,并且可能与计算机上构建的文件相同,也可能不是。
例如,它们可以由其他版本的cython构建,或者在不同的平台上生成不同的代码。
Cython是一个静态编译器--建议将它生成的文件提交到存储库。
强烈建议您分发生成的.c文件以及您的Cython源代码,这样用户就可以安装您的模块而不需要使用Cython。
https://stackoverflow.com/questions/46784964
复制相似问题