代码之家  ›  专栏  ›  技术社区  ›  olq_plo

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

  •  5
  • olq_plo  · 技术社区  · 7 年前

    我们有一组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
          ))
    

    我们不喜欢这样,我们必须重新编译所有内容,即使只有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
          ))
    
    1 回复  |  直到 4 年前
        1
  •  5
  •   danny    7 年前

    有一个似乎未记录的功能 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的一部分。

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

    这是未测试的,如果不起作用,请提供样本文件进行测试。