准备基于C的Cython包在pypi上发布

时间:2018-03-24 23:40:59

标签: python cython pypi

我要创建C库,我想使用Cython创建Python包装器。

现在我已经编译和捆绑了mylib.a文件(C文件),我想在Cython中从我的库中包装方法。

我成功创建了.pyx.pxd个文件,我可以使用python setup.py build_ext命令构建它。当我尝试在pypi上发布它时出现我的问题。如果我运行我的setup.py,创建轮并发布它我可以从pypi下载 - 但我无法运行import mylib

我为此阅读了很多在线教程。很少有人表明他们的C代码是在用户端编译的。我的代码库将由许多文件构成,我更愿意将已构建的C代码作为.a文件提供。

我的文件结构(仅限重要文件):

/ lib
    - mylib.a
    - *.h files (for mylib.a)
- setup.py
/ mylib
    - mylib.pyx
    - cmylib.pxd
    - __init__.py

我的__init__.py文件(导入从pip下载的软件包后,它会抛出错误):

from . import mylib

我的setup.py(仅在我看来是重要的参数):

setup(name='mylib'
      packages=['mylib'],
      ext_modules = [Extension(
          name="mylib", 
          sources=["mylib/mylib.bycython.c"], 
          include_dirs = [numpy.get_include(), "lib/"],
          extra_objects=["lib/mylib.a"])],
        "build_ext": build_ext
      }
)

(我使用来自mylib.bycode.c的cython在python setup.py build_ext之前构建mylib.pyx。根据this文章,它会更快地安装包,并且不需要用户拥有相同的cython版本。)

值得一提的是 - 在构建我的软件包之后,我获得了mylib的.so文件。如果我将其复制到/mylib目录,那么从父目录我可以import mylib并使用mylib.mylib.say_hello()访问我的方法。但是它不适用于从pip安装的软件包(在其他PC上),我也不想使用mylib.mylib

如果我应该提供更多信息 - 请告诉我。

修改

我的项目(我早先模糊了名字,所以这里是真正的项目)在GitHub上:https://github.com/franiis/statr-python

我希望从say_hello()成功运行statr.pyx方法(其他方法可能不起作用)。

我知道代码存在一些问题,但我想首先使用工作核心来修复和更新所有内容。构建项目使用build_script.shupload_script.sh创建轮子并发布它。

1 个答案:

答案 0 :(得分:0)

setup.py中有几个问题。

  • setup.py未编译链接到库。这意味着必须手动编译。
  • 链接到库是预编译的静态链接存档。这是不可移植,除了用于构建它的GCC / glibc的确切版本之外,不能分发给任何其他内容。
  • setup.py不构建cython扩展代码。对.pyx / .pxd的更改不会反映在包中。

尝试类似:

from setuptools import setup, find_packages, Extension
from Cython.Build import cythonize, build_ext

extensions = [Extension(
          name="statr._ext", 
          sources=["statr/_ext.pyx", "lib/mylib.c"],
          depends="lib/mylib.h",
          include_dirs=[numpy.get_include(), "lib/"]
]

setup(name='statr'
      packages=find_packages(),
      ext_modules=cythonize(extensions),
      build_ext: build_ext
      }
)

使用上述内容,扩展名将为statr._ext。 pyx的名称应为_ext.pyx

mylib.c将由setup.py构建并链接到扩展程序。 mylib.c所需的任何其他编译器指令都应添加到扩展名中。

包名称为statr。您应该从_ext中的顶级statrd模块导入您希望提供的__init__.py内的任何内容,例如

from ._ext import my_cython_function