setuptools:从 C++ 代码构建共享库,然后构建链接到共享库的 Cython 包装器

olq*_*plo 6 c++ python build setuptools cython

我们有一堆 C++ 文件,其中包含我们使用 Cython 包装到 Python 的类。我们使用 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
      ))
Run Code Online (Sandbox Code Playgroud)

我们不喜欢这样,我们必须重新编译所有内容,即使rect.pyx在本例中只有 Cython 部分发生变化。事实上我们从来不碰.cpp文件,但.pyx经常更改文件。

我们希望将.cpp文件单独编译成静态或共享库,然后.pyx独立构建文件,该文件链接到从文件生成的库.cppmake使用或,所有这些都会很容易cmake,但我们想要一个仅使用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
      ))
Run Code Online (Sandbox Code Playgroud)

dan*_*nny 6

有一个看似未记录的功能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)
Run Code Online (Sandbox Code Playgroud)

libraries参数构建在 directory 中找到的外部库,以及它和扩展之间公共的rectangleinclude 目录。rectangle/include

还已将导入切换到已弃用的setuptools位置,现在是安装工具的一部分。distutils

没有看到任何关于这个论点的文档,但看到它在其他项目中使用。

此未经测试,如果不起作用,请提供示例文件进行测试。