首页 > 解决方案 > Cython 用 setup.py build_clib 包装 c lib

问题描述

我决定重构我的 C api 包装器并深入libraries探讨setuptools.setup

我的项目结构如下:

|setup.py
|my_pkg
|--|ext_c_lib
|--|--|include
|--|--|--|c_file.h
|--|--|--|c_types.h
|--|--|src
|--|--|--|c_file.c
|--|cy_lib
|--|--|pxd_include
|--|--|--|__init__.py
|--|--|--|c_file.pxd   # functions redefined `with cdef exten from "c_file.h"`
|--|--|--|c_types.pxd  # types redefined `with cdef exten from "c_types.h"`
|--|--|__init__.py
|--|--|utils.pyx       # uses types from c_types.pxd
|--|--|cy_file.pyx     # uses funcs from c_file.c/c_file.pxd

实用程序.pyx:

from my_pkg.cylib.pxd_include.c_types cimport SOME_CUSTOM_TYPE
...

cy_file.pyx:

from my_pkg.cylib.pxd_include.c_file cimport c_func

cdef cy_func(arg):
    arg += 1
    return c_func(arg)

设置.py:

...
extensions = [Extension('my_pkg.cy_lib.utils', ['my_pkg/cy_lib/utils.pyx']),
              Extension('my_pkg.cy_lib.cy_file', ['my_pkg/cy_lib/cy_file.pyx',
                                                  'my_pkg/ext_c_lib/src/c_file.c']),]

setup(name='my_pkg', ext_modules=extensions, include_dirs=['my_pkg/ext_c_lib/include'])

由于ext_c_lib不依赖于我并且发布非常罕见,我想将它构建为外部库,python setup.py build_clib然后在 cython 文件中使用它,所以我可以摆脱 pxd 文件并编译c_file.c一次,即使我添加单独的 cython 文件使用函数从c_file.c. 那可能吗?

我期望类似:setup.py:

...
external = ('external', {'sources': ['my_pkg/ext_c_lib/src/c_file.c']})
extensions = [Extension('my_pkg.cy_lib.utils', ['my_pkg/cy_lib/utils.pyx']),
              Extension('my_pkg.cy_lib.cy_file', ['my_pkg/cy_lib/cy_file.pyx']),]

setup(name='my_pkg', libraries=external,
      ext_modules=extensions, include_dirs=['my_pkg/ext_c_lib/include'])

实用程序.pyx:

from external cimport SOME_CUSTOM_TYPE
...

cy_file.pyx:

from external cimport c_func

cdef cy_func(arg):
    arg += 1
    return c_func(arg)

当然,这段代码不会像我得到的那样编译external.pxd not found

标签: pythoncythonsetuptoolspackaging

解决方案


推荐阅读