使用 setuptools 创建调用外部 C 库的 cython 包
Posted
技术标签:
【中文标题】使用 setuptools 创建调用外部 C 库的 cython 包【英文标题】:Using setuptools to create a cython package calling an external C library 【发布时间】:2015-12-08 07:34:24 【问题描述】:我正在尝试编译、安装和运行一个我们称之为myPackage
的包。它包含一个*.pyx
文件,该文件从库fftw
中调用函数fftw_set_timelimit()
。目前,当我运行导入包的脚本clientScript.py
时,我收到以下错误消息:
Traceback (most recent call last):
File "clientScript.py", line 5, in <module>
import myPackage.myModule
ImportError: /usr/local/lib/python2.7/dist-packages/myPackage/myModule.so: undefined symbol: fftw_set_timelimit
据我了解(我对 python 和 cython 很陌生),与 C 库的链接尚未在我的包中执行。事实上,我的setup.py
文件看起来像这样:
from setuptools import setup,find_packages
from Cython.Build import cythonize
import os
setup(
name = "myPackage",
version = "0.0.1",
url = "none",
author = "me",
author_email = "me@me.me",
packages=find_packages(),
ext_modules = cythonize("pyClo/pyClo.pyx"),
)
如您所见,我的setup.py
文件使用setuptools
。我决定这样做,因为它是由Python Packaging User Guide 推荐的。但是,Cython documentation 中的说明使用 distutils
代替。链接库是通过调用distutils.Extension('file',['file.pyx'],libraries='fftw')
完成的。如何使用setuptools
获得相同的结果?
【问题讨论】:
【参考方案1】:原来setuptools
有一个模块setuptools.extension.Extension
,它的使用方式与distutils.extension.Extension
模块相同。
最后,setup.py
文件看起来像:
from setuptools import setup, find_packages
from setuptools.extension import Extension
from Cython.Build import cythonize
extensions = [
Extension(
"myPackage.myModule",
["myPackage/myModule.pyx"],
include_dirs=['/some/path/to/include/'], # not needed for fftw unless it is installed in an unusual place
libraries=['fftw3', 'fftw3f', 'fftw3l', 'fftw3_threads', 'fftw3f_threads', 'fftw3l_threads'],
library_dirs=['/some/path/to/include/'], # not needed for fftw unless it is installed in an unusual place
),
]
setup(
name = "myPackage",
packages = find_packages(),
ext_modules = cythonize(extensions)
)
这是我的安装目录的概述:
.
├── MANIFEST.in
├── myPackage
│ └── myModule.pyx
├── README.rst
└── setup.py
其中myModule.pyx
是调用fftw_set_timelimit()
的文件。
MANIFEST.in
包含:
include myPackage/*.*
而README.rst
只是一个纯文本文件。
【讨论】:
根据distutils documentation,distutils.core.Extension
将作为第一个参数:"扩展的全名,包括任何包——即不是文件名或路径名,而是 Python 点名" 因此,应该使用"myPackage.myModule"
,而不是"myPackage/myModule"
。
@SylM 我已经有一段时间没有使用 python 了……所以我需要努力仔细检查将斜杠“/”替换为点“。”正如你所建议的那样确实有效。但是,如果您测试解决方案并告诉我没问题,那么我将相应地编辑我的答案。通过“测试解决方案”,我的意思是从头开始一个新项目并确保你可以让它工作。你愿意这样做吗? ;)
@GLorieul 我刚刚使用了上面的模板,使用了点名语法,并且编译成功了。
@Gilly 谢谢!我相应地更新了我的答案:您能否再次检查我所做的编辑是否正确?以上是关于使用 setuptools 创建调用外部 C 库的 cython 包的主要内容,如果未能解决你的问题,请参考以下文章