Структура проекта для переноса многих классов С++ в cython на один общий объект
Я нашел частичные ответы между документами, списками рассылки и этот вопрос здесь, но я хотел получить более прямой ответ на мои особенности...
Я изучаю cython, пытаясь немного поменять небольшие части библиотеки, которую я уже использую, которая в настоящее время завернута в boost:: python. Я внес небольшой вклад в эту оболочку boost и использую ее как ссылку на С++, в то время как в то же время я использую привязки ZeroMQ Python как ссылку на cython.
Мой вопрос о структуре проекта. Текущая версия boost этого lib компилируется в один .so
, и это моя цель. Я быстро обнаружил, что вы не можете напрямую скомпилировать несколько модулей .pyx
в один .so
. Затем я начал сходить по пути определения файлов cppclass
in pxd
, а их соответствующие python экспортировал классы реализации в .pxi
и пытался включить их в один pyx
для компиляции. Хотя он работал сначала, как только я написал немного больше, я сталкивался с проблемами с конфликтующими множественными определениями, поскольку pxi
включает в себя разные места.
Я хотел бы услышать правильный организационный подход, который касается следующих вопросов и целей:
- Именование открытых классов так же, как
cppclass
(я делаю это сейчас, имея cppclass в другом имени pyd
и используя импортированное пространство имен для обработки похожих имен, ala Использование cimport для разрешения конфликтов имен)
- Одиночный
.so
как скомпилированный вывод (приемлемый подход?)
- Использовать ли метод
pyx
multi-include в основном pyx
только для этого, или если в главном pyx
содержится что-то еще, кроме того, что он содержит только те, которые включены?
- Где централизованно определять константы, которые будут экспортироваться в python?
- Есть ли предпочтительная структура папок? Прямо сейчас у меня есть все в большой директории
src
под моим setup.py
. Это запутывает, видя так много файлов pxi, pxd, pyx
.
- Являются ли теперь
pxi
ненужными? Если нет, мне нужно использовать защитник ifndef в стиле cython для обработки множественных включений между разными модулями?
- Я знаю, что привязки python ZeroMQ создают несколько модулей и используют пакетный подход, включая их через
__init__.py
. Это действительно правильный подход с cython?
Для справки, проект, который я тренирую для повторного обертывания, PyOpenNI (openni). Шаблон, который этот проект ускорения принимает, состоит в том, чтобы собрать общие объекты в одном месте, а затем определить определение заголовка 1-к-1 с источником, а затем есть огромная оболочка, которая собирает все определения в одном месте. А также добавлена специальная обработка исключений и утилиты.
Ответы
Ответ 1
Ожидая окончательного ответа, я продолжал играть с организацией своего кода. Включение файлов pyx
в один pyx
для компиляции уже работает.
Мой setup.py
прост как:
ext_modules = [
Extension(
"openni",
["src/openni.pyx"],
language="c++",
include_dirs=['src/', '/usr/include/ni'],
libraries=['OpenNI'],
)
],
Основной openni.pyx
выглядит следующим образом:
include "constants.pyx"
include "exceptions.pyx"
include "context.pyx"
...
У меня есть общий libopenni.pxd
, чтобы предоставить остальным модулям только объявления.
Я называю мои объявления cppclass
другим pxd
именем, чем определения класса pyx
, чтобы избежать столкновения имен:
xncontext.pxd
cdef extern from "XnCppWrapper.h" namespace "xn":
cdef cppclass Context:
...
context.pyx:
from libopenni cimport *
from xncontext cimport Context as c_Context
cdef class Context:
cdef c_Context *handle
...
Ответ 2
Ответ. Есть ли предпочтительная структура папок?
Да, предпочтительная структура папок для файлов Cython .pyx
и .pxd
должна обрабатывать их точно так же, как и ваши файлы .py
: по одному на модуль в хорошо организованной структуре пакета. __init__.pxd
файлы могут быть предоставлены так же, как файлы __init__.py
, чтобы собрать кураторский набор символов для сбора кураторского набора символов из его подмодулей/пакетов для cimporting.
Правда, это создает один файл .so
для каждого модуля, но эти файлы скрыты в каталоге сборки. То же самое относится к модулям построения Python; есть соответствующие файлы .so
для каждого из них. Это проблема?