static PyMethodDef MymathMethods[] = { {"sum", sum, METH_VARARGS, "add up two numbers and return their sum"}, {NULL} };
staticstructPyModuleDefmymath_module = { PyModuleDef_HEAD_INIT, "mymath", PyDoc_STR("A hello world example to demonstrate writing a python module in c language"), -1, MymathMethods };
PyMODINIT_FUNC PyInit_mymath(void) { PyObject *m = PyModule_Create(&mymath_module); return m; }
最关键的部分在 setup.py,安装时所有的依赖和行为都在这里定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
from setuptools import setup from setuptools import Extension
setup(name="demo", # 我们的 package 的名字 version="1.0", # 版本 description="This is a demo package", packages=["demo"], # 打包时需要带上的本地 python 包 ext_modules=[mymath] # 打包时需要编译的 c 模块 )
最基本的框架就如上所示,比较简单。 下面我们来试试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
$ python setup.py install $ python Python 3.6.9 (default, Feb 26 2020, 21:43:10) [GCC 7.4.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import mymath >>> help(mymath) >>> mymath.__doc__ 'A hello world example to demonstrate writing a python module in c language' >>> mymath.sum(99, 1) 100 >>>
二、setup.py 如何使用 CMake 来编译复杂的项目
上面使用 setup.py 编译了一个简单的 C 模块。不过它的弊端也很明显,那就是需要在 setup.py 里面组织 C 项目的结构,包括指定 sources, include_dirs, libraries 和其它编译选项。当项目变得复杂的时候,setup.py 也就变得异常难以管理。 而实际上,C 和 C++ 本身就有强大的 CMake 这个工具来进行项目管理了。在 setup.py 里面能不能直接用 CMake 呢? 我都在写这篇文章了,答案当然是有。不过有一些细节需要注意到。