z3 already builds under Pyodide, but via `pyodide build` the resulting
wheel is tagged `emscripten_<pyodide-version>_wasm32` and only usable as a
CI artifact. PEP 783 introduced the portable `pyemscripten_<date>_wasm32`
tag that PyPI accepts and micropip can install at runtime. This makes z3
produce that wheel via `cibuildwheel --platform pyodide`.
Changes:
* setup.py: for the emscripten target, use the wheel platform tag that
pyodide-build supplies verbatim via _PYTHON_HOST_PLATFORM (e.g.
`pyemscripten_2026_0_wasm32`) instead of reconstructing an
`emscripten_*` tag, falling back to the old behaviour when that env var
is absent.
* setup.py / CMakeLists.txt / pyproject.toml: switch the Pyodide build
from JS-based exceptions (`-fexceptions`, `-sDISABLE_EXCEPTION_CATCHING=0`)
to native wasm exception handling (`-fwasm-exceptions
-sSUPPORT_LONGJMP=wasm`), matching the ABI of the Pyodide 314 /
emscripten 5 main module. With the old flags libz3.so imports `invoke_*`
trampolines the runtime no longer provides, so the wheel builds but the
first Z3 call fails at runtime with
"Dynamic linking error: cannot resolve symbol invoke_vi".
* pyproject.toml: add [tool.cibuildwheel] / [tool.pyodide.build] config so
`cibuildwheel --platform pyodide` builds and tests the wheel.
* add .github/workflows/pyodide-pypi.yml building the wheel with
cibuildwheel and publishing it to PyPI (trusted publishing) on tags. The
existing pyodide.yml artifact build is left unchanged.
Verified with cibuildwheel 4.1.0 / pyodide-build 0.35.0 / emscripten 5.0.3:
the resulting z3_solver-4.17.0.0-py3-none-pyemscripten_2026_0_wasm32.whl
passes z3test.py in the Pyodide runtime and solves SMT problems both under
node and in a browser via micropip.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>