mirror of
https://github.com/pybind/pybind11.git
synced 2026-03-14 20:27:47 +00:00
chore: use scikit-build-core for the build (#5598)
* chore: use scikit-build-core for the build Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> * fix: support tests job Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> * refactor: use tomlkit instead of manual parsing Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> * tests: add tests for output Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> * chore: remove more unused files Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> * fix: restore global pin Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> * fix: test and fix pinning Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com> --------- Signed-off-by: Henry Schreiner <henryschreineriii@gmail.com>
This commit is contained in:
3
.github/workflows/format.yml
vendored
3
.github/workflows/format.yml
vendored
@@ -32,9 +32,6 @@ jobs:
|
||||
- name: Add matchers
|
||||
run: echo "::add-matcher::$GITHUB_WORKSPACE/.github/matchers/pylint.json"
|
||||
- uses: pre-commit/action@v3.0.1
|
||||
with:
|
||||
# Slow hooks are marked with manual - slow is okay here, run them too
|
||||
extra_args: --hook-stage manual --all-files
|
||||
|
||||
clang-tidy:
|
||||
# When making changes here, please also review the "Clang-Tidy" section
|
||||
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -45,3 +45,9 @@ pybind11Targets.cmake
|
||||
.ipynb_checkpoints/
|
||||
tests/main.cpp
|
||||
CMakeUserPresents.json
|
||||
|
||||
/Python
|
||||
/tmp*
|
||||
.ruby-version
|
||||
.*cache*/
|
||||
*.lock
|
||||
|
||||
@@ -108,15 +108,6 @@ repos:
|
||||
- id: rst-directive-colons
|
||||
- id: rst-inline-touching-normal
|
||||
|
||||
# Checks the manifest for missing files (native support)
|
||||
- repo: https://github.com/mgedmin/check-manifest
|
||||
rev: "0.50"
|
||||
hooks:
|
||||
- id: check-manifest
|
||||
# This is a slow hook, so only run this if --hook-stage manual is passed
|
||||
stages: [manual]
|
||||
additional_dependencies: [cmake, ninja]
|
||||
|
||||
# Check for spelling
|
||||
# Use tools/codespell_ignore_lines_from_errors.py
|
||||
# to rebuild .codespell-ignore-lines
|
||||
|
||||
@@ -65,6 +65,13 @@ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
||||
|
||||
message(STATUS "CMake ${CMAKE_VERSION}")
|
||||
|
||||
if(DEFINED SKBUILD AND DEFINED $ENV{PYBIND11_GLOBAL_PREFIX})
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"PYBIND11_GLOBAL_PREFIX is not supported, use nox -s build_global or a pybind11-global SDist instead."
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
@@ -295,6 +302,9 @@ elseif(USE_PYTHON_INCLUDE_DIR AND DEFINED PYTHON_INCLUDE_DIR)
|
||||
endif()
|
||||
|
||||
if(PYBIND11_INSTALL)
|
||||
if(DEFINED SKBUILD_PROJECT_NAME AND SKBUILD_PROJECT_NAME STREQUAL "pybind11_global")
|
||||
install(DIRECTORY ${pybind11_INCLUDE_DIR}/pybind11 DESTINATION "${SKBUILD_HEADERS_DIR}")
|
||||
endif()
|
||||
install(DIRECTORY ${pybind11_INCLUDE_DIR}/pybind11 DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
set(PYBIND11_CMAKECONFIG_INSTALL_DIR
|
||||
"${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME}"
|
||||
@@ -361,6 +371,17 @@ if(PYBIND11_INSTALL)
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/pybind11.pc"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig/")
|
||||
|
||||
# When building a wheel, include __init__.py's for modules
|
||||
# (see https://github.com/pybind/pybind11/pull/5552)
|
||||
if(DEFINED SKBUILD_PROJECT_NAME AND SKBUILD_PROJECT_NAME STREQUAL "pybind11")
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/empty")
|
||||
file(TOUCH "${CMAKE_CURRENT_BINARY_DIR}/empty/__init__.py")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/empty/__init__.py"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/")
|
||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/empty/__init__.py"
|
||||
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig/")
|
||||
endif()
|
||||
|
||||
# Uninstall target
|
||||
if(PYBIND11_MASTER_PROJECT)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/tools/cmake_uninstall.cmake.in"
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
prune tests
|
||||
recursive-include pybind11/include/pybind11 *.h
|
||||
recursive-include pybind11 *.py
|
||||
recursive-include pybind11 py.typed
|
||||
include pybind11/share/cmake/pybind11/*.cmake
|
||||
include LICENSE README.rst SECURITY.md pyproject.toml setup.py setup.cfg
|
||||
@@ -69,9 +69,10 @@ author = "Wenzel Jakob"
|
||||
# built documents.
|
||||
|
||||
# Read the listed version
|
||||
with open("../pybind11/_version.py") as f:
|
||||
code = compile(f.read(), "../pybind11/_version.py", "exec")
|
||||
loc = {}
|
||||
version_file = DIR.parent / "pybind11/_version.py"
|
||||
with version_file.open(encoding="utf-8") as f:
|
||||
code = compile(f.read(), version_file, "exec")
|
||||
loc = {"__file__": str(version_file)}
|
||||
exec(code, loc)
|
||||
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
|
||||
50
noxfile.py
50
noxfile.py
@@ -7,6 +7,13 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import contextlib
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from collections.abc import Generator
|
||||
|
||||
import nox
|
||||
|
||||
@@ -99,13 +106,46 @@ def make_changelog(session: nox.Session) -> None:
|
||||
@nox.session(reuse_venv=True, default=False)
|
||||
def build(session: nox.Session) -> None:
|
||||
"""
|
||||
Build SDists and wheels.
|
||||
Build SDist and wheel.
|
||||
"""
|
||||
|
||||
session.install("build")
|
||||
session.log("Building normal files")
|
||||
session.run("python", "-m", "build", *session.posargs)
|
||||
session.log("Building pybind11-global files (PYBIND11_GLOBAL_SDIST=1)")
|
||||
session.run(
|
||||
"python", "-m", "build", *session.posargs, env={"PYBIND11_GLOBAL_SDIST": "1"}
|
||||
)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def preserve_file(filename: Path) -> Generator[str, None, None]:
|
||||
"""
|
||||
Causes a file to be stored and preserved when the context manager exits.
|
||||
"""
|
||||
old_stat = filename.stat()
|
||||
old_file = filename.read_text(encoding="utf-8")
|
||||
try:
|
||||
yield old_file
|
||||
finally:
|
||||
filename.write_text(old_file, encoding="utf-8")
|
||||
os.utime(filename, (old_stat.st_atime, old_stat.st_mtime))
|
||||
|
||||
|
||||
@nox.session(reuse_venv=True)
|
||||
def build_global(session: nox.Session) -> None:
|
||||
"""
|
||||
Build global SDist and wheel.
|
||||
"""
|
||||
|
||||
installer = ["--installer=uv"] if session.venv_backend == "uv" else []
|
||||
session.install("build", "tomlkit")
|
||||
session.log("Building pybind11-global files")
|
||||
pyproject = Path("pyproject.toml")
|
||||
with preserve_file(pyproject):
|
||||
newer_txt = session.run("python", "tools/make_global.py", silent=True)
|
||||
assert isinstance(newer_txt, str)
|
||||
pyproject.write_text(newer_txt, encoding="utf-8")
|
||||
session.run(
|
||||
"python",
|
||||
"-m",
|
||||
"build",
|
||||
*installer,
|
||||
*session.posargs,
|
||||
)
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
# This file will be replaced in the wheel with a hard-coded version. This only
|
||||
# exists to allow running directly from source without installing (not
|
||||
# recommended, but supported).
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
DIR = Path(__file__).parent.resolve()
|
||||
|
||||
input_file = DIR.parent / "include/pybind11/detail/common.h"
|
||||
regex = re.compile(
|
||||
r"""
|
||||
\#define \s+ PYBIND11_VERSION_MAJOR \s+ (?P<major>\d+) .*?
|
||||
\#define \s+ PYBIND11_VERSION_MINOR \s+ (?P<minor>\d+) .*?
|
||||
\#define \s+ PYBIND11_VERSION_PATCH \s+ (?P<patch>\S+)
|
||||
""",
|
||||
re.MULTILINE | re.DOTALL | re.VERBOSE,
|
||||
)
|
||||
|
||||
match = regex.search(input_file.read_text(encoding="utf-8"))
|
||||
assert match, "Unable to find version in pybind11/detail/common.h"
|
||||
__version__ = "{major}.{minor}.{patch}".format(**match.groupdict())
|
||||
|
||||
|
||||
def _to_int(s: str) -> int | str:
|
||||
try:
|
||||
@@ -8,5 +31,4 @@ def _to_int(s: str) -> int | str:
|
||||
return s
|
||||
|
||||
|
||||
__version__ = "3.0.0.dev1"
|
||||
version_info = tuple(_to_int(s) for s in __version__.split("."))
|
||||
|
||||
129
pyproject.toml
129
pyproject.toml
@@ -1,25 +1,118 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=42", "cmake>=3.18", "ninja"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
requires = ["scikit-build-core >=0.11.2"]
|
||||
build-backend = "scikit_build_core.build"
|
||||
|
||||
|
||||
[tool.check-manifest]
|
||||
ignore = [
|
||||
"tests/**",
|
||||
"docs/**",
|
||||
"tools/**",
|
||||
"include/**",
|
||||
".*",
|
||||
"pybind11/include/**",
|
||||
"pybind11/share/**",
|
||||
"CMakeLists.txt",
|
||||
"CMakePresets.json",
|
||||
"noxfile.py",
|
||||
[project]
|
||||
name = "pybind11"
|
||||
description = "Seamless operability between C++11 and Python"
|
||||
authors = [{name = "Wenzel Jakob", email = "wenzel.jakob@epfl.ch"}]
|
||||
license = "BSD-3-Clause"
|
||||
license-files = ["LICENSE"]
|
||||
readme = "README.rst"
|
||||
classifiers = [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
"Intended Audience :: Developers",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
"Topic :: Utilities",
|
||||
"Programming Language :: C++",
|
||||
"Programming Language :: Python :: 3 :: Only",
|
||||
"Programming Language :: Python :: 3.8",
|
||||
"Programming Language :: Python :: 3.9",
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Programming Language :: Python :: 3.13",
|
||||
"Programming Language :: Python :: Implementation :: PyPy",
|
||||
"Programming Language :: Python :: Implementation :: CPython",
|
||||
"Programming Language :: C++",
|
||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||
]
|
||||
keywords = [
|
||||
"C++11",
|
||||
"Python bindings",
|
||||
]
|
||||
dynamic = ["version", "optional-dependencies"]
|
||||
requires-python = ">=3.8"
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://github.com/pybind/pybind11"
|
||||
Documentation = "https://pybind11.readthedocs.io/"
|
||||
"Bug Tracker" = "https://github.com/pybind/pybind11/issues"
|
||||
Discussions = "https://github.com/pybind/pybind11/discussions"
|
||||
Changelog = "https://pybind11.readthedocs.io/en/latest/changelog.html"
|
||||
Chat = "https://gitter.im/pybind/Lobby"
|
||||
|
||||
[project.scripts]
|
||||
pybind11-config = "pybind11.__main__:main"
|
||||
|
||||
[project.entry-points."pipx.run"]
|
||||
pybind11 = "pybind11.__main__:main"
|
||||
|
||||
[project.entry-points.pkg_config]
|
||||
pybind11 = "pybind11.share.pkgconfig"
|
||||
|
||||
|
||||
[dependency-groups]
|
||||
test = [
|
||||
"pytest",
|
||||
"build",
|
||||
"tomlkit",
|
||||
]
|
||||
dev = [{ include-group = "test" }]
|
||||
|
||||
|
||||
[tool.scikit-build]
|
||||
minimum-version = "build-system.requires"
|
||||
sdist.exclude = [
|
||||
"/docs/**",
|
||||
"/.**",
|
||||
]
|
||||
wheel.install-dir = "pybind11"
|
||||
wheel.platlib = false
|
||||
|
||||
[tool.scikit-build.cmake.define]
|
||||
BUILD_TESTING = false
|
||||
PYBIND11_NOPYTHON = true
|
||||
prefix_for_pc_file = "${pcfiledir}/../../"
|
||||
|
||||
[tool.scikit-build.metadata.version]
|
||||
provider = "scikit_build_core.metadata.regex"
|
||||
input = "include/pybind11/detail/common.h"
|
||||
regex = '''(?sx)
|
||||
\#define \s+ PYBIND11_VERSION_MAJOR \s+ (?P<major>\d+) .*?
|
||||
\#define \s+ PYBIND11_VERSION_MINOR \s+ (?P<minor>\d+) .*?
|
||||
\#define \s+ PYBIND11_VERSION_PATCH \s+ (?P<patch>\S+)
|
||||
'''
|
||||
result = "{major}.{minor}.{patch}"
|
||||
|
||||
[tool.scikit-build.metadata.optional-dependencies]
|
||||
provider = "scikit_build_core.metadata.template"
|
||||
result = { global = ["pybind11-global=={project[version]}"]}
|
||||
|
||||
[[tool.scikit-build.generate]]
|
||||
path = "pybind11/_version.py"
|
||||
template = '''
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
def _to_int(s: str) -> int | str:
|
||||
try:
|
||||
return int(s)
|
||||
except ValueError:
|
||||
return s
|
||||
|
||||
|
||||
__version__ = "$version"
|
||||
version_info = tuple(_to_int(s) for s in __version__.split("."))
|
||||
'''
|
||||
|
||||
|
||||
# Can't use tool.uv.sources with requirements.txt
|
||||
[tool.uv]
|
||||
# Can't use tool.uv.sources with requirements.txt
|
||||
index-strategy = "unsafe-best-match"
|
||||
# This extra confuses uv
|
||||
override-dependencies = ["pybind11-global"]
|
||||
|
||||
|
||||
[tool.mypy]
|
||||
files = ["pybind11"]
|
||||
@@ -29,7 +122,7 @@ enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
|
||||
warn_unreachable = true
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
module = ["ghapi.*"]
|
||||
module = ["ghapi.*", "tomlkit"] # tomlkit has types, but not very helpful
|
||||
ignore_missing_imports = true
|
||||
|
||||
|
||||
@@ -46,10 +139,10 @@ messages_control.disable = [
|
||||
"protected-access",
|
||||
"missing-module-docstring",
|
||||
"unused-argument", # covered by Ruff ARG
|
||||
"consider-using-f-string", # triggers in _version.py incorrectly
|
||||
]
|
||||
|
||||
[tool.ruff]
|
||||
target-version = "py38"
|
||||
src = ["src"]
|
||||
|
||||
[tool.ruff.lint]
|
||||
|
||||
42
setup.cfg
42
setup.cfg
@@ -1,42 +0,0 @@
|
||||
[metadata]
|
||||
long_description = file: README.rst
|
||||
long_description_content_type = text/x-rst
|
||||
description = Seamless operability between C++11 and Python
|
||||
author = Wenzel Jakob
|
||||
author_email = wenzel.jakob@epfl.ch
|
||||
url = https://github.com/pybind/pybind11
|
||||
license = BSD
|
||||
|
||||
classifiers =
|
||||
Development Status :: 5 - Production/Stable
|
||||
Intended Audience :: Developers
|
||||
Topic :: Software Development :: Libraries :: Python Modules
|
||||
Topic :: Utilities
|
||||
Programming Language :: C++
|
||||
Programming Language :: Python :: 3 :: Only
|
||||
Programming Language :: Python :: 3.8
|
||||
Programming Language :: Python :: 3.9
|
||||
Programming Language :: Python :: 3.10
|
||||
Programming Language :: Python :: 3.11
|
||||
Programming Language :: Python :: 3.12
|
||||
Programming Language :: Python :: 3.13
|
||||
License :: OSI Approved :: BSD License
|
||||
Programming Language :: Python :: Implementation :: PyPy
|
||||
Programming Language :: Python :: Implementation :: CPython
|
||||
Programming Language :: C++
|
||||
Topic :: Software Development :: Libraries :: Python Modules
|
||||
|
||||
keywords =
|
||||
C++11
|
||||
Python bindings
|
||||
|
||||
project_urls =
|
||||
Documentation = https://pybind11.readthedocs.io/
|
||||
Bug Tracker = https://github.com/pybind/pybind11/issues
|
||||
Discussions = https://github.com/pybind/pybind11/discussions
|
||||
Changelog = https://pybind11.readthedocs.io/en/latest/changelog.html
|
||||
Chat = https://gitter.im/pybind/Lobby
|
||||
|
||||
[options]
|
||||
python_requires = >=3.8
|
||||
zip_safe = False
|
||||
153
setup.py
153
setup.py
@@ -1,153 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Setup script for PyPI; use CMakeFile.txt to build extension modules
|
||||
from __future__ import annotations
|
||||
|
||||
import contextlib
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import string
|
||||
import subprocess
|
||||
import sys
|
||||
from collections.abc import Generator
|
||||
from pathlib import Path
|
||||
from tempfile import TemporaryDirectory
|
||||
|
||||
import setuptools.command.sdist
|
||||
|
||||
DIR = Path(__file__).parent.absolute()
|
||||
VERSION_REGEX = re.compile(
|
||||
r"^\s*#\s*define\s+PYBIND11_VERSION_([A-Z]+)\s+(.*)$", re.MULTILINE
|
||||
)
|
||||
VERSION_FILE = Path("pybind11/_version.py")
|
||||
COMMON_FILE = Path("include/pybind11/detail/common.h")
|
||||
|
||||
|
||||
def build_expected_version_hex(matches: dict[str, str]) -> str:
|
||||
patch_level_serial = matches["PATCH"]
|
||||
serial = None
|
||||
major = int(matches["MAJOR"])
|
||||
minor = int(matches["MINOR"])
|
||||
flds = patch_level_serial.split(".")
|
||||
if flds:
|
||||
patch = int(flds[0])
|
||||
if len(flds) == 1:
|
||||
level = "0"
|
||||
serial = 0
|
||||
elif len(flds) == 2:
|
||||
level_serial = flds[1]
|
||||
for level in ("a", "b", "c", "dev"):
|
||||
if level_serial.startswith(level):
|
||||
serial = int(level_serial[len(level) :])
|
||||
break
|
||||
if serial is None:
|
||||
msg = f'Invalid PYBIND11_VERSION_PATCH: "{patch_level_serial}"'
|
||||
raise RuntimeError(msg)
|
||||
version_hex_str = f"{major:02x}{minor:02x}{patch:02x}{level[:1]}{serial:x}"
|
||||
return f"0x{version_hex_str.upper()}"
|
||||
|
||||
|
||||
# PYBIND11_GLOBAL_SDIST will build a different sdist, with the python-headers
|
||||
# files, and the sys.prefix files (CMake and headers).
|
||||
|
||||
global_sdist = os.environ.get("PYBIND11_GLOBAL_SDIST")
|
||||
|
||||
setup_py = Path(
|
||||
"tools/setup_global.py.in" if global_sdist else "tools/setup_main.py.in"
|
||||
)
|
||||
extra_cmd = 'cmdclass["sdist"] = SDist\n'
|
||||
|
||||
to_src = (
|
||||
(Path("pyproject.toml"), Path("tools/pyproject.toml")),
|
||||
(Path("setup.py"), setup_py),
|
||||
)
|
||||
|
||||
|
||||
# Read the listed version
|
||||
loc: dict[str, str] = {}
|
||||
code = compile(VERSION_FILE.read_text(encoding="utf-8"), "pybind11/_version.py", "exec")
|
||||
exec(code, loc)
|
||||
version = loc["__version__"]
|
||||
|
||||
# Verify that the version matches the one in C++
|
||||
matches = dict(VERSION_REGEX.findall(COMMON_FILE.read_text(encoding="utf8")))
|
||||
cpp_version = "{MAJOR}.{MINOR}.{PATCH}".format(**matches)
|
||||
if version != cpp_version:
|
||||
msg = f"Python version {version} does not match C++ version {cpp_version}!"
|
||||
raise RuntimeError(msg)
|
||||
|
||||
version_hex = matches.get("HEX", "MISSING")
|
||||
exp_version_hex = build_expected_version_hex(matches)
|
||||
if version_hex != exp_version_hex:
|
||||
msg = f"PYBIND11_VERSION_HEX {version_hex} does not match expected value {exp_version_hex}!"
|
||||
raise RuntimeError(msg)
|
||||
|
||||
|
||||
# TODO: use literals & overload (typing extensions or Python 3.8)
|
||||
def get_and_replace(filename: Path, binary: bool = False, **opts: str) -> bytes | str:
|
||||
if binary:
|
||||
contents = filename.read_bytes()
|
||||
return string.Template(contents.decode()).substitute(opts).encode()
|
||||
|
||||
return string.Template(filename.read_text()).substitute(opts)
|
||||
|
||||
|
||||
# Use our input files instead when making the SDist (and anything that depends
|
||||
# on it, like a wheel)
|
||||
class SDist(setuptools.command.sdist.sdist):
|
||||
def make_release_tree(self, base_dir: str, files: list[str]) -> None:
|
||||
super().make_release_tree(base_dir, files)
|
||||
|
||||
for to, src in to_src:
|
||||
txt = get_and_replace(src, binary=True, version=version, extra_cmd="")
|
||||
|
||||
dest = Path(base_dir) / to
|
||||
|
||||
# This is normally linked, so unlink before writing!
|
||||
dest.unlink()
|
||||
dest.write_bytes(txt) # type: ignore[arg-type]
|
||||
|
||||
|
||||
# Remove the CMake install directory when done
|
||||
@contextlib.contextmanager
|
||||
def remove_output(*sources: str) -> Generator[None, None, None]:
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
for src in sources:
|
||||
shutil.rmtree(src)
|
||||
|
||||
|
||||
with remove_output("pybind11/include", "pybind11/share"):
|
||||
# Generate the files if they are not present.
|
||||
with TemporaryDirectory() as tmpdir:
|
||||
cmd = ["cmake", "-S", ".", "-B", tmpdir] + [
|
||||
"-DCMAKE_INSTALL_PREFIX=pybind11",
|
||||
"-DBUILD_TESTING=OFF",
|
||||
"-DPYBIND11_NOPYTHON=ON",
|
||||
"-Dprefix_for_pc_file=${pcfiledir}/../../",
|
||||
]
|
||||
if "CMAKE_ARGS" in os.environ:
|
||||
fcommand = [
|
||||
c
|
||||
for c in os.environ["CMAKE_ARGS"].split()
|
||||
if "DCMAKE_INSTALL_PREFIX" not in c
|
||||
]
|
||||
cmd += fcommand
|
||||
subprocess.run(cmd, check=True, cwd=DIR, stdout=sys.stdout, stderr=sys.stderr)
|
||||
subprocess.run(
|
||||
["cmake", "--install", tmpdir],
|
||||
check=True,
|
||||
cwd=DIR,
|
||||
stdout=sys.stdout,
|
||||
stderr=sys.stderr,
|
||||
)
|
||||
|
||||
# pkgconf-pypi needs pybind11/share/pkgconfig to be importable
|
||||
Path("pybind11/share/__init__.py").touch()
|
||||
Path("pybind11/share/pkgconfig/__init__.py").touch()
|
||||
|
||||
txt = get_and_replace(setup_py, version=version, extra_cmd=extra_cmd)
|
||||
code = compile(txt, setup_py, "exec")
|
||||
exec(code, {"SDist": SDist})
|
||||
@@ -3,16 +3,23 @@ from __future__ import annotations
|
||||
import contextlib
|
||||
import os
|
||||
import shutil
|
||||
import string
|
||||
import subprocess
|
||||
import sys
|
||||
import tarfile
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
from typing import Generator
|
||||
|
||||
# These tests must be run explicitly
|
||||
|
||||
DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
MAIN_DIR = os.path.dirname(os.path.dirname(DIR))
|
||||
DIR = Path(__file__).parent.resolve()
|
||||
MAIN_DIR = DIR.parent.parent
|
||||
|
||||
|
||||
# Newer pytest has global path setting, but keeping old pytest for now
|
||||
sys.path.append(str(MAIN_DIR / "tools"))
|
||||
|
||||
from make_global import get_global # noqa: E402
|
||||
|
||||
HAS_UV = shutil.which("uv") is not None
|
||||
UV_ARGS = ["--installer=uv"] if HAS_UV else []
|
||||
@@ -120,44 +127,44 @@ py_files = {
|
||||
}
|
||||
|
||||
headers = main_headers | conduit_headers | detail_headers | eigen_headers | stl_headers
|
||||
src_files = headers | cmake_files | pkgconfig_files
|
||||
all_files = src_files | py_files
|
||||
|
||||
generated_files = cmake_files | pkgconfig_files
|
||||
all_files = headers | generated_files | py_files
|
||||
|
||||
sdist_files = {
|
||||
"pybind11",
|
||||
"pybind11/include",
|
||||
"pybind11/include/pybind11",
|
||||
"pybind11/include/pybind11/conduit",
|
||||
"pybind11/include/pybind11/detail",
|
||||
"pybind11/include/pybind11/eigen",
|
||||
"pybind11/include/pybind11/stl",
|
||||
"pybind11/share",
|
||||
"pybind11/share/cmake",
|
||||
"pybind11/share/cmake/pybind11",
|
||||
"pybind11/share/pkgconfig",
|
||||
"pyproject.toml",
|
||||
"setup.cfg",
|
||||
"setup.py",
|
||||
"LICENSE",
|
||||
"MANIFEST.in",
|
||||
"README.rst",
|
||||
"PKG-INFO",
|
||||
"SECURITY.md",
|
||||
}
|
||||
|
||||
local_sdist_files = {
|
||||
".egg-info",
|
||||
".egg-info/PKG-INFO",
|
||||
".egg-info/SOURCES.txt",
|
||||
".egg-info/dependency_links.txt",
|
||||
".egg-info/not-zip-safe",
|
||||
".egg-info/top_level.txt",
|
||||
}
|
||||
|
||||
@contextlib.contextmanager
|
||||
def preserve_file(filename: Path) -> Generator[str, None, None]:
|
||||
old_stat = filename.stat()
|
||||
old_file = filename.read_text(encoding="utf-8")
|
||||
try:
|
||||
yield old_file
|
||||
finally:
|
||||
filename.write_text(old_file, encoding="utf-8")
|
||||
os.utime(filename, (old_stat.st_atime, old_stat.st_mtime))
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def build_global() -> Generator[None, None, None]:
|
||||
"""
|
||||
Build global SDist and wheel.
|
||||
"""
|
||||
|
||||
pyproject = MAIN_DIR / "pyproject.toml"
|
||||
with preserve_file(pyproject):
|
||||
newer_txt = get_global()
|
||||
pyproject.write_text(newer_txt, encoding="utf-8")
|
||||
yield
|
||||
|
||||
|
||||
def read_tz_file(tar: tarfile.TarFile, name: str) -> bytes:
|
||||
start = tar.getnames()[0] + "/"
|
||||
start = tar.getnames()[0].split("/")[0] + "/"
|
||||
inner_file = tar.extractfile(tar.getmember(f"{start}{name}"))
|
||||
assert inner_file
|
||||
with contextlib.closing(inner_file) as f:
|
||||
@@ -177,95 +184,58 @@ def test_build_sdist(monkeypatch, tmpdir):
|
||||
)
|
||||
|
||||
(sdist,) = tmpdir.visit("*.tar.gz")
|
||||
version = sdist.basename.split("-")[1][:-7]
|
||||
|
||||
with tarfile.open(str(sdist), "r:gz") as tar:
|
||||
start = tar.getnames()[0] + "/"
|
||||
version = start[9:-1]
|
||||
simpler = {n.split("/", 1)[-1] for n in tar.getnames()[1:]}
|
||||
(pkg_info_path,) = (n for n in simpler if n.endswith("PKG-INFO"))
|
||||
|
||||
setup_py = read_tz_file(tar, "setup.py")
|
||||
pyproject_toml = read_tz_file(tar, "pyproject.toml")
|
||||
pkgconfig = read_tz_file(tar, "pybind11/share/pkgconfig/pybind11.pc")
|
||||
cmake_cfg = read_tz_file(
|
||||
tar, "pybind11/share/cmake/pybind11/pybind11Config.cmake"
|
||||
)
|
||||
pkg_info = read_tz_file(tar, pkg_info_path).decode("utf-8")
|
||||
|
||||
assert (
|
||||
'set(pybind11_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include")'
|
||||
in cmake_cfg.decode("utf-8")
|
||||
)
|
||||
files = headers | sdist_files
|
||||
assert files <= simpler
|
||||
|
||||
files = {f"pybind11/{n}" for n in all_files}
|
||||
files |= sdist_files
|
||||
files |= {f"pybind11{n}" for n in local_sdist_files}
|
||||
files.add("pybind11.egg-info/entry_points.txt")
|
||||
files.add("pybind11.egg-info/requires.txt")
|
||||
assert simpler == files
|
||||
|
||||
with open(os.path.join(MAIN_DIR, "tools", "setup_main.py.in"), "rb") as f:
|
||||
contents = (
|
||||
string.Template(f.read().decode("utf-8"))
|
||||
.substitute(version=version, extra_cmd="")
|
||||
.encode("utf-8")
|
||||
)
|
||||
assert setup_py == contents
|
||||
|
||||
with open(os.path.join(MAIN_DIR, "tools", "pyproject.toml"), "rb") as f:
|
||||
contents = f.read()
|
||||
assert pyproject_toml == contents
|
||||
|
||||
simple_version = ".".join(version.split(".")[:3])
|
||||
pkgconfig_expected = PKGCONFIG.format(VERSION=simple_version).encode("utf-8")
|
||||
assert normalize_line_endings(pkgconfig) == pkgconfig_expected
|
||||
assert b'name = "pybind11"' in pyproject_toml
|
||||
assert "License-Expression: BSD-3-Clause" in pkg_info
|
||||
assert "License-File: LICENSE" in pkg_info
|
||||
assert "Provides-Extra: global" in pkg_info
|
||||
assert f'Requires-Dist: pybind11-global=={version}; extra == "global"' in pkg_info
|
||||
|
||||
|
||||
def test_build_global_dist(monkeypatch, tmpdir):
|
||||
monkeypatch.chdir(MAIN_DIR)
|
||||
monkeypatch.setenv("PYBIND11_GLOBAL_SDIST", "1")
|
||||
subprocess.run(
|
||||
[sys.executable, "-m", "build", "--sdist", "--outdir", str(tmpdir), *UV_ARGS],
|
||||
check=True,
|
||||
)
|
||||
with build_global():
|
||||
subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
"-m",
|
||||
"build",
|
||||
"--sdist",
|
||||
"--outdir",
|
||||
str(tmpdir),
|
||||
*UV_ARGS,
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
|
||||
(sdist,) = tmpdir.visit("*.tar.gz")
|
||||
|
||||
with tarfile.open(str(sdist), "r:gz") as tar:
|
||||
start = tar.getnames()[0] + "/"
|
||||
version = start[16:-1]
|
||||
simpler = {n.split("/", 1)[-1] for n in tar.getnames()[1:]}
|
||||
(pkg_info_path,) = (n for n in simpler if n.endswith("PKG-INFO"))
|
||||
|
||||
setup_py = read_tz_file(tar, "setup.py")
|
||||
pyproject_toml = read_tz_file(tar, "pyproject.toml")
|
||||
pkgconfig = read_tz_file(tar, "pybind11/share/pkgconfig/pybind11.pc")
|
||||
cmake_cfg = read_tz_file(
|
||||
tar, "pybind11/share/cmake/pybind11/pybind11Config.cmake"
|
||||
)
|
||||
pkg_info = read_tz_file(tar, pkg_info_path).decode("utf-8")
|
||||
|
||||
assert (
|
||||
'set(pybind11_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include")'
|
||||
in cmake_cfg.decode("utf-8")
|
||||
)
|
||||
files = headers | sdist_files
|
||||
assert files <= simpler
|
||||
|
||||
files = {f"pybind11/{n}" for n in all_files}
|
||||
files |= sdist_files
|
||||
files |= {f"pybind11_global{n}" for n in local_sdist_files}
|
||||
assert simpler == files
|
||||
|
||||
with open(os.path.join(MAIN_DIR, "tools", "setup_global.py.in"), "rb") as f:
|
||||
contents = (
|
||||
string.Template(f.read().decode())
|
||||
.substitute(version=version, extra_cmd="")
|
||||
.encode("utf-8")
|
||||
)
|
||||
assert setup_py == contents
|
||||
|
||||
with open(os.path.join(MAIN_DIR, "tools", "pyproject.toml"), "rb") as f:
|
||||
contents = f.read()
|
||||
assert pyproject_toml == contents
|
||||
|
||||
simple_version = ".".join(version.split(".")[:3])
|
||||
pkgconfig_expected = PKGCONFIG.format(VERSION=simple_version).encode("utf-8")
|
||||
assert normalize_line_endings(pkgconfig) == pkgconfig_expected
|
||||
assert b'name = "pybind11-global"' in pyproject_toml
|
||||
assert "License-Expression: BSD-3-Clause" in pkg_info
|
||||
assert "License-File: LICENSE" in pkg_info
|
||||
assert "Provides-Extra: global" not in pkg_info
|
||||
assert 'Requires-Dist: pybind11-global; extra == "global"' not in pkg_info
|
||||
|
||||
|
||||
def tests_build_wheel(monkeypatch, tmpdir):
|
||||
@@ -280,47 +250,94 @@ def tests_build_wheel(monkeypatch, tmpdir):
|
||||
|
||||
files = {f"pybind11/{n}" for n in all_files}
|
||||
files |= {
|
||||
"dist-info/LICENSE",
|
||||
"dist-info/licenses/LICENSE",
|
||||
"dist-info/METADATA",
|
||||
"dist-info/RECORD",
|
||||
"dist-info/WHEEL",
|
||||
"dist-info/entry_points.txt",
|
||||
"dist-info/top_level.txt",
|
||||
}
|
||||
|
||||
with zipfile.ZipFile(str(wheel)) as z:
|
||||
names = z.namelist()
|
||||
share = zipfile.Path(z, "pybind11/share")
|
||||
pkgconfig = (share / "pkgconfig/pybind11.pc").read_text(encoding="utf-8")
|
||||
cmakeconfig = (share / "cmake/pybind11/pybind11Config.cmake").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
(pkg_info_path,) = (n for n in names if n.endswith("METADATA"))
|
||||
pkg_info = zipfile.Path(z, pkg_info_path).read_text(encoding="utf-8")
|
||||
|
||||
trimmed = {n for n in names if "dist-info" not in n}
|
||||
trimmed |= {f"dist-info/{n.split('/', 1)[-1]}" for n in names if "dist-info" in n}
|
||||
|
||||
assert files == trimmed
|
||||
|
||||
assert 'set(pybind11_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include")' in cmakeconfig
|
||||
|
||||
version = wheel.basename.split("-")[1]
|
||||
simple_version = ".".join(version.split(".")[:3])
|
||||
pkgconfig_expected = PKGCONFIG.format(VERSION=simple_version)
|
||||
assert pkgconfig_expected == pkgconfig
|
||||
|
||||
assert "License-Expression: BSD-3-Clause" in pkg_info
|
||||
assert "License-File: LICENSE" in pkg_info
|
||||
assert "Provides-Extra: global" in pkg_info
|
||||
assert f'Requires-Dist: pybind11-global=={version}; extra == "global"' in pkg_info
|
||||
|
||||
|
||||
def tests_build_global_wheel(monkeypatch, tmpdir):
|
||||
monkeypatch.chdir(MAIN_DIR)
|
||||
monkeypatch.setenv("PYBIND11_GLOBAL_SDIST", "1")
|
||||
|
||||
subprocess.run(
|
||||
[sys.executable, "-m", "build", "--wheel", "--outdir", str(tmpdir), *UV_ARGS],
|
||||
check=True,
|
||||
)
|
||||
with build_global():
|
||||
subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
"-m",
|
||||
"build",
|
||||
"--wheel",
|
||||
"--outdir",
|
||||
str(tmpdir),
|
||||
*UV_ARGS,
|
||||
],
|
||||
check=True,
|
||||
)
|
||||
|
||||
(wheel,) = tmpdir.visit("*.whl")
|
||||
|
||||
files = {f"data/data/{n}" for n in src_files}
|
||||
files = {f"data/data/{n}" for n in headers}
|
||||
files |= {f"data/headers/{n[8:]}" for n in headers}
|
||||
files |= {f"data/data/{n}" for n in generated_files}
|
||||
files |= {
|
||||
"dist-info/LICENSE",
|
||||
"dist-info/licenses/LICENSE",
|
||||
"dist-info/METADATA",
|
||||
"dist-info/WHEEL",
|
||||
"dist-info/top_level.txt",
|
||||
"dist-info/RECORD",
|
||||
}
|
||||
|
||||
with zipfile.ZipFile(str(wheel)) as z:
|
||||
names = z.namelist()
|
||||
beginning = names[0].split("/", 1)[0].rsplit(".", 1)[0]
|
||||
|
||||
share = zipfile.Path(z, f"{beginning}.data/data/share")
|
||||
pkgconfig = (share / "pkgconfig/pybind11.pc").read_text(encoding="utf-8")
|
||||
cmakeconfig = (share / "cmake/pybind11/pybind11Config.cmake").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
|
||||
(pkg_info_path,) = (n for n in names if n.endswith("METADATA"))
|
||||
pkg_info = zipfile.Path(z, pkg_info_path).read_text(encoding="utf-8")
|
||||
|
||||
assert "License-Expression: BSD-3-Clause" in pkg_info
|
||||
assert "License-File: LICENSE" in pkg_info
|
||||
assert "Provides-Extra: global" not in pkg_info
|
||||
assert 'Requires-Dist: pybind11-global; extra == "global"' not in pkg_info
|
||||
|
||||
beginning = names[0].split("/", 1)[0].rsplit(".", 1)[0]
|
||||
trimmed = {n[len(beginning) + 1 :] for n in names}
|
||||
|
||||
assert files == trimmed
|
||||
|
||||
assert 'set(pybind11_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/include")' in cmakeconfig
|
||||
|
||||
version = wheel.basename.split("-")[1]
|
||||
simple_version = ".".join(version.split(".")[:3])
|
||||
pkgconfig_expected = PKGCONFIG.format(VERSION=simple_version)
|
||||
assert pkgconfig_expected == pkgconfig
|
||||
|
||||
@@ -15,3 +15,4 @@ scipy~=1.5.4; platform_python_implementation=="CPython" and python_version<"3.10
|
||||
scipy~=1.8.0; platform_python_implementation=="CPython" and python_version=="3.10" and sys_platform!="win32"
|
||||
scipy~=1.11.1; platform_python_implementation=="CPython" and python_version>="3.11" and python_version<"3.13" and sys_platform!="win32"
|
||||
scipy~=1.15.2; platform_python_implementation=="CPython" and python_version=="3.13" and sys_platform!="win32"
|
||||
tomlkit
|
||||
|
||||
33
tools/make_global.py
Executable file
33
tools/make_global.py
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env -S uv run -q
|
||||
|
||||
# /// script
|
||||
# dependencies = ["tomlkit"]
|
||||
# ///
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
import tomlkit
|
||||
|
||||
DIR = Path(__file__).parent.resolve()
|
||||
PYPROJECT = DIR.parent / "pyproject.toml"
|
||||
|
||||
|
||||
def get_global() -> str:
|
||||
pyproject = tomlkit.parse(PYPROJECT.read_text())
|
||||
del pyproject["tool"]["scikit-build"]["generate"]
|
||||
del pyproject["project"]["entry-points"]
|
||||
del pyproject["project"]["scripts"]
|
||||
del pyproject["tool"]["scikit-build"]["metadata"]["optional-dependencies"]
|
||||
pyproject["project"]["name"] = "pybind11-global"
|
||||
pyproject["tool"]["scikit-build"]["experimental"] = True
|
||||
pyproject["tool"]["scikit-build"]["wheel"]["install-dir"] = "/data"
|
||||
pyproject["tool"]["scikit-build"]["wheel"]["packages"] = []
|
||||
|
||||
result = tomlkit.dumps(pyproject)
|
||||
assert isinstance(result, str)
|
||||
return result
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(get_global())
|
||||
@@ -1,3 +0,0 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=42", "wheel"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
@@ -1,66 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Setup script for pybind11-global (in the sdist or in tools/setup_global.py in the repository)
|
||||
# This package is targeted for easy use from CMake.
|
||||
|
||||
import glob
|
||||
import os
|
||||
import re
|
||||
|
||||
# Setuptools has to be before distutils
|
||||
from setuptools import setup
|
||||
|
||||
from distutils.command.install_headers import install_headers
|
||||
|
||||
class InstallHeadersNested(install_headers):
|
||||
def run(self):
|
||||
headers = self.distribution.headers or []
|
||||
for header in headers:
|
||||
# Remove pybind11/include/
|
||||
short_header = header.split("/", 2)[-1]
|
||||
|
||||
dst = os.path.join(self.install_dir, os.path.dirname(short_header))
|
||||
self.mkpath(dst)
|
||||
(out, _) = self.copy_file(header, dst)
|
||||
self.outfiles.append(out)
|
||||
|
||||
|
||||
main_headers = glob.glob("pybind11/include/pybind11/*.h")
|
||||
conduit_headers = sum([glob.glob(f"pybind11/include/pybind11/conduit/*.{ext}")
|
||||
for ext in ("h", "txt")], [])
|
||||
detail_headers = glob.glob("pybind11/include/pybind11/detail/*.h")
|
||||
eigen_headers = glob.glob("pybind11/include/pybind11/eigen/*.h")
|
||||
stl_headers = glob.glob("pybind11/include/pybind11/stl/*.h")
|
||||
cmake_files = glob.glob("pybind11/share/cmake/pybind11/*.cmake")
|
||||
pkgconfig_files = glob.glob("pybind11/share/pkgconfig/*.pc")
|
||||
headers = main_headers + conduit_headers + detail_headers + eigen_headers + stl_headers
|
||||
|
||||
cmdclass = {"install_headers": InstallHeadersNested}
|
||||
$extra_cmd
|
||||
|
||||
# This will _not_ affect installing from wheels,
|
||||
# only building wheels or installing from SDist.
|
||||
# Primarily intended on Windows, where this is sometimes
|
||||
# customized (for example, conda-forge uses Library/)
|
||||
base = os.environ.get("PYBIND11_GLOBAL_PREFIX", "")
|
||||
|
||||
# Must have a separator
|
||||
if base and not base.endswith("/"):
|
||||
base += "/"
|
||||
|
||||
setup(
|
||||
name="pybind11_global",
|
||||
version="$version",
|
||||
packages=[],
|
||||
headers=headers,
|
||||
data_files=[
|
||||
(base + "share/cmake/pybind11", cmake_files),
|
||||
(base + "share/pkgconfig", pkgconfig_files),
|
||||
(base + "include/pybind11", main_headers),
|
||||
(base + "include/pybind11/conduit", conduit_headers),
|
||||
(base + "include/pybind11/detail", detail_headers),
|
||||
(base + "include/pybind11/eigen", eigen_headers),
|
||||
(base + "include/pybind11/stl", stl_headers),
|
||||
],
|
||||
cmdclass=cmdclass,
|
||||
)
|
||||
@@ -1,50 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Setup script (in the sdist or in tools/setup_main.py in the repository)
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
cmdclass = {}
|
||||
$extra_cmd
|
||||
|
||||
setup(
|
||||
name="pybind11",
|
||||
version="$version",
|
||||
download_url='https://github.com/pybind/pybind11/tarball/v$version',
|
||||
packages=[
|
||||
"pybind11",
|
||||
"pybind11.include.pybind11",
|
||||
"pybind11.include.pybind11.conduit",
|
||||
"pybind11.include.pybind11.detail",
|
||||
"pybind11.include.pybind11.eigen",
|
||||
"pybind11.include.pybind11.stl",
|
||||
"pybind11.share",
|
||||
"pybind11.share.cmake.pybind11",
|
||||
"pybind11.share.pkgconfig",
|
||||
],
|
||||
package_data={
|
||||
"pybind11": ["py.typed"],
|
||||
"pybind11.include.pybind11": ["*.h"],
|
||||
"pybind11.include.pybind11.conduit": ["*.h", "*.txt"],
|
||||
"pybind11.include.pybind11.detail": ["*.h"],
|
||||
"pybind11.include.pybind11.eigen": ["*.h"],
|
||||
"pybind11.include.pybind11.stl": ["*.h"],
|
||||
"pybind11.share.cmake.pybind11": ["*.cmake"],
|
||||
"pybind11.share.pkgconfig": ["*.pc"],
|
||||
},
|
||||
extras_require={
|
||||
"global": ["pybind11_global==$version"]
|
||||
},
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
"pybind11-config = pybind11.__main__:main",
|
||||
],
|
||||
"pipx.run": [
|
||||
"pybind11 = pybind11.__main__:main",
|
||||
],
|
||||
"pkg_config": [
|
||||
"pybind11 = pybind11.share.pkgconfig",
|
||||
],
|
||||
},
|
||||
cmdclass=cmdclass
|
||||
)
|
||||
Reference in New Issue
Block a user