微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何构建符合 PEP 517 的 C 扩展,即使用 pyproject.toml 而不是 setup.py?

如何解决如何构建符合 PEP 517 的 C 扩展,即使用 pyproject.toml 而不是 setup.py?

我想为 cpython 构建一个 C 扩展。传统上,我可以使用 setup.py 文件来完成。但是,出于 PEP 517 中提到的原因,我更喜欢使用 pyproject.toml 的声明性方法。我知道 setuptools 是唯一可以在所有相关平台上构建 C 扩展的构建后端。事实上,除了过时的 distutils 之外,我根本不知道有任何后端能够构建 C 扩展。

在此背景下,常见的 setup.py 如下所示:

from setuptools import setup,Extension
kwargs = dict(
    name='mypackage',# more Metadata
    ext_modules=[
        Extension('mypackage.mymodule',['lib/mymodule.c','lib/mypackage.c','lib/myalloc.c'],include_dirs=['lib'],py_limited_api=True)])

setup(**kwargs)

现在,挑战是将上述内容放入一个 pyproject.toml 加上一个 setup.cfg

setuptools 文档建议使用这样的 pyproject.toml

[build-system]
requires = [
    "setuptools >=52.0",'wheel >= 0.36']
build-backend = "setuptools.build_Meta"

此外,实际的元数据应该进入 setup.cfg。但是,我没有找到任何关于如何将 ext_modules kwarg,特别是 Extension() 调用转换为 setup.cfg 语法的解释。

解决方法

pyproject.toml 并不是严格意义上的替换 setup.py,而是确保它在仍然需要时正确执行(参见 PEP 517my answer here):

如果 build-backend 键存在,则优先,源树遵循指定后端的格式和约定(因此不需要 setup.py 除非后端需要它强>)。项目可能仍希望包含 setup.py 以与不使用此规范的工具兼容。

虽然 setuptools 尝试将所有内容从脚本移动到配置文件中,但 it's not always possible

有两种类型的元数据:静态和动态。

  • 静态元数据 (setup.cfg):保证每次都相同。这更简单、更易于阅读,并避免了许多常见错误,例如编码错误。
  • 动态元数据 (setup.py):可能不确定。任何动态的或在安装时确定的项目,以及扩展模块setuptools 的扩展,都需要进入 setup.py

应首选静态元数据,仅在绝对必要时才将动态元数据用作逃生舱。

事实上,setup.cfg-only projects 现在只有 2 年可能,而 setuptools will use an imaginary setup.py if it doesn't exist 无论如何。


话虽如此,如果您想尽可能地坚持静态方式,您可以将所有可以移动到 setup.cfg 文件中,并将其余部分留在 setup.py 中:

setup.cfg
[metadata]
name = mypackage
; more metadata
setup.py
from setuptools import setup,Extension

setup_args = dict(
    ext_modules = [
        Extension(
            'mypackage.mymodule',['lib/mymodule.c','lib/mypackage.c','lib/myalloc.c'],include_dirs = ['lib'],py_limited_api = True
        )
    ]
)
setup(**setup_args)

但我会把所有东西都放在 setup.py 中。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。