【问题标题】:Bundling C++ extension headers with a Python package source distribution将 C++ 扩展标头与 Python 包源分发捆绑在一起
【发布时间】:2017-01-31 10:45:03
【问题描述】:

我正在为一个 C++ 库编写一个 Cython 包装器,我想将它作为 Python 包分发。我想出了一个看起来像这样的包的虚拟版本(完整源代码here)。

$ tree
.
├── bogus.pyx
├── inc
│   └── bogus.hpp
├── setup.py
└── src
    └── bogus.cpp
$
$ cat inc/bogus.hpp 
#ifndef BOGUS
#define BOGUS

class bogus
{
protected:
    int data;

public:
    bogus();
    int get_double(int value);
};

#endif
$
$ cat src/bogus.cpp 
#include "bogus.hpp"

bogus::bogus() : data(0)
{

}

int bogus::get_double(int value)
{
    data = value * 2;
    return data;
}
$ cat bogus.pyx 
# distutils: language = c++
# distutils: sources = src/bogus.cpp
# cython: c_string_type=str, c_string_encoding=ascii

cdef extern from 'bogus.hpp':
    cdef cppclass bogus:
        bogus() except +
        int get_double(int value)

cdef class Bogus:
    cdef bogus b
    def get_double(self, int value):
        return self.b.get_double(value)

使用下面的setup.py 文件,我可以确认库使用python setup.py install 正确安装,并且可以正常工作。

from setuptools import setup, Extension
import glob

headers = list(glob.glob('inc/*.hpp'))

bogus = Extension(
    'bogus',
    sources=['bogus.pyx', 'src/bogus.cpp'],
    include_dirs=['inc/'],
    language='c++',
    extra_compile_args=['--std=c++11', '-Wno-unused-function'],
    extra_link_args=['--std=c++11'],
)

setup(
    name='bogus',
    description='Troubleshooting Python packaging and distribution',
    author='Daniel Standage',
    ext_modules=[bogus],
    install_requires=['cython'],
    version='0.1.0'
)

但是,当我使用 python setup.py sdist build 构建源代码分发时,不包含 C++ 头文件并且无法编译 C++ 扩展。

如何确保 C++ 头文件与源代码分发捆绑在一起?!?!

对此进行故障排除后,我们发现了大量令人费解且不一致的文档、建议和技巧,但其中没有一个对我有用。在MANIFEST.in 中添加graft 行?没有。 package_datadata_files 选项?没有。在过去的几年里,Python 打包似乎有了很大的改进,但对于我们这些不喜欢 Python 打包的人来说,它仍然几乎是难以理解的!

【问题讨论】:

    标签: python packaging python-extensions python-packaging


    【解决方案1】:

    简答

    include inc/*.hpp 放入MANIFEST.in 文件中。

    长答案

    根据各种博客文章和 SO 线程,我尝试了在 MANIFEST.in 文件中声明文件的建议。在these instructions 之后,我在MANIFEST.in 中添加了graft inc/ 行以包含整个目录。这不起作用。

    但是,将这一行替换为 include inc/*.hpp 确实有效。可以说这应该是我尝试的第一件事,但是由于不熟悉 setuptools 和 distutils 的复杂性和缺陷,我没有理由期望 graft 不起作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-24
      • 1970-01-01
      • 2011-11-27
      • 1970-01-01
      • 2012-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多