Project organization with Cython and C++(使用 Cython 和 C++ 进行项目组织)
问题描述
我想为我的 C++ 项目提供 Python 接口.从技术上讲,我决定使用 Cython 来包装 C++ 代码.随着时间的推移,整个项目旨在成为一个 Python 扩展模块,但起初,这是高度实验性的.渐渐地,C++ 类需要暴露给 Python.
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.
我的问题是如何最好地组织文件和构建配置,以便 Cython 生成的和人工编写的 C++ 代码不会混合在一起,并且 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.
我想像这样的目录结构用于源文件,以及一些用于 Cython 的构建目录.
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
推荐答案
基本上我有 3 个文件夹:
Basically I have 3 folders :
CPROJECT
,C++ 库:生成一个libcproject.so
共享对象CYPPROJECT
,cythonized Python 扩展:使用 Cython 生成cyproject.so
DEPENDENCIES
,依赖项:我复制两个项目的外部需求
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
在 1. 我构建了 C++ 扩展(使用 gcc 编译 - -shared
, -fPIC
编译选项)将暴露给python 并且 CYPPROJECT
依赖于向 Python 公开功能.作为后处理命令,生成的 .so
被复制到 DEPENDENCIES/libcproject/
(以及 include
文件).这样,库当然也可以在纯 C++ 项目中独立使用.
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.
在 2. 我使用了 3 个子文件夹:
In 2. I make use of 3 sub-folders :
adapters
:主要包含 C++ 附加类(通常是从libcproject.so
提供的类派生的类).这些通常是使用特定于 Cython 要求的功能增强的类(例如存储目标 Python 版本的PyObject *
C 版本 - 从object
继承 - 给定类以及引用计数管理,通过Py_XINCREF
和Py_DECREF
,...).pyext
: 所有 Cython 手写.pyx
文件的存储位置.setup
:包含setup.sh
脚本(用于设置依赖路径和调用python setup.py build_ext --inplace
用于生成最终的cyproject.so(要添加到 PYTHONPATH
)和cyproject.pyx
.
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
.
那么 setup
子文件夹中有什么?
So what's in the setup
sub-folder ?
这是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
的例子(主要是为了演示额外的适配器
是如何编译的):
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=[]
)
]
)
最后是主要的 .pyx
,它将 cython 部分的所有手写 .pyx
链接在一起 [cyproject.pyx
] :
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"
...
注意:Cython 生成的所有文件都保留在这个 setup
文件夹中,与手写的东西(adapters
和 pyext
)分开,正如预期的那样.
Note : All the files generated by Cython remains in this setup
folder, well separated from the hand written stuffs (adapters
and pyext
), as expected.
在 3. 中使用单独的 DEPENDENCIES
文件夹可以将事情分开(以防我移动 CYPPROJECT
- 及其依赖项- 在其他一些环境中).
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++ 进行项目组织的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用 Cython 和 C++ 进行项目组织
基础教程推荐
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01