如何解决如何构建符合 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"
见
- https://setuptools.readthedocs.io/en/latest/build_meta.html 和
- https://setuptools.readthedocs.io/en/latest/userguide/declarative_config.html#declarative-config
此外,实际的元数据应该进入 setup.cfg
。但是,我没有找到任何关于如何将 ext_modules
kwarg,特别是 Extension()
调用转换为 setup.cfg
语法的解释。
解决方法
pyproject.toml
并不是严格意义上的替换 setup.py
,而是确保它在仍然需要时正确执行(参见 PEP 517 和 my 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 举报,一经查实,本站将立刻删除。