【问题标题】:How to specify header files in setup.py script for Python extension module?如何在 setup.py 脚本中为 Python 扩展模块指定头文件?
【发布时间】:2011-07-09 08:19:47
【问题描述】:

如何在 setup.py 脚本中为 Python 扩展模块指定头文件?按如下方式将它们与源文件一起列出是行不通的。但我不知道在哪里列出它们。

from distutils.core import setup, Extension
from glob import glob

setup(
    name = "Foo",
    version = "0.1.0",
    ext_modules = [Extension('Foo', glob('Foo/*.cpp') + glob('Foo/*.h'))]
)

【问题讨论】:

  • 尝试导入 setuptools 而不是 distutils.core。然后我相信它会自动拾取头文件。如果这不起作用,请添加一个 MANIFEST.in 如下

标签: python distutils


【解决方案1】:

在 setup.py 之外添加 MANIFEST.in 文件,内容如下:

graft relative/path/to/directory/of/your/headers/

【讨论】:

  • 这不是告诉 distutils 安装头文件吗?我不想安装标题;它们只能用作编译器的输入。只应安装编译器生成的 pyd 文件。
  • 不,不会安装乳清。 MANIFEST 不是用于安装,而是用于源代码分发(setup.py sdist)。
  • 太棒了!但令我惊讶的是,你需要一个清单来做这么简单的事情。
  • 哎呀,我不敢相信我忘记了 MANIFEST.in。 >.
  • @Éric Araujo:我很惊讶 distutils 知道源文件但不知道头文件。
【解决方案2】:

尝试将标头 kwarg 设置为 setup()。我不知道它在任何地方都有记录,但它确实有效。

setup(name='mypkg', ..., headers=['src/includes/header.h'])

【讨论】:

  • 这确实应该有效。我不知道该文档是否被疏忽遗漏了,或者它是否应该是内部细节。
  • @Éric Araujo:我试过了,但没有用。我做了“setup.py sdist”,并且标头未包含在 Foo-0.1.0.zip 中。
  • 在 sdist 命令的代码中实际上有一条注释说不包含标头,而 build_ext 中的另一个注释(它定义了 sdist 用来构建其文件列表的一部分的 get_source_file 函数) 上面写着“如果我们也知道头文件的名称会不会很整洁”。 distutils 对新功能关闭(我们现在在 distutils2 上工作),但我倾向于认为这是一个错误,并在 Python 2.7 和 3.2 的下一个版本中修复它。稍后我会打开关于 bugs.python.org 的报告。
  • @ÉricAraujo 你能添加错误报告的链接吗?我找不到它。
【解决方案3】:

我在使用 setuptools 时遇到了很多麻烦,它甚至不再有趣了。 以下是我最终不得不使用一种解决方法来生成带有头文件的工作源分发的方式:我使用了 package_data。

我分享这个是为了避免其他人的恶化。如果您知道更好的工作解决方案,请告诉我。

详情请看这里: https://bitbucket.org/blais/beancount/src/ccb3721a7811a042661814a6778cca1c42433d64/setup.py?fileviewer=file-view-default#setup.py-36

    # A note about setuptools: It's profoundly BROKEN.
    #
    # - The header files are needed in order to distribution a working
    #   source distribution.
    # - Listing the header files under the extension "sources" fails to
    #   build; distutils cannot make out the file type.
    # - Listing them as "headers" makes them ignored; extra options to
    #   Extension() appear to be ignored silently.
    # - Listing them under setup()'s "headers" makes it recognize them, but
    #   they do not get included.
    # - Listing them with "include_dirs" of the Extension fails as well.
    #
    # The only way I managed to get this working is by working around and
    # including them as "packaged data" (see {63fc8d84d30a} below). That
    # includes the header files in the sdist, and a source distribution can
    # be installed using pip3 (and be built locally). However, the header
    # files end up being installed next to the pure Python files in the
    # output. This is the sorry situation we're living in, but it works.

我的OSS项目里有对应的ticket: https://bitbucket.org/blais/beancount/issues/72

【讨论】:

    【解决方案4】:

    如果我没记错的话,你应该只需要指定源文件,它应该可以找到/使用标题。

    在设置工具手册中,我相信对此有所了解。

    “例如,如果您的扩展需要在您的发行版根目录下的包含目录中的头文件,请使用 include_dirs 选项”

    Extension('foo', ['foo.c'], include_dirs=['include'])
    

    http://docs.python.org/distutils/setupscript.html#preprocessor-options

    【讨论】:

    • 试过 ext_modules = [Extension('Foo', glob('Foo/*.cpp'), include_dirs=['Foo'])]。不工作;头文件未添加到包中。
    • 您是否尝试过问题示例中的代码?它可能起作用,至少我希望它会起作用。 :) 我在手册中找不到与您的问题相关的任何其他内容;对不起。 :(
    • 我添加了 include_dirs 参数。它似乎需要一个绝对目录而不是相对目录,因为构建是在构建目录中执行的,并且不会复制 .h 文件。
    • 似乎提出了一个选项。参考:bugs.python.org/issue34012
    猜你喜欢
    • 2013-12-21
    • 2021-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多