项目组织与用Cython和C ++ [英] Project organization with Cython and C++

查看:140
本文介绍了项目组织与用Cython和C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想提供我的C ++与Python接口项目。从技术上讲,我已经决定用用Cython用于包装的C ++ code。随着时间的推移,整个项目是为了成为一个Python的扩展模块,但在第一,这是高度实验性的。渐渐地,C ++类需要接触到Python。

我的问题是如何最好地组织文件和构建配置,以便用Cython产生和人类编写的C ++ code不要混合Python的扩展模块是干净建单独从其他目标。

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

 项目/
    SRC /
        *。H
        *的.cpp
    用Cython /
        Project.pyx
        setup.py


解决方案

基本上我有3个文件夹:


  1. 的CProject ,C ++库:生产 libcproject.so 共享对象

  2. CYPROJECT ,该cythonized Python扩展:生产 cyproject.so 使用用Cython

  3. 相关内容,依赖:在那里我复制外部需求​​这两个项目

在1 我打造C ++的扩展名(用gcc编译 - -shared -fPIC 编译选项),将被暴露在蟒蛇的 CYPROJECT 靠揭露功能到Python。作为后处理命令,产生的的.so 复制到相关内容/ libcproject / (还有包含文件)。这样,图书馆,当然,可用独立在纯C ++项目也是如此。

2 我使用3个子文件夹:


  • 适配器:主要包括C ++其他类(通常从 libcproject.so 提供的那些派生类) 。这些通常是与特定于用Cython要求的功能(如存储的有针对性的Python版本的的PyObject * C版增强类 - 从继承的对象 - 一个给定的类和引用计数管理,通过 Py_XINCREF Py_DECREF 。 ..)。

  • pyext :用于存储所有的用Cython写得一手 .pyx 文件

  • 设置:包含 setup.sh 脚本(用于设置依赖路径和调用蟒蛇setup.py build_ext --inplace 生成最终的 cyproject.so (将被添加到 PYTHONPATH )和 cyproject.pyx

那么,在设置子文件夹?

下面是一个简单的code为 setup.sh

 出口PYTHONPATH = $ PYTHONPATH:../../../相关内容/用Cython-0.18
出口PATH = $ PATH:../../../ DEPENDENCIES / libcproject:../../../相关内容/用Cython-0.18 / bin中#注意`../../../相关内容/ libcproject` ...CC =海湾合作委员会\\
CXX =G + +\\
    蟒蛇setup.py build_ext --inplace

和这里的例子 setup.py (主要是为了演示如何额外的适配器编译):

 进口SYS
进口OS
进口shutil从distutils.core进口设置
从distutils.extension进口延期
从Cython.Distutils进口build_ext#清洁
在os.walk根,显示目录,文件(,自上而下=假。):
    在文件名称:
        如果(name.startswith(cyproject),而不是(name.endswith(PYX。))):
            os.remove(os.path.join(根,名))
    在显示目录名称:
        如果(名称==构建):
            shutil.rmtree(名)# 建造
建立(
    cmdclass = {'build_ext':build_ext},
    ext_modules = [
    扩展(cyproject
              来源= [cyproject.pyx,\\
                       适配器/ ALabSimulatorBase.cpp,\\
                       适配器/ ALabSimulatorTime.cpp,\\
                       适配器/ ALabNetBinding.cpp,\\
                       适配器/ AValueArg.cpp,\\
                       适配器/ ALabSiteSetsManager.cpp,\\
                       适配器/ ALabSite.cpp,\\
                       ]
              库= [的CProject],
              语言=C ++,
              extra_compile_args = - 我../公司,-I ../../../相关内容/ python2.7 /公司,-I ../../../相关内容/ GSL-1.8 /包括],
              extra_link_args =L - ../ lib目录]
              extra_compile_args = [ - fopenmp,-O3],
              extra_link_args = []
              )
    ]

最后,主 .pyx ,链接所有的手写 .pyx 的用Cython部分第一起[ cyproject.pyx ]:

 包括pyext / Utils.pyx
包括pyext / TCLAP.pyx
包括pyext / LabSimulatorBase.pyx
包括pyext / LabBinding.pyx
包括pyext / LabSimulatorTime.pyx
...

请注意:所有通过用Cython生成的文件仍保留在该设置文件夹,从手写的东西(以及分离适配器 pyext ),符合市场预期。

3 是一个分离的相关内容文件夹允许保留的东西很好地分离(的情况下,我会移动 CYPROJECT - 和它的依赖 - 在其他一些环境下)

这一切给你一个概述(一中肯的,我希望)在一个可以如何组织之类的项目。

I want to provide my C++ project with a Python interface. Technically, I have decided to use Cython for wrapping the C++ code. Over time, the entire project is meant to become a Python extension module, but at first, this is highly experimental. Gradually, C++ classes need to be exposed to Python.

My question is how to best organize files and build configurations so that Cython-generated and human-written C++ code do not get mixed and the Python extension module is cleanly built seperate from the other targets.

I imagine a directory structure like this for the source files, and some build directory for Cython.

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

解决方案

Basically I have 3 folders :

  1. CPROJECT, The C++ library : producing a libcproject.so shared object
  2. CYPROJECT, The cythonized Python extension : producing the cyproject.so using Cython
  3. DEPENDENCIES, The dependencies : where I copy external requirements for both projects

In 1. I build the C++ extension (compiled with gcc - -shared, -fPIC compile options) that will be exposed to python and that the CYPROJECT relies on to expose features to Python. As a post processing command, the resulting .so is copied into DEPENDENCIES/libcproject/ (as well as the include files). This way the library is, of course, usable independently in a pure C++ project as well.

In 2. I make use of 3 sub-folders :

  • adapters : which mainly contains C++ additional classes (often classes derived from the ones provided by libcproject.so). Those are usually classes that are enhanced with functionalities specific to Cython requirements (such as storing the PyObject * C version of a targeted Python version - inherited from object - of a given class and the reference counting management, via Py_XINCREF and Py_DECREF, ...).
  • pyext : where are stored all the Cython hand written .pyx files.
  • setup : containing the setup.sh script (for setting up the dependencies paths and calling the python setup.py build_ext --inplace for generating the final cyproject.so (to be added to the PYTHONPATH) and cyproject.pyx.

So what's in the setup sub-folder ?

Here is a sample code for 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

And here an example of setup.py (mainly to demonstrate how the additional adapters are compiled):

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=[]
              )
    ]
)                   

And finally, the main .pyx, that links all the hand written .pyxs of the cython part together [cyproject.pyx] :

include "pyext/Utils.pyx" 
include "pyext/TCLAP.pyx" 
include "pyext/LabSimulatorBase.pyx"
include "pyext/LabBinding.pyx"
include "pyext/LabSimulatorTime.pyx"
...

Note : All the files generated by Cython remains in this setup folder, well separated from the hand written stuffs (adapters and pyext), as expected.

In 3. Using a separated DEPENDENCIES folder allows to keep things well separated (in case I would move the CYPROJECT - and its dependencies - in some other environment).

All of this to give you an overview (a pertinent one, I hope) on how one can organize that sort of project.

这篇关于项目组织与用Cython和C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆