Packaging and native-wheel policy
Why setuptools remains the build backend
A scikit-build-core/CMake migration would require translating a mature Makefile that carries qualification-sensitive compiler flags, per-translation-unit floating-point controls, RPATH behavior, CFITSIO linking, and the standalone shared-production architecture. Milestone 8 therefore chooses the lower-risk path: retain setuptools and formalize the existing Makefile build as an isolated wheel-build step.
A future CMake migration should be treated as its own science-neutral build refactor with exact native product qualification.
Native wheel construction
The build hook:
builds normal Python modules/package data;
evaluates
XSTAR_TOOLS_NATIVE;validates platform-native build prerequisites;
copies the self-contained
src/xstar_tools/xstar/cpp/tree to a temporary staging directory;runs
make cleanand then the retainedmake allthere;verifies every required runtime artifact exists;
copies only runtime binaries/libraries to the wheel build tree;
writes
native_build.jsonwith package/science/ABI/build provenance.
This design prevents old .o/.so files in a checkout from entering a wheel.
PyPI Linux release profile (0.6.89.2, closures through 0.6.89.2.2)
The 0.6.89.2.1 workflow first installs the declared PEP 517 build-backend requirements (setuptools>=77 and wheel) into the qualification interpreter before importing build_support.py. 0.6.89.2.2 additionally maps the pypi-linux packaging profile to a dedicated make pypi-linux target so the standalone Python-embedding plugin is never built in the release-wheel path; ordinary make all remains unchanged. Public Linux release wheels are produced with cibuildwheel in a manylinux_2_28_x86_64 container and repaired with auditwheel. CFITSIO 4.6.2 is built from a pinned official source archive inside the container and its runtime library is vendored into the repaired wheel.
XSTAR_TOOLS_NATIVE_PROFILE=pypi-linux changes only the staged binary payload: it omits libxstar_backend_python.so, whose standalone embedding contract links libpythonX.Y and therefore is not a valid portable manylinux dependency. The default full profile used by ordinary source/native installations is unchanged. The PyPI profile still contains the public C API, production-zone library, modular C++ libraries, xstar-cpp, and all non-MPI XSTAR2XSPEC executables.
The clean installed-wheel test exercises zone-cpp, so omission of the embedding plugin does not weaken the Python-to-native production path.
Cross-platform PyPI release closure (0.6.89.5)
0.6.89.5 — PYPI_CROSS_PLATFORM_RELEASE_CLOSURE does not introduce a new science or native-runtime implementation. It advances package/version metadata and rebuilds the already-qualified pypi-linux, pypi-macos, and pypi-windows profiles under one version. The release workflow uses GitHub-hosted runners and produces exactly 24 native wheels plus one sdist:
6 CPython 3.9–3.14
manylinux_2_28_x86_64wheels;6 CPython 3.9–3.14
macosx_11_0_arm64wheels;6 CPython 3.9–3.14
macosx_11_0_x86_64wheels;6 CPython 3.9–3.14
win_amd64wheels;1
xstar_tools-0.6.89.5.tar.gzsource distribution.
The aggregate gate rejects extra or missing distributions and specifically rejects a py3-none-any control wheel from the publication set. Each native wheel is clean-install tested by cibuildwheel on its platform before aggregation. The final aggregate job runs twine check and writes SHA-256 checksums. Publication itself remains a separate deliberate action so the same qualified bundle can be sent first to TestPyPI and then to PyPI.
No local Mac or Windows machine is required for release construction: macOS arm64/x86_64 and Windows AMD64 are built and tested on the corresponding GitHub-hosted runners.
Wheel contents
Normal wheels include only installed Python modules plus required runtime data:
compact benchmark/reference fixtures still consumed by current tests/runtime;
coheat.dat;constants.def;public C/production-zone ABI headers;
built native runtime artifacts on native wheels;
native_build.json.
They exclude:
generated/history-only material that is not part of the active release contract;
documentation source;
tests and qualification reports;
C++ implementation
.cppfiles and Makefile;object files, caches, and source-tree build products;
atdb.fits.
The sdist retains source/build/qualification material required to reproduce and validate a build, while still pruning the top-level historical archive.
Data policy
atdb.fits is external scientific data. It is not bundled and is never fetched
silently during a run. Installed packages store configured data paths under the
user configuration directory (normally ~/.config/xstar-tools/datapath) and
use a user data default (normally ~/.local/share/xstar-tools) rather than
writing into site-packages.
Release checks
Packaging CI must perform the equivalent of:
python -m build
python -m twine check dist/*
pip install dist/*.whl
xstar-tools doctor
Native Linux jobs additionally run:
xstar-cpp --abi
xstar-tools doctor --require zone-cpp
Clean-wheel characterization tests verify import/API/CLI behavior and wheel payload policy without relying on the source checkout.
Persistent release-build staging
For constrained release builders, XSTAR_TOOLS_NATIVE_BUILD_DIR=/path enables a
persistent staging directory. The hook fingerprints the complete native source
plus pyproject.toml and automatically discards the staging tree if that
fingerprint changes. This allows long qualified translation units to be built
incrementally without ever consuming unchecked object files from the source
checkout. Normal builds do not set this variable and use a temporary clean
stage.
Conda packaging
The conda-forge recipe reuses this same build hook and native capability policy; see Conda and conda-forge packaging.
Windows delvewheel in-wheel dependency resolution
For the pypi-windows profile, XSTAR DLLs are already packaged under xstar_tools/xstar/cpp. The repair command intentionally uses --ignore-existing together with --analyze-existing --analyze-existing-exes: the first enables resolution of DLLs already inside the wheel and keeps those XSTAR DLLs in place; the analysis flags still discover external CFITSIO and MinGW runtime dependencies for vendoring. The external search path remains XSTAR_TOOLS_WINDOWS_DLL_PATH.