我喜欢给自己开发的C++组件写个python接口,这样我可以利用python来直接对写的组件做一些简单测试。
C++程序的python接口有很多实现方式 ctypes、Boost.Python、SWIG、cython等,都挺不错的,我比较熟悉cython,因为已经入坑了,暂时还是用熟悉的吧,等把cython用透了,在实践的基础上发现其局限性,再考虑使用其他的方式吧。
废话不多说,咱们直接聊聊cython 和cmake的关系
cmake可用来管理C++项目代码,很多优秀的项目使用的是cmake来管理,如opencv,最近因为公司项目代码扩大,急需一种能够对整个项目实现高效管理的工具,cmake正好适用。
cython用于实现C++代码的python接口,C++代码都用cmake管理了,所以也希望用cmake管理cython代码,但是cython库并没有原生支持cmake管理(应该说cmake并没有原生支持cython代码)
好在我在github上找到了example,https://github.com/thewtex/cython-cmake-example,再次特别感谢该项目创立者,为我cmake管理cython代码提供了很好的思路,关键就在于cython的相关cmake脚本,项目提供了简单的cythoncmake脚本,最新版本的cython的cmake脚本跟着scikit-build项目发布https://github.com/scikit-build/scikit-build,我们可以直接从该项目中获取脚本
拷贝脚本到项目中
find_package(PythonInterp 3)
find_package(PythonExtensions REQUIRED)
find_package(Cython REQUIRED)
message(STATUS "PYTHON_EXECUTABLE: ${PYTHON_EXECUTABLE}")
message(STATUS "PYTHON_VERSION_STRING: ${PYTHON_VERSION_STRING}")
message(STATUS "PYTHON_INCLUDE_DIR: ${PYTHON_INCLUDE_DIR}")
message(STATUS "PYTHON_LIBRARY: ${PYTHON_LIBRARY}")
add_subdirectory(python)
在项目CMakeLists.txt加上以上代码,就可以管理cython代码了
python目录下的CMakeLists.txt文件如下
add_cython_target(test_py CXX)
add_library(test_py MODULE ${test_py})
python_extension_module(test_py)
target_link_libraries(test_py test)
add_dependencies(test_py test)
install(TARGETS test_py LIBRARY DESTINATION lib)
其中需要注意的是add_cython_target(test_py CXX)是将pyx文件转成CXX文件用于编译,因为cython本质上还是将cython代码转成python C API代码然后再编译成so
而add_library(test_py MODULE ${test_py}) 第一个test_py为要编译的so的名字,而第二个test_py则为上一条命令获得的CXX文件,这边要注意一点