python — setuptools: создайте общую библиотеку из кода C ++, затем создайте оболочку Cython, связанную с общей библиотекой

У нас есть куча файлов C ++ с классами, которые мы переносим в Python, используя Cython. Мы используем setuptools для создания расширения Cython. Это все отлично работает, мы следовали за руководством здесь
http://cython.readthedocs.io/en/latest/src/userguide/wrapping_CPlusPlus.html

Мы в основном делаем что-то вроде этого

from distutils.core import setup
from Cython.Build import cythonize

setup(ext_modules = cythonize(
"rect.pyx",                 # our Cython source
sources=["Rectangle.cpp"],  # additional source file(s)
language="c++",             # generate C++ code
))

Нам не нравится в этом то, что мы должны перекомпилировать все, даже если меняется только часть Cython, rect.pyx в этом примере. На самом деле мы никогда не трогаем .cpp файлы, но измените .pyx файлы часто.

Мы хотели бы скомпилировать .cpp файлы отдельно в статическую или общую библиотеку, затем соберите .pyx файлы, которые ссылаются на библиотеку, сгенерированную из .cpp файлы. Все это будет легко с make или же cmake, но мы хотим чисто Python-решение, которое использует только setuptools, Код макета будет выглядеть примерно так:

from distutils.core import setup
from Cython.Build import cythonize

class CppLibary:
# somehow get that to work

# this should only recompile cpplib when source files changed
cpplib = CppLibary('cpplib',
sources=["Rectangle.cpp"], # put static cpp code here
include_dirs=["include"])

setup(ext_modules = cythonize(
"rect.pyx",                 # our Cython source
libraries=[cpplib],         # link to cpplib
language="c++",             # generate C++ code
))

0

Решение

Существует, казалось бы, недокументированная особенность setup который может сделать это, например:

import os

from setuptools import setup
from Cython.Build import cythonize

ext_lib_path = 'rectangle'
include_dir = os.path.join(ext_lib_path, 'include')

sources = ['Rectangle.cpp']

# Use as macros = [('<DEFINITION>', '<VALUE>')]
# where value can be None
macros = None

ext_libraries = [['rectangle', {
'sources': [os.path.join(ext_lib_path, src) for src in sources],
'include_dirs': [include_dir],
'macros': macros,
}
]]

extensions = [Extension("rect",
sources=["rect.pyx"],
language="c++",
include_dirs=[include_dir],
libraries=['rectangle'],
)]

setup(ext_modules=cythonize(extensions),
libraries=ext_libraries)

libraries Аргумент строит внешнюю библиотеку, найденную в каталоге rectangle, с включенным каталогом rectangle/include общего между ним и расширением.

Также переключили импорт на setuptools от distutils который устарел, теперь часть setuptools.

Не видел никакой документации по этому аргументу, но видел, что она использовалась в других проектах.

Это не проверено, пожалуйста, предоставьте образцы файлов для тестирования, если это не работает.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]