-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpyproject.toml
More file actions
260 lines (249 loc) · 16.8 KB
/
Copy pathpyproject.toml
File metadata and controls
260 lines (249 loc) · 16.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# Root build adapter so `pip wheel .` / cibuildwheel can build the cvista wheel.
#
# cvista is a hard-fork of VTK 9.6.2 and is NOT a normal PEP-517 project: VTK only
# emits a setup.py INSIDE the cmake build tree (VTK_WHEEL_BUILD), after a full C++
# configure+build. The in-tree backend ci/cibw/cvista_backend.py bridges that:
# build_wheel() runs cmake configure (-C ci/cmake/linux.cmake) -> cmake --build ->
# the generated build-tree `setup.py bdist_wheel`, then hands the wheel to pip.
#
# This file exists ONLY to drive wheel builds (CI / cibuildwheel). There is no
# `pip install .` source-dist path (build_sdist raises) — that is intentional.
[build-system]
# setuptools_scm derives the tag-driven version (see [tool.setuptools_scm] and
# cvista_backend._version_suffix). cmake + ninja must already be on PATH (CIBW_BEFORE_ALL
# installs them); they are NOT listed here because pip would then try to build them
# into the isolated build env, and we want the system/CIBW-provided ones that match
# the toolchain.
requires = ["setuptools<81", "wheel", "setuptools_scm>=8"]
build-backend = "cvista_backend"
backend-path = ["ci/cibw"]
# Tag-driven PyPI versioning (start at 9.6.2.0). The base is pinned to the VTK
# version this fork is a drop-in for (9.6.2); git tags add a 4th release segment
# (the cvista iteration), so a release tagged `9.6.2.0` publishes `cvista 9.6.2.0`,
# `9.6.2.1`, etc. The 4th segment is a normal PEP 440 release component (NOT a
# .post — cvista ships code changes, and a real release segment also unlocks
# publishable RCs like `9.6.2.1rc1`). See docs/versioning.md for the full scheme.
# cvista_backend reads this via setuptools_scm.get_version() and feeds the suffix
# (everything past `9.6.2.`) to VTK's setup.py.in as VTK_VERSION_SUFFIX. Commits
# between tags get `9.6.2.N.devM` (never published — publish runs only on a
# release tag). local_scheme = no-local-version keeps dev versions PyPI-clean.
[tool.setuptools_scm]
version_scheme = "guess-next-dev"
local_scheme = "no-local-version"
fallback_version = "9.6.2.0.dev0"
[project]
name = "cvista"
# VTK's generated setup.py computes the real version (9.6.2[.devN]) from the
# build tree; this static value only satisfies pip's pre-build metadata peek and
# is overwritten by the wheel the backend actually produces.
version = "9.6.2"
description = "cvista — trimmed PyVista-parity hard-fork of VTK 9.6.2 (vtkmodules renamed to top-level cvista)"
# Floor is 3.10 (NOT 3.12) so cibuildwheel will SELECT cp310/cp311 for the
# additive legacy versioned-wheel line (.github/workflows/wheels-legacy.yml).
# cibuildwheel intersects its `build`/CIBW_BUILD selector with this metadata
# floor, so a 3.12 floor here silently dropped every cp310/cp311 identifier
# ("No build identifiers selected"). The shipped cp312-abi3 path is UNAFFECTED:
# ci.yml + wheels-cibuildwheel.yml + [tool.cibuildwheel].build all pin
# cp312-*/cp313-*/cp314-*, so the abi3 build still selects only 3.12+. This is
# pip's pre-build metadata peek only; the real wheel metadata is computed by
# VTK's generated build-tree setup.py, so lowering the floor does not alter what
# the abi3 wheel ships.
requires-python = ">=3.10"
# ===========================================================================
# cibuildwheel — Linux manylinux_2_28 (glibc 2.28, AlmaLinux 8, GCC 14.2.1). The
# 2_28 image is the single biggest cold-CI lever: its GCC>=12 toolchain ACTIVATES
# the GCC<12-gated unity levers (CVISTA_SOURCE_UNITY + CVISTA_WRAP_UNITY) and the
# array-TU split, which are inert on the old manylinux2014/GCC-10.2.1 image. One
# C++ build is shared across the cp matrix via ccache. NOTE: 2_28 raises the glibc
# floor from 2.17 to 2.28 — wheels no longer install on glibc<2.28 (CentOS7/RHEL7,
# Ubuntu<18.10, Debian<10); stock vtk==9.6.2 still ships manylinux_2_17. This is
# the deliberate tradeoff for the ~modern-GCC build speedup.
# ===========================================================================
[tool.cibuildwheel]
build-frontend = "pip"
# SINGLE-WHEEL matrix (Python 3.11 dropped, maintainer directive). The backend
# (ci/cibw/cvista_backend.py) builds ONE abi3 wheel tagged cp312-abi3
# (Py_LIMITED_API 0x030c0000) that installs + imports on CPython 3.12+ including
# future minors. 3.12 is the abi3 floor: PyMemberDef + the Py_T_*/Py_READONLY
# member constants the heap-type wrappers emit only entered the stable ABI in 3.12
# (gh-93274), so 3.12 is the lowest possible stable-ABI target — and now the
# minimum supported Python. We list cp312-* cp313-* cp314-*; cibuildwheel's abi3
# dedup means cp313/cp314 do NOT rebuild — they reuse and TEST the cp312-abi3
# wheel — so the matrix yields exactly ONE build and ONE wheel. Set CVISTA_ABI3=0
# to force a legacy per-version static wheel (escape hatch, reversible).
build = "cp312-* cp313-* cp314-*"
skip = "*-musllinux_*"
test-command = "CVISTA_IMPORT_NAME=cvista xvfb-run -a -s '-screen 0 1280x1024x24' python {project}/ci/smoke_test.py"
# auditwheel repair runs by default; stamp the 2_28 tag explicitly to match the
# manylinux_2_28 build image (AlmaLinux 8 / glibc 2.28). --strip removes the
# ELF .symtab (local/debug symbols) from the bundled .so's — the shipped build
# never stripped them, leaving ~47 MB of symbol tables (≈6 MB / 15% of the
# COMPRESSED wheel: 39→33 MB measured). Bit-exact-safe: only symbol metadata is
# dropped; .dynsym + the abi3 PyInit entry points stay, so the wheel imports and
# computes byte-identically (the bit-exact + pixel-exact gates run on this wheel).
repair-wheel-command = "python ci/cibw/repair_linux.py {dest_dir} {wheel}"
# NOTE on abi3audit: cibuildwheel >=4.0 auto-runs `abi3audit --strict` on
# abi3-tagged wheels and FAILS the build on any non-abi3 symbol. cvista's cp312-abi3
# modules export the wrapper runtime's OWN cross-module symbols (PyVTKObject_New,
# PyVTKEnum_Add, ...) shared between cvista's own .so files — abi3audit reports these
# as "violations" even though it also confirms the wheel is baseline-3.12-compatible
# (is_abi3_baseline_compatible=true, computed=3.12). They are NOT CPython limited-API
# violations (the wheel genuinely loads on 3.12+, verified by the bitexact/render
# gates). The pinned cibuildwheel here is 3.1.4, which does NOT run abi3audit at all,
# so nothing to override. If/when bumping to cibuildwheel >=4.0, set the audit to
# non-strict via the env knob CIBW_AUDIT_COMMAND="abi3audit --report {wheel}" (the
# `audit-command` pyproject key does not exist in 3.1.4 and 3.1.4 rejects unknown
# keys, so it must NOT be added here until the cibuildwheel pin is >=4.0).
[tool.cibuildwheel.linux]
# manylinux_2_28 == glibc 2.28 == AlmaLinux 8.10, system GCC 14.2.1 + gold on PATH.
# GCC 14 (>=12) activates the unity + array-split build-time levers (inert on the
# old manylinux2014/GCC-10.2.1 image).
manylinux-x86_64-image = "quay.io/pypa/manylinux_2_28_x86_64"
# Pin the aarch64 image to the matching glibc 2.28 floor too, so an aarch64 build
# (a runner that sets CIBW_ARCHS=aarch64) uses the same manylinux policy.
manylinux-aarch64-image = "quay.io/pypa/manylinux_2_28_aarch64"
archs = ["x86_64"]
# CIBW_BEFORE_ALL runs ONCE in the build container before the cp matrix: install
# the rendering stack (system mesa = GL backend) + ccache + ninja + xvfb. The
# AlmaLinux 8 package names are identical to the el7 set (verified: all 13 install
# from the stock 2_28 repos, no EPEL/CRB enable needed); only the package manager
# is dnf (yum is a dnf alias on AlmaLinux 8, but call dnf explicitly).
before-all = [
# mold = the fast ELF linker the build defaults to (CVISTA_FAST_LINKER=mold);
# lld is the validated fallback. Both install from the stock 2_28 repos (no
# EPEL): mold 2.40, lld 21.1 verified on quay.io/pypa/manylinux_2_28_x86_64.
"dnf install -y mesa-libGL-devel mesa-libEGL-devel mesa-libOSMesa-devel mesa-libGLU-devel libglvnd-devel libX11-devel libXcursor-devel libXt-devel libXext-devel mesa-dri-drivers xorg-x11-server-Xvfb ccache git mold lld",
# before-all runs as root; the build runs as a non-root user, so make the
# in-container ccache dir world-writable up front.
"mkdir -p /ccache && chmod 0777 /ccache",
]
# Per-leg: pip provides cmake>=3.22 + ninja>=1.11 (el7 ninja 1.10 can't do VTK's
# multiple-output wrapping edges). Installed before each `pip wheel` so they are
# on PATH for the backend's cmake calls.
before-build = "{project}/ci/cibw/before-build.sh"
[tool.cibuildwheel.linux.environment]
# ccache shared across the abi3 dedup: cibuildwheel keeps ONE container alive for
# the whole linux matrix, so an in-container CCACHE_DIR persists across legs
# automatically. This is the crux — VTK's C++ is python-independent, so the
# cp313/cp314 dedup legs (and re-runs) hit the cache and only recompile the abi3
# wrappers. For that to actually happen the C++ compile commands must be
# byte-identical across legs, which is why cvista_backend uses ONE constant build dir
# (build-cibw-abi3 shared by cp312/313/314) rather than a per-SOABI one: the build
# path is embedded in every TU's -I generated-header flags, so a name that varied
# would change the cache key and miss on the C++.
# (/output is a
# cibuildwheel-managed in-container dir that survives the matrix; we use a plain
# /tmp path the build user owns to avoid host-mount uid/permission friction.)
CCACHE_DIR = "/ccache"
CCACHE_MAXSIZE = "30G"
CMAKE_C_COMPILER_LAUNCHER = "ccache"
CMAKE_CXX_COMPILER_LAUNCHER = "ccache"
# Cross-leg cache robustness. The backend now uses ONE constant build tree
# (cvista_backend._build_dir), so the C++ object compile commands are byte-identical
# across legs and ccache hits. These three harden that against the remaining ways a
# path/time can leak into a TU and bust an otherwise-identical object:
# CCACHE_BASEDIR — rewrite absolute paths under the repo to relative in the
# hash, so a build run from a different checkout dir still hits.
# CCACHE_SLOPPINESS=time_macros — VTK bakes __DATE__/__TIME__ into a few banner
# TUs; without this every rebuild misses on them. (locale +
# pch_defines are the standard safe companions.)
# NOHASHDIR is intentionally NOT set: with a constant build dir the directory is
# already identical across legs, and NOHASHDIR would weaken debug-path correctness
# for no extra hit.
# NOTE: cibuildwheel does NOT expand the {project} token inside environment values
# (only in before-build/test-command), so this literal "{project}" reaches the
# build env unexpanded. cvista_backend._fix_ccache_basedir() resolves it to the real
# checkout root (REPO) before invoking cmake, so ccache sees a valid absolute path.
CCACHE_BASEDIR = "{project}"
CCACHE_SLOPPINESS = "time_macros,locale,pch_defines"
# CVISTA_BUILD_JOBS is intentionally NOT pinned here: the backend defaults the
# `cmake --build --parallel` width to os.cpu_count() (ci/cibw/cvista_backend.py
# _jobs()), so the compile auto-scales to whatever runner it lands on — a
# blacksmith-16vcpu runner runs 16 jobs, a 32vcpu runs 32, github's 4-core
# ubuntu-latest runs 4 — with no per-runner core count baked into the repo. To
# force a specific width (e.g. oversubscription) set CVISTA_BUILD_JOBS in the
# workflow env or as an org/repo variable; leave it unset to track the runner.
# OPTIONAL cross-RUN persistence: mount a host dir at /ccache. NOT enabled by
# default because cibuildwheel runs the build as a non-root user whose uid differs
# from the host dir owner, so a host-owned dir trips "Permission denied" on
# ccache's mkdir. To persist across runs on CI, create a world-writable dir and add:
# container-engine = { name = "docker", create-args = ["-v", "/tmp/cvista-cibw-ccache:/ccache"] }
# (chmod 0777 it first). Within a SINGLE run the in-container /ccache already gives
# the cross-cp matrix sharing that matters; cross-run is a CI cache-action nicety.
# ===========================================================================
# macOS arm64 — AppleClang + ThinLTO + Cocoa GL (ci/cmake/macos.cmake). The SAME
# cvista_backend + minimal.cmake 3-way toolchain gate; only the init-cache + repair
# tool + env differ. delocate is cibuildwheel's default macOS repair tool.
# ===========================================================================
[tool.cibuildwheel.macos]
archs = ["arm64"]
# ccache is NOT on PyPI (no wheel) — install it via Homebrew (preinstalled on the
# macos-14 runner). cmake/ninja/setuptools/wheel come from pip into the build env.
before-build = "brew install ccache && python -m pip install 'cmake>=3.22,<4.2' 'ninja>=1.11' 'setuptools<81' wheel"
# delocate-wheel bundles the dylibs but does NOT strip symbols; repair_macos.py
# runs delocate then strips local symbol tables (strip -x) + re-signs ad-hoc,
# mirroring the Linux `auditwheel repair --strip` size win. Set CVISTA_STRIP=0 to
# fall back to a plain delocate repair.
repair-wheel-command = "python ci/cibw/repair_macos.py {delocate_archs} {dest_dir} {wheel}"
# macOS ships a native Cocoa GL backend with no headless display on CI, so the
# global xvfb offscreen-render smoke is Linux-only. Use the minimal import+compute
# smoke (no render, no xvfb) instead.
test-command = "python {project}/ci/smoke_min.py"
[tool.cibuildwheel.macos.environment]
# REPO-relative (NOT "{project}/..."): cibuildwheel does not expand {project}
# inside environment values, only in before-build/test-command. The backend
# (ci/cibw/cvista_backend.py _init_cache) resolves this against the repo root.
CVISTA_CMAKE_INIT = "ci/cmake/macos.cmake"
CVISTA_TARGET_OS = "macos"
MACOSX_DEPLOYMENT_TARGET = "11.0"
_PYTHON_HOST_PLATFORM = "macosx-11.0-arm64"
CMAKE_C_COMPILER_LAUNCHER = "ccache"
CMAKE_CXX_COMPILER_LAUNCHER = "ccache"
# ===========================================================================
# Windows x86_64 — MSVC /GL+/LTCG (ci/cmake/windows.cmake). delvewheel repair.
# vcvars MUST be on PATH, set up in the workflow via ilammy/msvc-dev-cmd BEFORE
# cibuildwheel. Do NOT rely on cibuildwheel's MSVC autodetection: it puts
# cl/link on PATH but NOT the SDK resource toolchain (rc.exe / mt.exe), so the
# Ninja compiler probe fails its link step ("RC Pass 1: no such file or
# directory", CMAKE_MT-NOTFOUND). Every Windows-building workflow runs that step.
# ===========================================================================
[tool.cibuildwheel.windows]
archs = ["AMD64"]
before-build = "pip install delvewheel \"cmake>=3.22,<4.2\" \"ninja>=1.11\" \"setuptools<81\" wheel"
# cvista builds with VTK_ENABLE_KITS=ON: every DLL a .pyd imports (kit DLLs like
# vtkRendering / vtkFilters, standalone module DLLs like vtkChartsCore, and the
# vendored third-party DLLs) is a real file in the build tree's bin/ dir, but
# VTK's Windows wheel layout does NOT copy them beside the .pyds (it leaves that
# to delvewheel). That bin/ dir is not on PATH when delvewheel runs, so a plain
# `delvewheel repair` fails with "Unable to find library: vtkchartscore-...dll".
# repair_windows.py globs the per-leg build-cibw*/bin dirs and feeds them to
# delvewheel via --add-path so every needed DLL resolves in one pass.
# NOTE: cibuildwheel does NOT expand {project} in repair-wheel-command (only
# {wheel}/{dest_dir} are substituted, unlike before-build/test-command). It runs
# this command with cwd == the project root, so we use a repo-relative script
# path and pass "." for the project arg (the script resolves it to an abspath).
repair-wheel-command = "python ci/cibw/repair_windows.py . {dest_dir} {wheel}"
# Windows ships the native Win32 WGL backend with no headless display on CI, so
# the global xvfb offscreen-render smoke is Linux-only. Use the minimal
# import+compute smoke (no render, no xvfb) instead.
test-command = "python {project}/ci/smoke_min.py"
# Test the abi3 wheel only on its BUILD interpreter (cp312) on Windows. The
# single cp312-abi3 wheel BUILDS, repairs (delvewheel) and imports+computes
# cleanly on cp312 — which is exactly what this leg exists to prove ("the wheel
# BUILDS + imports on its native platform"; the numeric/pixel gates are
# Linux-only). It does NOT yet import on cp313/cp314 on Windows: a Python-using
# DLL still carries a python3XX.dll dependency (MSVC links the version import lib
# python312.lib instead of the stable-ABI stub python3.lib for that module), and
# delvewheel correctly does not vendor the interpreter DLL, so the load fails on a
# different minor. This is a Windows-ONLY gap — the abi3 cross-version promise is
# already gated on Linux (the bitexact job installs the one abi3 wheel on BOTH
# py3.12 and py3.13) and macOS extensions use dynamic lookup (no version dep).
# Windows wheels are not shipped today. TODO(win-abi3-xver): make every
# Python-using module link Python3::SABIModule (python3.lib) so the Windows wheel
# is cross-version, then drop this skip.
test-skip = "cp313-* cp314-*"
[tool.cibuildwheel.windows.environment]
# REPO-relative (see the macos table note): {project} is not expanded in env
# values. The backend resolves this against the repo root.
CVISTA_CMAKE_INIT = "ci/cmake/windows.cmake"
CVISTA_FORCE_MSVC = "ON"