本文介绍了准备基于C的Cython软件包以在pypi上发布的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将创建C库,并希望使用Cython创建Python包装器。

I'm going to create C library and I would like to create Python wrapper using Cython.

现在我已经编译并捆绑了 mylib.a 文件(C文件),并且我想从我的图书馆位于Cython。

Right now I have mylib.a file compiled and bundled (C files) and I want to wrap methods from my library in Cython.

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

I successfully created .pyx and .pxd files and I can build it using python setup.py build_ext command. My problem appears when I try publish it on pypi. If I run my setup.py, create wheel and publish it I can download it from pypi - but I can't run import mylib.

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

I read a lot online tutorials for this. Few of them shown that theirs C code compiled on user side. My codebase will be constructed from many files and I would prefer to supply already build C code as .a file.

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

My file structure (only important files):

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

我的 __ init __。py 文件(导入从pip会在此处引发错误):

My __init__.py file (after importing package downloaded from pip it throws errors here):

from . import mylib

我的 setup.py (仅重要参数-我认为):

My setup.py (only important parameters - in my opinion):

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版本。 )

(I build mylib.bycode.c before python setup.py build_ext using cython from mylib.pyx. According to this article it would make installing package faster and would not require user to have same cython version.)

也许值得一提-构建软件包后,我得到了mylib的 .so 文件。如果我将其复制到 / mylib 目录,则可以从父目录导入mylib 并使用<$ c访问我的方法$ c> mylib.mylib.say_hello()。但是,它对从pip(在其他PC上)安装的软件包不起作用,我也不想使用 mylib.mylib

It maybe worth mentioning - after building my package I get .so file for mylib. If I copy it to /mylib directory then from parent directory I can import mylib and access my methods using mylib.mylib.say_hello(). However it doesn't work on package installed from pip (on other PC) neither I don't want to use mylib.mylib.

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

If I should provide more info - let me know.

编辑:

我在GitHub上的项目(我之前混淆了名称,所以这里是实际项目):

My project (I obfuscated name earlier, so here goes real project) on GitHub: https://github.com/franiis/statr-python

我想成功运行 say_hello() statr.pyx 中的c>方法(其他方法可能无法使用)。

I want to successfully run say_hello() method from statr.pyx (other methods probably will not work).

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

I know code has some problems, but I want to first have working core to fix and update everything. To build project use build_script.sh. upload_script.sh creates wheel and publishes it.

推荐答案

有几个 setup.py 中的问题。


  • 链接库未编译通过 setup.py 。这意味着它必须手动编译。

  • 链接到库是一个预编译的静态链接存档。这是不可移植的,并且不能分发到用于构建它的GCC / glibc的确切版本以外。

  • cython扩展代码未构建通过 setup.py 。对.pyx / .pxd的更改不会反映在软件包中。

  • The linked to library is not being compiled by setup.py. This means it must be compiled manually.
  • The linked to library is a pre-compiled statically linked archive. This is not portable and cannot be distributed to anything other than the exact versions of GCC/glibc used to build it.
  • The cython extension code is not being built by setup.py. Changes to .pyx/.pxd will not be reflected in the package.

尝试类似的操作:

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

With the above, the name of the extension will be statr._ext. The name of the pyx should be _ext.pyx.

mylib.c 将被构建并通过<$ c $链接到扩展名c> setup.py 。 mylib.c 所需的任何其他编译器指令都应添加到扩展名。

mylib.c will be built and linked to the extension by setup.py. Any additional compiler directives required by mylib.c should be added to the extension.

包名称为 statr 。您应该从 _ext 导入想要从顶级 statrd 模块的<$ c $中可用的任何内容。 c> __ init __。py ,例如

The package name will be statr. You should import anything from _ext that you want to be available from the top level statrd module in its __init__.py, for example

from ._ext import my_cython_function

这篇关于准备基于C的Cython软件包以在pypi上发布的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 10:39