通常通过尝试导入 cython 并调整扩展名来完成
- 如果 cython 存在,则使用 cython 构建 pyx 文件
- 如果 cython 不存在,则构建 C 文件
例如:
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)
The source.split
需要一些东西,因为 cythonized 扩展名称需要采用以下形式my_module.ext
而 glob 需要路径名,例如my_module/ext
.
查看这个存储库 https://github.com/ParallelSSH/ssh2-python/blob/master/setup.py#L14-L25举一个现实世界的例子。
但是,您应该包括.c
git 存储库中的文件以及可分发的文件,否则当需要构建发行版时.c
文件将被重新构建,并且可能与您计算机上构建的文件相同,也可能不同。
例如,它们可能由另一个版本的 cython 构建,或者在不同的平台上生成不同的代码。
Cython 是一个静态编译器 - 建议将其生成的文件提交到存储库。
强烈建议您分发生成的 .c 文件以及 Cython 源,以便用户无需使用 Cython 即可安装您的模块。
请参阅有关分发模块的 Cython 文档 https://cython.readthedocs.io/en/latest/src/userguide/source_files_and_compilation.html#distributing-cython-modules.