跳转到主要内容

为基于CMake的项目构建后端

项目描述

scikit-build-core

Documentation Status GitHub Discussion Discord

Actions Status codecov

PyPI version Conda-Forge PyPI platforms Downloads

[!注意]

我们每月举行一次公开的Scikit-build社区会议!请在每月第三个星期五中午12:00 EST加入我们参加Google Meet会议。[链接](https://meet.google.com/dvx-jkai-xhq "加入我们")。我们还在每月第一个星期五同一时间举行开发者会议。我们的过去会议记录[在这里](https://github.com/orgs/scikit-build/discussions/categories/community-meeting-notes "社区会议记录")。

scikit-build-core是一个使用CMake构建扩展模块的Python构建后端。它拥有一个简单而强大的静态配置系统(在pyproject.toml中),并通过CMake支持几乎无限的灵活性。它最初是为了满足科学用户的高要求而开发的,但可以构建任何使用CMake的软件包。

scikit-build-core是经典Scikit-build的从头重写。Scikit-build经典(基于setuptools)的关键特性也在这里

  • 对大多数操作系统、编译器、IDE和库的优秀支持
  • 支持C++特性和Fortran等其他语言
  • 支持多线程构建
  • 简单的CMakeFiles.txt文件,而不是成千上万的脆弱的setuptools/distutils代码
  • 支持Apple Silicon和Windows ARM的交叉编译

scikit-build-core使用在scikit-build(经典)编写之后开发的Python打包标准构建。直接使用它相对于经典Scikit-build提供了以下功能

  • 更好的警告、错误和日志记录
  • 没有关于未使用变量的警告
  • 根据需要自动添加Ninja和/或CMake
  • 不依赖于setuptools、distutils或wheel
  • 强大的配置系统,包括配置选项支持
  • 自动将site-packages包含在CMAKE_PREFIX_PATH
  • 如果运行在CMake < 3.26.1上,则回退使用FindPython,支持PyPY SOABI & 有限API / 稳定ABI
  • 通过配置选项支持有限API / 稳定ABI和pythonless标记
  • 没有缓慢的生成器搜索,默认使用ninja/make或MSVC,尊重CMAKE_GENERATOR
  • 默认情况下SDists是可以重制的(UNIX,Python 3.9+,建议进行未压缩的比较)
  • 支持构建之间的缓存(通过设置build-dir进行选择)
  • 支持写入额外的wheel文件夹(脚本、头文件、数据)
  • 支持选择安装组件和构建目标
  • 为模块和前缀目录提供专用入口点
  • 几个集成的动态元数据插件(即将提供标准化支持)
  • 实验性可编辑模式支持,可选的实验性自动重建(导入时)和可选的现场模式
  • 支持WebAssembly(Emscripten/Pyodide
  • 支持免费线程的Python 3.13

与经典scikit-build相比,以下存在一些限制

  • 最低支持的CMake版本是3.15
  • 最低支持的Python版本是3.7

一些即将开发的功能

  • 轮子(wheels)还不能完全重制(大多数其他系统,包括setuptools也是如此)
  • 一些可编辑模式注意事项(在文档中提及)

还计划其他后端

  • setuptools集成处于高度实验阶段
  • Hatchling插件处于高度实验阶段

推荐接口是本机pyproject构建器。还有一个基于setuptools的WIP接口正在开发中,以提供经典scikit-build的过渡路径,以及一个WIP的Hatchling插件。两者都可能在未来被移动到独立包中。

[!警告]

应仅使用基于 pyproject 的构建器;setuptools 后端处于实验阶段,可能在被正式认定为稳定之前移动到单独的包中,内部 API 仍在巩固中。本包的未来版本将支持创建新的构建扩展。

示例

要使用 scikit-build-core,请将其添加到您的 build-system.requires,并将 scikit_build_core.build 构建器指定为您的 build-system.build-backend。您 无需 指定 cmakeninja;如果系统版本不足,scikit-build-core 将自动要求它们。

[build-system]
requires = ["scikit-build-core"]
build-backend = "scikit_build_core.build"

[project]
name = "scikit_build_simplest"
version = "0.0.1"

您(也应该)指定 project 中的其余条目,但这些是最基本的启动项。

一个示例 CMakeLists.txt

cmake_minimum_required(VERSION 3.15...3.30)
project(${SKBUILD_PROJECT_NAME} LANGUAGES C)

find_package(Python COMPONENTS Interpreter Development.Module REQUIRED)

Python_add_library(_module MODULE src/module.c WITH_SOABI)
install(TARGETS _module DESTINATION ${SKBUILD_PROJECT_NAME})

Scikit-build-core 将将 CMake 3.26.1 中的 FindPython 回滚到较旧的 Python 版本,并在您从 PyPy 构建时为您处理 PyPy。您需要将所有您想要安装的内容安装到 site-modules 内部的完整最终路径中(因此您通常会使用包名作为前缀)。

更多示例请参阅 tests/packages

配置

所有配置选项都可以放在 pyproject.toml 中,通过构建时的 -C/--config-settingpip 中的 -C/--config-settings 传递,或者作为环境变量设置。在 toml 中使用 tool.scikit-build,在 -C 选项中使用 skbuild.,或使用环境变量中的 SKBUILD_*。以下列出了默认值:

[tool.scikit-build]
# The versions of CMake to allow. If CMake is not present on the system or does
# not pass this specifier, it will be downloaded via PyPI if possible. An empty
# string will disable this check. The default on 0.10+ is "CMakeLists.txt",
# which will read it from the project's CMakeLists.txt file, or ">=3.15" if
# unreadable or <0.10.
cmake.version = ""

# A list of args to pass to CMake when configuring the project. Setting this in
# config or envvar will override toml. See also ``cmake.define``.
cmake.args = []

# A table of defines to pass to CMake when configuring the project. Additive.
cmake.define = {}

# DEPRECATED in 0.10, use build.verbose instead.
cmake.verbose = ""

# The build type to use when building the project. Valid options are: "Debug",
# "Release", "RelWithDebInfo", "MinSizeRel", "", etc.
cmake.build-type = "Release"

# The source directory to use when building the project. Currently only affects
# the native builder (not the setuptools plugin).
cmake.source-dir = "."

# DEPRECATED in 0.10; use build.targets instead.
cmake.targets = ""

# The versions of Ninja to allow. If Ninja is not present on the system or does
# not pass this specifier, it will be downloaded via PyPI if possible. An empty
# string will disable this check.
ninja.version = ">=1.5"

# If Ninja is not present on the system or is older than required, it will be
# downloaded via PyPI if this is false.
ninja.make-fallback = true

# The logging level to display, "DEBUG", "INFO", "WARNING", and "ERROR" are
# possible options.
logging.level = "WARNING"

# Files to include in the SDist even if they are skipped by default. Supports
# gitignore syntax.
sdist.include = []

# Files to exclude from the SDist even if they are included by default. Supports
# gitignore syntax.
sdist.exclude = []

# If set to True, try to build a reproducible distribution (Unix and Python 3.9+
# recommended).  ``SOURCE_DATE_EPOCH`` will be used for timestamps, or a fixed
# value if not set.
sdist.reproducible = true

# If set to True, CMake will be run before building the SDist.
sdist.cmake = false

# A list of packages to auto-copy into the wheel. If this is not set, it will
# default to the first of ``src/<package>``, ``python/<package>``, or
# ``<package>`` if they exist.  The prefix(s) will be stripped from the package
# name inside the wheel. If a dict, provides a mapping of package name to source
# directory.
wheel.packages = ["src/<package>", "python/<package>", "<package>"]

# The Python tags. The default (empty string) will use the default Python
# version. You can also set this to "cp37" to enable the CPython 3.7+ Stable ABI
# / Limited API (only on CPython and if the version is sufficient, otherwise
# this has no effect). Or you can set it to "py3" or "py2.py3" to ignore Python
# ABI compatibility. The ABI tag is inferred from this tag.
wheel.py-api = ""

# Fill out extra tags that are not required. This adds "x86_64" and "arm64" to
# the list of platforms when "universal2" is used, which helps older Pip's
# (before 21.0.1) find the correct wheel.
wheel.expand-macos-universal-tags = false

# The install directory for the wheel. This is relative to the platlib root. You
# might set this to the package name. The original dir is still at
# SKBUILD_PLATLIB_DIR (also SKBUILD_DATA_DIR, etc. are available). EXPERIMENTAL:
# An absolute path will be one level higher than the platlib root, giving access
# to "/platlib", "/data", "/headers", and "/scripts".
wheel.install-dir = ""

# A list of license files to include in the wheel. Supports glob patterns.
wheel.license-files = ["LICEN[CS]E*", "COPYING*", "NOTICE*", "AUTHORS*"]

# If set to True (the default), CMake will be run before building the wheel.
wheel.cmake = true

# Target the platlib or the purelib. If not set, the default is to target the
# platlib if wheel.cmake is true, and the purelib otherwise.
wheel.platlib = ""

# A set of patterns to exclude from the wheel. This is additive to the SDist
# exclude patterns. This applies to the final paths in the wheel, and can
# exclude files from CMake output as well.  Editable installs may not respect
# this exclusion.
wheel.exclude = []

# The build tag to use for the wheel. If empty, no build tag is used.
wheel.build-tag = ""

# If CMake is less than this value, backport a copy of FindPython. Set to 0
# disable this, or the empty string.
backport.find-python = "3.26.1"

# Select the editable mode to use. Can be "redirect" (default) or "inplace".
editable.mode = "redirect"

# Turn on verbose output for the editable mode rebuilds.
editable.verbose = true

# Rebuild the project when the package is imported. The build-directory must be
# set.
editable.rebuild = false

# Extra args to pass directly to the builder in the build step.
build.tool-args = []

# The build targets to use when building the project. Empty builds the default
# target.
build.targets = []

# Verbose printout when building.
build.verbose = false

# The components to install. If empty, all default components are installed.
install.components = []

# Whether to strip the binaries. True for release builds on scikit-build-core
# 0.5+ (0.5-0.10.5 also incorrectly set this for debug builds).
install.strip = true

# The path (relative to platlib) for the file to generate.
generate[].path = ""

# The template to use for the file. This includes string.Template style
# placeholders for all the metadata. If empty, a template-path must be set.
generate[].template = ""

# The path to the template file. If empty, a template must be set.
generate[].template-path = ""

# The place to put the generated file. The "build" directory is useful for CMake
# files, and the "install" directory is useful for Python files, usually. You
# can also write directly to the "source" directory, will overwrite existing
# files & remember to gitignore the file.
generate[].location = "install"

# A message to print after a build failure.
messages.after-failure = ""

# A message to print after a successful build.
messages.after-success = ""

# List dynamic metadata fields and hook locations in this table.
metadata = {}

# Strictly check all config options. If False, warnings will be printed for
# unknown options. If True, an error will be raised.
strict-config = true

# Enable early previews of features not finalized yet.
experimental = false

# If set, this will provide a method for backward compatibility.
minimum-version = "0.10"  # current version

# The build directory. Defaults to a temporary directory, but can be set.
build-dir = ""

# Immediately fail the build. This is only useful in overrides.
fail = false

大多数 CMake 环境变量都应受支持,可以使用 CMAKE_ARGS 设置额外的 CMake 参数。ARCHFLAGS 用于指定 macOS universal2 或交叉编译,就像 setuptools 一样。

您还可以指定 [[tool.scikit-build.overrides]] 来为不同的系统自定义值。有关详细信息,请参阅文档。

其他构建项目

Scikit-build-core 是一个二进制构建后端。还有其他二进制构建后端

  • py-build-cmake:CMake 标准兼容构建器的一次尝试。重点关注交叉编译。使用 Flit 内部机制。
  • cmeel:CMake 标准兼容构建器的一次尝试。重点关注围绕 site-packages 中特殊不可导入文件夹的生态系统构建(类似于 scikit-build 对 cmake.* 入口点的使用,但基于文件夹)。
  • meson-python:基于 meson 的构建后端;与 scikit-build-core 有一些维护者重叠。
  • maturin:使用 Cargo 的 Rust 项目的构建后端。
  • enscons:基于 SCons 的后端,开发不太活跃(但它在现代标准支持方面是最早的!)

如果您不需要二进制构建,则不需要使用二进制构建后端!有一些非常好的 Python 构建后端;我们推荐 hatchling 作为初学者良好默认设置和高级用例良好支持的良好平衡。这是 scikit-build-core 本身使用的工具。

致谢

本工作的支持由 NSF 奖学金 OAC-2209877 提供。本材料中表达的意见、发现、结论或建议是作者的观点,不一定反映美国国家科学基金会的观点。

项目详情


发布历史 发布通知 | RSS 源

下载文件

下载适用于您平台文件的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分发

scikit_build_core-0.10.7.tar.gz (255.0 kB 查看散列值)

上传时间

构建分发

scikit_build_core-0.10.7-py3-none-any.whl (165.5 kB 查看散列值)

上传时间 Python 3

支持者: