Skip to content

goccy/python-wasm

Repository files navigation

python-wasm

wasmify project that compiles CPython to wasm32-wasip1 and emits the pure-Go (wasm2go) bindings go-python consumes.

Outputs

The CI workflow at .github/workflows/build.yml and the local make wasm target both produce, from a clean checkout:

File Where What
python.wasm .wasmify/wasm-build/output/python.wasm The wasi-sdk-built CPython interpreter (thin embedding API in py.cc), optimised by binaryen wasm-opt.
python_wasm2go.tar.gz build/wasm2go/internal/wasm2go/ The transpiled pure-Go bundle, a self-contained Go module (github.com/goccy/pythonwasm2go). go-python downloads and extracts it.
python_wasm2go.go build/wasm2go/python.go protoc-gen-wasmify-go's wasm2go bridge.
python_stdlib.zip generated by scripts/make-stdlib-zip.py Trimmed CPython Lib/ tree (pure-Python stdlib), locked to the pinned cpython submodule version. go-python embeds it as the interpreter's module search path.

Everything above is regenerated on every build; only the inputs below are committed.

Committed inputs

wasmify.json            # wasmify decisions: project metadata, build_commands, bridge config
cpython/                # git submodule pinned to the upstream commit we build against
buf.yaml                # buf module
buf.gen.yaml            # protoc-gen-wasmify-go invocation (wasm2go bundle)
proto/wasmify/          # wasmify proto options the generated proto imports
py.cc, py.h             # the thin C++ embedding API (py_new / py_eval / ...) exported to the bridge
patches/                # CPython source patches (host-provided posix_spawn)
scripts/wasi-configure.sh   # the CPython-specific configure phase (host build-python + wasm cross-configure + pyconfig patches)

Everything else (build.json, api-spec.json, proto/python.proto, bridge/, build/, python.wasm) is in .gitignore and reproduced by make wasm.

Building locally

The full pipeline runs inside a wasmify image bundling wasi-sdk, binaryen, buf, and the wasmify CLI — you install none of those on your host:

make wasm                              # uses ghcr.io/goccy/wasmify:v0.4.5
make wasm DOCKER_PLATFORM=linux/amd64  # on Apple Silicon (the image is amd64-only)
make wasm-clean                        # drop regenerated outputs, keep committed inputs

make wasm runs (under docker run --rm -v $PWD:/work …) the same sequence as CI. Unlike a bazel project, CPython needs a configure phase first:

make tools                  # ensure wasi-sdk (pre-baked in the image)
scripts/wasi-configure.sh   # host build-python + wasm cross-configure + pyconfig patches
wasmify build               # replay the captured `make` (CPython wasi cross-build)
wasmify generate-build      # build.log -> build.json
wasmify parse-headers       # py.h -> api-spec.json
wasmify gen-proto           # api-spec.json -> proto/ + bridge/
wasmify wasm-build \
    --with-bridge --optimize    # build.json + bridge -> python.wasm + wasm-opt
buf generate                # proto/ -> build/wasm2go/ (the wasm2go bundle)
make bundle-gomod           # stamp the bundle's go.mod

CI

.github/workflows/build.yml runs the same pipeline inside the wasmify image on push to main, v* tags, and workflow_dispatch. It uploads the artefacts, attaches actions/attest-build-provenance SLSA attestations, and on a version tag publishes python.wasm, python_wasm2go.go, python_wasm2go.tar.gz, python_wasm2go.sha256, and python_stdlib.zip as Release assets.

About

No description, website, or topics provided.

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors