我们简单介绍一下如何使用Cython在不同路径中编译生成多个*.so扩展模块。比如现在我们在做一个可以被import的模块,其中有些代码是可以用Cython提速的。为了维护方便,一般会考虑用一个setup.py文件在不同的路径下,生成多个*.so扩展模块。
比如我们有如下一个组织好的模块:
main/
| - run.py
| - __init__.py
| - cls/
| |- __init__.py
| |- water.pyx
| |- land.py
| - funcs/
|- __init__.py
|- func1.pyx
|- func2.py
我们这里想通过Cython编译出一个water.so和一个func1.so。通过一个setup.py如何实现呢?
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
extensions = [
Extension(
"main.funcs.func1",["main/funcs/func1.pyx"]
),
Extension(
"main.cls.water",["main/cls/water.pyx"]
)
]
setup(
name = "test",
ext_modules=cythonize(extensions),
)
在上边这个setup.py,大概可以分为3部分:
第一部分:导入(import)相关的模块。
第二部分:定义extensions列表。通过distutlis.extension中的Extension方法可以分别指定不同路径下的*.pyx。Extension大概的使用方式如下:
Extension(
"mod_name.mod1.pyx_file", ["mod_name/mod1/pyx_file.pyx"],
include_dirs = ["c_library/include/"],
libraries = ["c_lib_name"],
library_dirs = ["c_library/lib"]
)
这里需要解释一下Extension中的各项内容。第一个引号中,是给出要编译出的扩展库名称,按照import的格式和顺序写到你要编译*.pyx文件的位置。第二个列表中的内容,是相应的路径,是从这个模块的主目录开始算起的。include_dirs =是该扩展模块所用c的library的头文件的路径,类似于makefile里的-I c_library/include。libraries =是c语言库文件的名称,如果这里使用的库为libc_lib_name.so,这里就要写libraries=["c_lib_name"],相应与makefile里就是-lc_lib_name。library_dirs =则是指定库文件所在位置,类似makefile中的-L c_library/lib。
第三部分:将上边指定好的*pyx分别进行编译。
这里要注意,将setup.py要放在正确的地方。在这个例子中,需要将setup.py和main/放在同一级目录。
这里通过一个非计算机专业的使用者的角度,简单记录的如何使用一个setup.py编译多个扩展库的多个方法之一。