使用Cython和C ++的项目组织

时间:2013-05-28 13:01:13

标签: c++ python build cython

我想为我的C ++项目提供Python接口。从技术上讲,我决定使用Cython来包装C ++代码。随着时间的推移,整个项目将成为一个Python扩展模块,但首先,这是高度实验性的。渐渐地,C ++类需要暴露给Python。

我的问题是如何最好地组织文件和构建配置,以便Cython生成的和人工编写的C ++代码不会混合,并且Python扩展模块与其他目标完全分开构建。

我想象一个源文件的目录结构,以及Cython的一些构建目录。

Project/
    src/
        *.h
        *.cpp
    cython/
        Project.pyx
        setup.py

1 个答案:

答案 0 :(得分:5)

基本上我有3个文件夹:

  1. CPROJECT,C ++库:生成libcproject.so共享对象
  2. CYPROJECT,cythonized Python扩展:使用Cython生成cyproject.so
  3. DEPENDENCIES,依赖项:我复制两个项目的外部需求
  4. 在1中。我构建了C ++扩展(使用gcc - -shared-fPIC编译选项编译),它将暴露给python并且{{1}依赖于向Python公开功能。作为后期处理命令,生成的CYPROJECT将复制到.so(以及DEPENDENCIES/libcproject/个文件中)。这样,库当然也可以在纯C ++项目中独立使用。

    2。我使用了3个子文件夹:

    • include:主要包含C ++附加类(通常是从adapters提供的类派生的类)。这些通常是通过特定于Cython需求的功能增强的类(例如存储目标Python版本的libcproject.so C版本 - 继承自PyObject * - 给定类和引用计数管理,通过objectPy_XINCREF,...)。
    • Py_DECREF:存储所有Cython手写的pyext文件。
    • .pyx:包含setup脚本(用于设置依赖关系路径并调用setup.sh以生成最终python setup.py build_ext --inplace(将添加到cyproject.so }}和PYTHONPATH

    那么cyproject.pyx子文件夹中的内容是什么?

    以下是setup的示例代码:

    setup.sh

    这里有export PYTHONPATH=$PYTHONPATH:../../../DEPENDENCIES/Cython-0.18 export PATH=$PATH:../../../DEPENDENCIES/libcproject:../../../DEPENDENCIES/Cython-0.18/bin # Note the `../../../DEPENDENCIES/libcproject`... CC="gcc" \ CXX="g++" \ python setup.py build_ext --inplace 的示例(主要是为了演示如何编译附加setup.py):

    adapters

    最后,主import sys import os import shutil from distutils.core import setup from distutils.extension import Extension from Cython.Distutils import build_ext # Cleaning for root, dirs, files in os.walk(".", topdown=False): for name in files: if (name.startswith("cyproject") and not(name.endswith(".pyx"))): os.remove(os.path.join(root, name)) for name in dirs: if (name == "build"): shutil.rmtree(name) # Building setup( cmdclass = {'build_ext': build_ext}, ext_modules = [ Extension("cyproject", sources=["cyproject.pyx", \ "adapter/ALabSimulatorBase.cpp", \ "adapter/ALabSimulatorTime.cpp", \ "adapter/ALabNetBinding.cpp", \ "adapter/AValueArg.cpp", \ "adapter/ALabSiteSetsManager.cpp", \ "adapter/ALabSite.cpp", \ ], libraries=["cproject"], language="c++", extra_compile_args=["-I../inc", "-I../../../DEPENDENCIES/python2.7/inc", "-I../../../DEPENDENCIES/gsl-1.8/include"], extra_link_args=["-L../lib"] extra_compile_args=["-fopenmp", "-O3"], extra_link_args=[] ) ] ) 将cython部分的所有手写.pyx链接在一起[.pyx]:

    cyproject.pyx

    注意:Cython生成的所有文件都保留在此include "pyext/Utils.pyx" include "pyext/TCLAP.pyx" include "pyext/LabSimulatorBase.pyx" include "pyext/LabBinding.pyx" include "pyext/LabSimulatorTime.pyx" ... 文件夹中,与预期的手写内容(setupadapters完全分开)。

    3。使用分隔的pyext文件夹可以保持良好的分隔(如果我将移动DEPENDENCIES - 及其依赖项 - 在其他环境中)

    所有这些都是为了给你一个如何组织这类项目的概述(我希望是一个相关的概述)。