【问题标题】:Using setuptools to create a cython package calling an external C library使用 setuptools 创建调用外部 C 库的 cython 包
【发布时间】: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 获得相同的结果?

【问题讨论】:

    标签: python cython setuptools distutils setup.py


    【解决方案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 documentationdistutils.core.Extension 将作为第一个参数:"扩展的全名,包括任何包——即不是文件名或路径名,而是 Python 点名" 因此,应该使用"myPackage.myModule",而不是"myPackage/myModule"
    • @SylM 我已经有一段时间没有使用 python 了……所以我需要努力仔细检查将斜杠“/”替换为点“。”正如你所建议的那样确实有效。但是,如果您测试解决方案并告诉我没问题,那么我将相应地编辑我的答案。通过“测试解决方案”,我的意思是从头开始一个新项目并确保你可以让它工作。你愿意这样做吗? ;)
    • @GLorieul 我刚刚使用了上面的模板,使用了点名语法,并且编译成功了。
    • @Gilly 谢谢!我相应地更新了我的答案:您能否再次检查我所做的编辑是否正确?
    猜你喜欢
    • 2018-05-11
    • 2022-08-15
    • 1970-01-01
    • 1970-01-01
    • 2018-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多