我想为CPython构建一个C扩展。我传统上可以使用<code>设置来完成。py文件。然而,出于PEP517中提到的原因,我更喜欢使用<code>pyproject.toml</code>的声明性方法。我知道setuptools
是唯一可以在所有相关平台上构建C扩展的构建后端。事实上,除了过时的distutils
之外,我还不知道有任何后端能够构建C扩展。
在此背景下,常见的<code>设置。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)
现在的挑战是将上述内容放入< code>pyproject.toml和< code>setup.cfg中。
setup工具
文档建议pyproject.toml
如下所示:
[build-system]
requires = [
"setuptools >=52.0",
'wheel >= 0.36']
build-backend = "setuptools.build_meta"
看见
此外,实际的元数据应该放入< code>setup.cfg中。但是,我还没有找到任何关于如何将< code>ext_modules kwarg,尤其是< code>Extension()调用,翻译成< code>setup.cfg语法的解释。
下面是一个黑客,可用于使用 pyproject.toml
构建 ext,而无需依赖 setup.py
pyproject.toml
[tool.setuptools]
py-modules = ["_custom_build"]
[tool.setuptools.cmdclass]
build_py = "_custom_build.build_py"
_custom_build.py
from setuptools import Extension
from setuptools.command.build_py import build_py as _build_py
class build_py(_build_py):
def run(self):
self.run_command("build_ext")
return super().run()
def initialize_options(self):
super().initialize_options()
if self.distribution.ext_modules == None:
self.distribution.ext_modules = []
self.distribution.ext_modules.append(
Extension(
"termial_random.random",
sources=["termial_random/random.c"],
extra_compile_args=["-std=c17", "-lm"],
)
)
严格来说,< code>pyproject.toml并不是要取代< code>setup.py,而是要确保在仍然需要的情况下正确执行它(参见PEP
如果存在构建
后端密钥,则优先,并且源代码树遵循指定后端的格式和约定(因此,除非后端需要,否则不需要 setup.py
)。项目可能仍希望包含与不使用此规范的工具兼容的 setup.py
。
虽然setuptools
计划将所有内容从脚本移动到配置文件中,但这并不总是可能的:
有两种类型的元数据:静态和动态。
setup.cfg
):保证每次都是一样的,这样更简单,更容易阅读,并且避免了许多常见的错误,比如编码错误。setup.py
):可能是非确定性的。任何动态的或在安装时确定的项目,以及扩展模块或setuptools
的扩展,都需要进入setup.py
。静态元数据应该是首选,而动态元数据应该仅在绝对必要时作为一个出口使用。
事实上,<code>setuptools</code>仍将使用虚构的<code>设置。py(如果不存在)。
注意:自版本
话虽如此,如果你想尽可能多地坚持静态方式,你可以将所有内容移动到pyproject.toml
文件中,其余的暂时保留在 setup.py
:
[build-system]
requires = ["setuptools>=61"]
build-backend = "setuptools.build_meta"
[project]
name = "mypackage"
# more metadata
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)
问题内容: 我有一个C扩展模块,很高兴分发内置的二进制文件。SetupTools使得在OS X和GNU / Linux上构建扩展模块变得很容易,因为那些OS随GCC一起提供,但是我不知道如何在Windows中进行。 我需要购买Visual Studio的副本,还是可以使用Visual Studio Express?我可以只使用Cygwin或MinGW吗? 问题答案: 您可以同时使用MinGW和VC
我有一个proto,它有一条包含扩展名的消息 我有另一个proto,它有扩展(只显示下面的一个扩展) 通过protobuf代码,我能够获得MsgB的描述符和FileDescriptor,并从中检索FieldDescriptor类型的扩展名“MsgB”。我通过protobuf代码查找扩展,而不是使用MsgB协议生成的代码,因为我试图迭代所有扩展消息,而不是将每个消息硬编码为可变扩展。(我理解Muta
作者:陈希章 发表于 2018年4月7日 前言 此前我有一篇 文章 讲解了Microsoft Graph的一种数据扩展技术—— 开发扩展(Open Extensions),它可以实现在支持的对象(例如用户,组等)上面附加任意的数据。但开放扩展的问题在于,它是基于某个具体对象的,你无法确定两个对象是否具有同样的扩展(即便属性名一样,但也可能其包含的数据完全不同)。如果我们需要对一类对象进行统一的扩展
问题内容: 我想用Java解决带有多个线程的数学问题。我的数学问题可以分为多个工作单元,我想通过几个线程来解决。 我不希望有固定数量的线程在工作,而是与CPU核心数量匹配的线程数量。我的问题是,为此我在互联网上找不到简单的教程。我发现的只是带有固定线程的示例。 如何才能做到这一点?你能提供例子吗? 问题答案: 你可以通过使用静态运行时方法,确定提供给Java虚拟机的进程数availableProc
问题内容: 我在python代码中发现了瓶颈,并与psycho等打交道。然后决定编写ac / c ++扩展以提高性能。 借助swig,您几乎不需要关心参数等。一切正常。 现在我的问题是:swig创建了一个很大的py文件,该文件在调用实际的.pyd或.so代码之前会执行很多“检查”和“ PySwigObject”。 你们中的任何人是否有经验,如果您手动编写此文件或让wig来做,是否可以获得更多性能。