项目组织与用Cython和C ++ [英] Project organization with Cython and C++
问题描述
我想提供我的C ++与Python接口项目。从技术上讲,我已经决定用用Cython用于包装的C ++ code。随着时间的推移,整个项目是为了成为一个Python的扩展模块,但在第一,这是高度实验性的。渐渐地,C ++类需要接触到Python。
我的问题是如何最好地组织文件和构建配置,以便用Cython产生和人类编写的C ++ code不要混合Python的扩展模块是干净建单独从其他目标。
我想象用Cython这样的目录结构的源文件,以及一些构建目录。
项目/
SRC /
*。H
*的.cpp
用Cython /
Project.pyx
setup.py
基本上我有3个文件夹:
-
的CProject
,C ++库:生产libcproject.so
共享对象 -
CYPROJECT
,该cythonized Python扩展:生产cyproject.so
使用用Cython -
相关内容
,依赖:在那里我复制外部需求这两个项目
在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 :
CPROJECT
, The C++ library : producing alibcproject.so
shared objectCYPROJECT
, The cythonized Python extension : producing thecyproject.so
using CythonDEPENDENCIES
, 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 bylibcproject.so
). Those are usually classes that are enhanced with functionalities specific to Cython requirements (such as storing thePyObject *
C version of a targeted Python version - inherited fromobject
- of a given class and the reference counting management, viaPy_XINCREF
andPy_DECREF
, ...).pyext
: where are stored all the Cython hand written.pyx
files.setup
: containing thesetup.sh
script (for setting up the dependencies paths and calling thepython setup.py build_ext --inplace
for generating the finalcyproject.so
(to be added to thePYTHONPATH
) andcyproject.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 .pyx
s 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屋!