From a6e370ac5ecb3b8f8360db18f219b64845b25f77 Mon Sep 17 00:00:00 2001 From: Gyeongjae Choi Date: Tue, 24 Mar 2026 16:54:04 +0900 Subject: [PATCH 1/8] Add index --- docs/DOCUMENTATION_PLAN.md | 436 +++++++++++++++++++++++++++++++++++++ docs/conf.py | 5 + docs/index.md | 143 ++++++++++++ docs/index.rst | 18 -- docs/requirements-doc.txt | 1 + 5 files changed, 585 insertions(+), 18 deletions(-) create mode 100644 docs/DOCUMENTATION_PLAN.md create mode 100644 docs/index.md delete mode 100644 docs/index.rst diff --git a/docs/DOCUMENTATION_PLAN.md b/docs/DOCUMENTATION_PLAN.md new file mode 100644 index 00000000..ac8eccd6 --- /dev/null +++ b/docs/DOCUMENTATION_PLAN.md @@ -0,0 +1,436 @@ +# pyodide-build Documentation Plan + +> Status: Draft +> Last updated: 2026-03-24 + +## Background + +pyodide-build has virtually no user-facing documentation. The `docs/` directory contains an empty Sphinx skeleton, and the README is 12 lines. Relevant content currently lives on pyodide.org (scattered across the Pyodide project docs) — this will be migrated here, and pyodide.org will link to these docs instead. + +This plan proposes a comprehensive documentation structure for pyodide-build as the **canonical source** for all package building documentation, following the [Diataxis framework](https://diataxis.fr/) (tutorials, how-to guides, reference, explanation). + +### Target Audience + +**Primary**: Python package maintainers who want their package to work in Pyodide/WebAssembly. +**Secondary**: Pyodide ecosystem contributors who author recipes. + +pyodide-build docs are the **canonical home** for everything related to building, testing, and publishing Python packages for Pyodide. pyodide.org will link here for build-related content. + +### Guiding Principles + +1. **This is the canonical source** — All package building docs live here. Existing content on pyodide.org (building packages, out-of-tree builds, meta.yaml spec, CLI reference) will be migrated here, and pyodide.org will link to these docs instead. +2. **Lead with the happy path** — Quickstart should be 4 commands with a working result. +3. **Explain the "why" before the "how"** — Concepts page before CLI reference. +4. **Real-world examples** — Use NumPy, pandas, matplotlib configs as proof points, not hypothetical examples. +5. **Progressive disclosure** — 80% of users need Getting Started + CI guide + Publishing. The rest serves progressively smaller audiences. + +--- + +## Document Structure + +### Part I — Getting Started + +#### 1. Overview (`index.md`) + +The landing page. Sets expectations and orients the reader. + +- What is pyodide-build? (one paragraph: "the `python -m build` for WebAssembly") +- Who is this for? (Python package maintainers, not Pyodide end-users) +- Ecosystem map diagram: pyodide-build -> pyodide-cli -> Emscripten -> Pyodide runtime +- Quick links to the three main workflows: Build -> Test -> Ship + +#### 2. Installation (`getting-started/installation.md`) + +- `pip install pyodide-build` (also: `pipx install`, `uv tool install`, `uvx`) +- Version requirements: Python >= 3.12, Node.js (for venv testing) +- Verify installation: `pyodide --version` +- Optional extras: `pip install pyodide-build[resolve]` for dependency resolution + +#### 3. Concepts (`getting-started/concepts.md`) + +Explain the mental model before showing commands. This addresses a major user pain point — people don't understand what xbuildenv is or why they need Emscripten. + +- **Why cross-compilation?** Python packages with C extensions must be compiled for the target platform. Pyodide's target is Emscripten/WebAssembly. +- **The cross-build environment (xbuildenv)**: pre-built CPython headers, sysconfig data, and package stubs. Analogous to a sysroot in cross-compilation. +- **Emscripten SDK**: the compiler toolchain that turns C/C++ into WebAssembly. Managed automatically by pyodide-build. +- **Platform tags**: `pyemscripten_2025_0_wasm32` — what each part means, ABI versioning, the PEP 783 specification. +- **Side-by-side comparison**: `python -m build` vs `pyodide build` — what's the same, what's different. + +#### 4. Quick Start (`getting-started/quickstart.md`) + +The "5-minute" path. Build a package with a C extension for Pyodide. + +- Callout: **Pure-Python packages don't need pyodide-build.** A pure-Python wheel built with `python -m build` (or any standard build frontend) is already compatible with Pyodide — no special tooling required. pyodide-build is for packages that contain C, C++, Rust, or Fortran extensions. + +``` +pip install pyodide-build +pyodide xbuildenv install +pyodide build . +ls dist/ # -> your_package-1.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl +``` + +- Step 1: Install pyodide-build +- Step 2: Install the cross-build environment (one sentence explanation, link to Concepts) +- Step 3: Build — show the three source modes: + - From current directory (like `python -m build`) + - From PyPI (`pyodide build numpy==2.0`) + - From URL (`pyodide build https://...tar.gz`) +- Step 4: Inspect the output wheel — what the platform tag means +- Callout box: "From `python -m build` to `pyodide build`" migration comparison + +#### 5. Testing with `pyodide venv` (`getting-started/testing.md`) + +Immediately after building, show how to verify the wheel works. + +``` +pyodide venv .venv-pyodide +source .venv-pyodide/bin/activate +pip install dist/your_package-*.whl +python -c "import your_package; print('works!')" +``` + +- What `pyodide venv` does differently from `python -m venv` (Node.js + Pyodide runtime as interpreter) +- Installing your wheel — pip inside the venv only accepts Wasm-compatible wheels +- Running tests: `python -m pytest` inside the venv runs on Pyodide/Node.js +- "What's weird about this venv": pip runs on host Python, but `python` invokes Pyodide/Node.js +- Note: requires Node.js +- Windows notes (`Scripts\activate` path, known quirks) + +--- + +### Part II — Tutorials (learning-oriented, end-to-end walkthroughs) + +Each tutorial walks through a complete scenario from start to finish. + +#### 6. Tutorial: Package with C Extension (`tutorials/c-extension.md`) + +- Setuptools/distutils package with a `.c` file +- What happens under the hood: pywasmcross intercepts `gcc` calls and redirects to `emcc` +- Export modes explained in context: `pyinit` (default) vs `requested` vs `whole_archive` +- Debugging a build failure (practical example with a real error) + +#### 7. Tutorial: CMake/Meson Package (`tutorials/cmake-meson.md`) + +- How to pass the cross-compilation files: + - `pyodide config get meson_cross_file` + - `pyodide config get cmake_toolchain_file` +- The `-C setup-args=--cross-file=...` pattern +- `--no-isolation` mode for complex build environments +- pybind11, nanobind, and Cython examples +- scikit-build-core integration + +#### 8. Tutorial: Rust Package (PyO3/Maturin) (`tutorials/rust.md`) + +- Rust toolchain auto-setup (`wasm32-unknown-emscripten` target) +- Key environment variables: `CARGO_BUILD_TARGET`, `RUSTFLAGS`, `PYO3_CROSS_*` +- `pyodide config get rust_toolchain` and `rustflags` +- Example: building a simple PyO3 extension + +#### 9. Tutorial: Building with Dependencies (`tutorials/dependencies.md`) + +- Installing the resolve extra: `pip install pyodide-build[resolve]` +- `pyodide build --build-dependencies` — auto-resolves and builds the dependency tree +- Skipping built-in packages (`--skip-built-in-packages`) and specific deps (`--skip-dependency `) +- Building from a requirements file: `-r requirements.txt` +- Exporting resolved dependencies: `--output-lockfile` +- Practical example: building a package that needs numpy + scipy at runtime + +--- + +### Part III — How-to Guides (task-oriented, for working developers) + +Each guide solves a specific task. Assumes the reader has basic familiarity from Parts I-II. + +#### 10. CI with cibuildwheel (`how-to/cibuildwheel.md`) + +This is likely the **highest-value section** after the quickstart — many users encounter pyodide-build through cibuildwheel. + +- Why cibuildwheel: build for Linux, macOS, Windows, **and** Pyodide in one CI config +- Pyodide support history: added in cibuildwheel v2.19.0, current at v3.4.0 +- Platform identifiers: `cp312-pyodide_wasm32`, `cp313-pyodide_wasm32` +- Minimal `pyproject.toml` configuration: + ```toml + [tool.cibuildwheel] + build = ["cp312-*", "cp313-*"] + + [tool.cibuildwheel.pyodide] + test-command = "python -m pytest {project}/tests -x" + test-requires = ["pytest"] + ``` +- Complete GitHub Actions workflow (copy-paste-ready, Pyodide as separate job) +- Key constraints: + - Must explicitly set `CIBW_PLATFORM=pyodide` — auto-detection won't select it + - `pip` frontend NOT supported — only `build` or `build[uv]` + - Linux/macOS only — cannot build on Windows runners + - Tests must use `python -m pytest`, not bare `pytest` + - No default wheel repair — most projects set `repair-wheel-command = ""` +- Real-world config examples from: NumPy, pandas, matplotlib, Rust+Pyodide projects +- Link to cibuildwheel's Pyodide platform docs + +#### 11. CI without cibuildwheel (`how-to/ci-direct.md`) + +For projects that don't use cibuildwheel or want more control. + +- Direct GitHub Actions workflow using `pyodide build` commands +- Matrix builds across Pyodide versions +- Caching the xbuildenv for faster CI runs +- Testing step with `pyodide venv` + +#### 12. Publishing Wasm Wheels (`how-to/publishing.md`) + +- Publishing to PyPI: standard `twine upload` / trusted publishing works — Wasm wheels are regular wheels +- Platform tag format: `pyemscripten_YYYY_P_wasm32` (per PEP 783; older versions used `pyodide_YYYY_P_wasm32`) +- How Pyodide users consume your wheel: `micropip.install("your-package")` in the browser, or `pip install` inside a `pyodide venv` +- Complete CI example: build with cibuildwheel -> publish with trusted publishing +- Admonition (single note): PEP 783 formalizes the Emscripten platform tags — link to the PEP for details on the platform specification + +#### 13. Migrating from Native Builds (`how-to/migrate.md`) + +Addresses a major user pain point: "I already build native wheels, what do I change?" + +- Side-by-side comparison: `python -m build` workflow vs `pyodide build` workflow +- Common issues when adapting: + - `pthreads` (not supported in Wasm) + - SIMD intrinsics / inline assembly + - Filesystem assumptions (limited in Wasm) + - Networking code (no sockets in Wasm) + - 64-bit integer assumptions +- Conditional compilation: detecting Pyodide at build time: + - C/C++: `#ifdef __EMSCRIPTEN__` + - Python: `os.environ.get("PYODIDE")` (build-time), `sys.platform == "emscripten"` (runtime) + +#### 14. Managing Cross-Build Environments (`how-to/xbuildenv.md`) + +- Install: `pyodide xbuildenv install [version]` +- List installed: `pyodide xbuildenv versions` +- Switch active: `pyodide xbuildenv use ` +- Uninstall: `pyodide xbuildenv uninstall [version]` +- Search available: `pyodide xbuildenv search [--all] [--json]` +- Path resolution order: `PYODIDE_XBUILDENV_PATH` env var -> pyproject.toml -> platform cache dir -> cwd +- Pinning a version in pyproject.toml (`xbuildenv_path` or `default_cross_build_env_url`) +- Emscripten SDK management: `pyodide xbuildenv install-emscripten` +- Lazy cross-build package installation (packages installed on first use, not eagerly) + +#### 15. Customizing Compiler Flags (`how-to/compiler-flags.md`) + +For power users who need to tweak the build. + +- Default flags and what they do: + - `-Oz` (optimize for size), `SIDE_MODULE=1` (Emscripten side module) +- Overriding via `pyproject.toml` `[tool.pyodide.build]`: + ```toml + [tool.pyodide.build] + cflags = "$(CFLAGS_BASE) -I$(PYTHONINCLUDE) -O2" + ``` +- Overriding via environment variables: `CFLAGS`, `CXXFLAGS`, `LDFLAGS` (appended to defaults) +- What pywasmcross silently filters out: + - `-pthread` (threading disabled) + - macOS-specific flags (`-bundle`, `-undefined dynamic_lookup`) + - x86 SIMD flags (`-mpopcnt`, `-mno-sse2`, etc.) + - Fortran-specific flags +- Fortran handling: `gfortran` calls are converted via f2c translation +- CMake toolchain file and Meson cross-file integration + +#### 16. Debugging Build Failures (`how-to/debugging.md`) + +Systematic troubleshooting guide organized by failure phase. + +- **Phase 1: Environment errors** + - "No Emscripten compiler found" -> install xbuildenv + - "Version X is not compatible" -> Python/pyodide-build version mismatch + - "local Python version does not match" -> Python changed after xbuildenv install +- **Phase 2: Compilation errors** + - Missing headers -> check include paths + - Incompatible C/C++ code -> pthread, SIMD, inline assembly + - Function pointer cast errors -> Wasm strict typing +- **Phase 3: Link errors** + - Missing symbols -> check export mode (`pyinit` vs `requested` vs `whole_archive`) + - Duplicate symbols -> wasm-ld doesn't allow duplicate `-l` flags (pywasmcross deduplicates) +- **Phase 4: Build system errors** + - CMake/Meson configuration failures -> cross-file not passed + - scikit-build-core issues -> `CMAKE_EXECUTABLE` env var +- **Phase 5: Runtime errors** + - "Wheel works in browser but fails in venv" -> testing environment differences + +--- + +### Part IV — Recipe System (for Pyodide ecosystem contributors) + +Separate audience — most users never need this. + +#### 17. Recipe Authoring (`recipes/authoring.md`) + +- What is a recipe? A `meta.yaml` file that declares how to build a package for Pyodide's package ecosystem. +- When do you need a recipe vs. just `pyodide build`? + - Recipe: contributing to the Pyodide built-in packages set + - `pyodide build`: building your own package for distribution +- Generating a recipe: `pyodide skeleton pypi ` +- `meta.yaml` walkthrough with annotated example +- Build types: `package`, `static_library`, `shared_library`, `cpython_module` +- Source handling: URL vs local path, sha256 checksums, patches, extras +- Build customization: `cflags`, `ldflags`, `backend-flags`, `script`, `post` +- Requirements: `run` (runtime), `host` (build-time), `executable` (e.g., rustc), `constraint` +- Cross-build support: `cross-build-env`, `cross-build-files` +- Test imports validation + +#### 18. Building Recipes (`recipes/building.md`) + +- `pyodide build-recipes` — dependency graph resolution + parallel builds +- `pyodide build-recipes-no-deps` — building individual packages without resolution +- `pyodide clean recipes` — cleaning build artifacts +- Recipe lifecycle management: + - `pyodide skeleton enable ` / `disable -m "reason"` + - `pyodide skeleton pin -m "reason"` + +--- + +### Part V — Reference (information-oriented, exhaustive) + +#### 19. CLI Reference (`reference/cli.md`) + +Complete option tables for every command. Consider auto-generating from Click's `--help` output. + +Commands to document: +- `pyodide build` — all arguments and options with defaults, env var mappings +- `pyodide venv` — arguments and options +- `pyodide xbuildenv` — all subcommands: `install`, `version`, `versions`, `uninstall`, `use`, `search`, `install-emscripten` +- `pyodide config` — subcommands: `list`, `get` +- `pyodide build-recipes` — all options +- `pyodide build-recipes-no-deps` — all options +- `pyodide skeleton` — subcommands: `pypi`, `enable`, `disable`, `pin` +- `pyodide py-compile` — arguments and options +- `pyodide clean recipes` — arguments and options + +#### 20. Configuration Reference (`reference/configuration.md`) + +- Configuration precedence: env vars > pyproject.toml > Makefile.envs > defaults +- Complete `[tool.pyodide.build]` key reference table: + + | Key | Env Var | Default | Description | + |---|---|---|---| + | `cflags` | `SIDE_MODULE_CFLAGS` | `$(CFLAGS_BASE) -I$(PYTHONINCLUDE) -Oz` | C compiler flags | + | `cxxflags` | `SIDE_MODULE_CXXFLAGS` | `$(CFLAGS_BASE) -Oz` | C++ compiler flags | + | `ldflags` | `SIDE_MODULE_LDFLAGS` | `$(LDFLAGS_BASE) -s SIDE_MODULE=1 -Oz` | Linker flags | + | `rustflags` | `RUSTFLAGS` | `-C link-arg=-sSIDE_MODULE=2 ...` | Rust compiler flags | + | `rust_toolchain` | `RUST_TOOLCHAIN` | `nightly-2025-02-01` | Rust toolchain version | + | `meson_cross_file` | `MESON_CROSS_FILE` | `/emscripten.meson.cross` | Meson cross file | + | `xbuildenv_path` | `PYODIDE_XBUILDENV_PATH` | platform cache dir | xbuildenv location | + | `ignored_build_requirements` | `IGNORED_BUILD_REQUIREMENTS` | `patchelf oldest-supported-numpy` | Build deps to ignore | + | ... | ... | ... | ... | + +- Environment variables reference table (all `PYODIDE_*` vars) +- `$(VAR)` substitution syntax in config values + +#### 21. meta.yaml Reference (`reference/meta-yaml.md`) + +- Complete field reference with types, defaults, validation rules +- All sections: `package`, `source`, `build`, `requirements`, `test`, `about`, `extra` +- Validation error messages and what triggers them +- Migrated from pyodide.org's meta.yaml spec — this becomes the canonical reference + +#### 22. Platform Tags & Compatibility (`reference/platform.md`) + +- Platform version <-> Python version <-> Emscripten version matrix: + + | Platform Tag | Python | Notes | + |---|---|---| + | `pyodide_2024_0_wasm32` | 3.12 | Legacy tag name | + | `pyemscripten_2025_0_wasm32` | 3.13 | PEP 783 standardized name | + | `pyemscripten_2026_0_wasm32` | 3.14 | PEP 783 standardized name | + +- Wheel naming format explained +- PEP 783 (Emscripten/WebAssembly platform) — the formal specification for these tags +- ABI compatibility rules: wheels are NOT cross-version compatible +- cibuildwheel identifier mapping: `cp312-pyodide_wasm32`, `cp313-pyodide_wasm32` + +--- + +### Part VI — Explanation (understanding-oriented) + +#### 23. How pyodide-build Works (`explanation/architecture.md`) + +For users who want to understand the internals. + +- The build pipeline: source -> pypa/build -> pywasmcross wrapper -> emcc -> .wasm -> wheel +- The compiler wrapper (pywasmcross): intercepts cc/gcc/g++ calls, translates flags, redirects to emcc/em++ +- Symlinks created: `cc`, `c++`, `ld`, `ar`, `cmake`, `meson`, `cargo`, `gfortran`, etc. +- Why `SIDE_MODULE` and symbol exports matter +- Flag filtering: what gets removed and why (pthreads, macOS flags, SIMD, etc.) +- Fortran-to-C translation pipeline (f2c) + +#### 24. The Pyodide Ecosystem (`explanation/ecosystem.md`) + +- Package relationships: + - `pyodide-cli`: the dispatcher that routes `pyodide ` to plugins + - `pyodide-build`: registers all build commands as pyodide-cli plugins + - `pyodide-lock`: the lockfile format library + - `auditwheel-emscripten`: wheel repair/inspection for Wasm wheels + - `micropip`: runtime package installer (browser-side) +- How users consume your wheel: `micropip.install()` in the browser or `pip install` in a pyodide venv +- The relationship between pyodide-build and the main Pyodide project + +--- + +### Appendix + +#### 25. Troubleshooting (`troubleshooting.md`) + +Organized by error message for searchability. + +- "No Emscripten compiler found" -> install xbuildenv or check `PYODIDE_SKIP_EMSCRIPTEN_INSTALL` +- "Version X is not compatible with the current environment" -> Python/pyodide-build version mismatch, use `--force` +- "local Python version does not match" -> Python changed after xbuildenv install, reinstall xbuildenv +- "MissingOptionalDependencyError" -> `pip install pyodide-build[resolve]` +- "Can't find package: " -> PyPI resolution failure +- "PIP_CONSTRAINT contains spaces" -> move project to a path without spaces +- Build failures with C extensions -> check filtered flags, threading, SIMD +- Wheel is too large -> compression level, `unvendor-tests`, `-Oz` vs `-O2` tradeoff +- Windows-specific issues -> Makefile.envs parsing limitations + +#### 26. FAQ (`faq.md`) + +- "Which packages work with Pyodide?" — Pure Python = always. C extensions = usually. Threading/multiprocessing = no. Filesystem-heavy = maybe. Networking = no. +- "What's the difference between `pyodide build` and `pyodide build-recipes`?" — Out-of-tree single package build vs in-tree recipe system with dependency resolution. +- "Can I use maturin/meson-python/scikit-build-core?" — Yes, with cross-file configuration. +- "Do I need the full Pyodide repo?" — No, pyodide-build is standalone. +- "What Node.js version do I need?" — v22+ recommended (for pyodide venv). +- "Should I use `pyodide build` directly or cibuildwheel?" — cibuildwheel if you already build native wheels and want one CI config. `pyodide build` directly if you only target Pyodide or want more control. +- "Can I publish Wasm wheels to PyPI?" — Yes. Upload with `twine` or trusted publishing like any other wheel. + +#### 27. Changelog + +Link to `CHANGELOG.md`. Highlight breaking changes between versions: +- **Unreleased**: `-Oz` replaces `-O2` default, `vendor_sharedlib` defaults to `true` +- **v0.33.0**: Emscripten auto-install +- **v0.32.0**: typer -> click CLI framework migration +- **v0.31.0**: Windows support for `pyodide venv` +- **v0.30.0**: uv support, xbuildenv moved to cache dir + +--- + +## Reader Journey Map + +| Reader Profile | Sections They Need | Time | +|---|---|---| +| "I have 5 minutes, show me it works" | 1, 2, 4, 5 | 10 min | +| "I have a C extension package" | + 6, 7 | + 30 min | +| "I want CI for my project" | + 10 or 11 | + 15 min | +| "I want to publish" | + 12 | + 10 min | +| "My build is failing" | 16, 25 | lookup | +| "I need custom compiler flags" | 15, 20 | lookup | +| "I want to contribute a Pyodide recipe" | 17, 18, 21 | 30 min | +| "I want to understand the internals" | 23, 24 | 30 min | + +**80% of users** need only: **Getting Started (1-5) + CI guide (10) + Publishing (12)**. + +## Implementation Notes + +- The `docs/` directory already has Sphinx + myst-parser configured (`.readthedocs.yaml`, `conf.py`). Write in Markdown (`.md`), not reStructuredText. +- Consider auto-generating the CLI Reference (Section 20) from Click's `--help` output to stay in sync. +- Real-world examples (NumPy, pandas, matplotlib cibuildwheel configs) should be kept up-to-date or link to the source repos directly. +- PEP 783 is assumed accepted throughout the docs. A single admonition in the Publishing guide (Section 13) links to the PEP for the formal platform specification. No scattered caveats elsewhere. +- **Migration from pyodide.org**: The following pyodide.org pages should be migrated here and replaced with redirects/links: + - `development/building-packages.html` → Sections 4, 6, 10 + - `development/building-packages-from-source.html` → Sections 6, 7, 16 + - `development/meta-yaml.html` → Section 21 + - `usage/api/pyodide-cli.html` (build-related commands) → Section 19 diff --git a/docs/conf.py b/docs/conf.py index 6781adc3..568ae4e1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -15,6 +15,11 @@ "sphinx.ext.napoleon", "myst_parser", "sphinx_autodoc_typehints", + "sphinx_design", +] + +myst_enable_extensions = [ + "colon_fence", ] intersphinx_mapping = { diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..5bf74a1c --- /dev/null +++ b/docs/index.md @@ -0,0 +1,143 @@ +# pyodide-build + +**Build Python packages for WebAssembly.** + +pyodide-build is the build toolchain for compiling Python packages to [WebAssembly](https://webassembly.org/) via [Emscripten](https://emscripten.org/). It is the reference implementation of the build toolchain for the [Emscripten/WebAssembly Python platform](https://peps.python.org/pep-0783/). + +This tool is designed to be used with [Pyodide](https://pyodide.org/), but it can also be used with other Emscripten-based Python runtimes that support the same platform tags. + +If you're familiar with `python -m build`, pyodide-build works the same way — just replace it with `pyodide build`: + +```bash +pip install pyodide-build +pyodide build . +``` + +This produces a `.whl` file tagged for the Emscripten platform (e.g., `your_package-1.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl`) that can be published to PyPI and installed in [Pyodide](https://pyodide.org/). + +## Who is this for? + +```{note} +**Pure-Python packages do not need pyodide-build.** A standard wheel built with `python -m build`, `hatch`, `flit`, or any PEP 517 build frontend is already compatible with Pyodide. pyodide-build is for packages that contain compiled extensions. +``` + +pyodide-build is for **Python package maintainers** who want their package to work in WebAssembly environments — the browser, Node.js, or any Emscripten-based Python runtime. Typical users include: + +- **Package authors** adding Pyodide/WebAssembly to their platform support matrix +- **Library maintainers** whose users need the package in [JupyterLite](https://jupyterlite.readthedocs.io/), [Pyodide](https://pyodide.org/), or other browser-based Python environments + +## How it works + +pyodide-build wraps [pypa/build](https://build.pypa.io/) with a cross-compilation layer. When you run `pyodide build`, it: + +1. Sets up a cross-build environment with Emscripten-compiled CPython headers and sysconfig data +2. Intercepts compiler calls (`gcc`, `g++`, `ld`, etc.) and redirects them to Emscripten (`emcc`, `em++`) +3. Translates compiler flags for WebAssembly compatibility +4. Produces a standard wheel with the appropriate platform tag + +Your existing `setup.py`, `pyproject.toml`, CMakeLists.txt, or `meson.build` works as-is — pyodide-build handles the cross-compilation transparently. + +## Where to start + +::::{grid} 1 1 2 3 +:gutter: 2 + +:::{grid-item-card} Quick Start +:link: getting-started/quickstart +Build your first WebAssembly wheel in 5 minutes. +::: + +:::{grid-item-card} CI with cibuildwheel +:link: how-to/cibuildwheel +Add Pyodide to your existing cibuildwheel CI pipeline. +::: + +:::{grid-item-card} Testing with `pyodide venv` +:link: getting-started/testing +Verify your wheel works in a Pyodide environment. +::: + +:::: + +```{toctree} +:maxdepth: 2 +:hidden: +:caption: Getting Started + +getting-started/installation +getting-started/concepts +getting-started/quickstart +getting-started/testing +``` + +```{toctree} +:maxdepth: 2 +:hidden: +:caption: Tutorials + +tutorials/c-extension +tutorials/cmake-meson +tutorials/rust +tutorials/dependencies +``` + +```{toctree} +:maxdepth: 2 +:hidden: +:caption: How-to Guides + +how-to/cibuildwheel +how-to/ci-direct +how-to/publishing +how-to/migrate +how-to/xbuildenv +how-to/compiler-flags +how-to/debugging +``` + +```{toctree} +:maxdepth: 2 +:hidden: +:caption: Recipe System + +recipes/authoring +recipes/building +``` + +```{toctree} +:maxdepth: 2 +:hidden: +:caption: Reference + +reference/cli +reference/configuration +reference/meta-yaml +reference/platform +``` + +```{toctree} +:maxdepth: 2 +:hidden: +:caption: Explanation + +explanation/architecture +explanation/ecosystem +``` + +```{toctree} +:maxdepth: 2 +:hidden: +:caption: Appendix + +troubleshooting +faq +changelog +``` + +## Communication + +- Blog: [blog.pyodide.org](https://blog.pyodide.org/) +- Mailing list: [mail.python.org/mailman3/lists/pyodide.python.org/](https://mail.python.org/mailman3/lists/pyodide.python.org/) +- Gitter: [gitter.im/pyodide/community](https://gitter.im/pyodide/community) +- Twitter: [twitter.com/pyodide](https://twitter.com/pyodide) +- Stack Overflow: [stackoverflow.com/questions/tagged/pyodide](https://stackoverflow.com/questions/tagged/pyodide) diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index 28b521a4..00000000 --- a/docs/index.rst +++ /dev/null @@ -1,18 +0,0 @@ -pyodide-build -============= - -``pyodide-build`` is the build toolchain for `PEP 783 `_. - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - - -Communication -------------- - -- Blog: `blog.pyodide.org `_ -- Mailing list: `mail.python.org/mailman3/lists/pyodide.python.org/ `_ -- Gitter: `gitter.im/pyodide/community `_ -- Twitter: `twitter.com/pyodide `_ -- Stack Overflow: `stackoverflow.com/questions/tagged/pyodide `_ diff --git a/docs/requirements-doc.txt b/docs/requirements-doc.txt index 63d8a5d2..0ae1b9f6 100644 --- a/docs/requirements-doc.txt +++ b/docs/requirements-doc.txt @@ -2,3 +2,4 @@ sphinx>=5.3.0 sphinx_book_theme>=0.4.0rc1 myst-parser sphinx-autodoc-typehints>=1.21.7 +sphinx-design From f9a59e23f7a388e8d813a95bc418900a76ad796e Mon Sep 17 00:00:00 2001 From: Gyeongjae Choi Date: Tue, 24 Mar 2026 17:39:51 +0900 Subject: [PATCH 2/8] Add getting started section --- docs/getting-started/concepts.md | 109 +++++++++++++++++++++++++++ docs/getting-started/installation.md | 42 +++++++++++ docs/getting-started/quickstart.md | 71 +++++++++++++++++ docs/getting-started/testing.md | 78 +++++++++++++++++++ 4 files changed, 300 insertions(+) create mode 100644 docs/getting-started/concepts.md create mode 100644 docs/getting-started/installation.md create mode 100644 docs/getting-started/quickstart.md create mode 100644 docs/getting-started/testing.md diff --git a/docs/getting-started/concepts.md b/docs/getting-started/concepts.md new file mode 100644 index 00000000..16ef4a91 --- /dev/null +++ b/docs/getting-started/concepts.md @@ -0,0 +1,109 @@ +# Concepts + +This page explains the key ideas behind pyodide-build. Understanding these concepts will help you debug build issues and make sense of the configuration options. + +## Why cross-compilation? + +When you run `python -m build` on your laptop, your C extensions are compiled for your machine's architecture — x86_64 on most desktops, arm64 on Apple Silicon. The resulting wheel only works on that platform. + +Pyodide runs Python inside WebAssembly, which is a completely different compilation target. You can't run `gcc` or `clang` and get a `.so` that works in WebAssembly — you need [Emscripten](https://emscripten.org/), a compiler toolchain that produces WebAssembly output from C/C++ source code. + +pyodide-build automates this cross-compilation. When you run `pyodide build`, it: + +1. Invokes your package's normal build system (setuptools, meson-python, scikit-build-core, etc.) +2. Intercepts all compiler and linker calls +3. Redirects them through Emscripten with the right flags for WebAssembly +4. Produces a standard wheel tagged for the Emscripten platform + +Your build scripts don't need to change — pyodide-build handles the translation transparently. + +## The cross-build environment + +Cross-compilation needs more than just a compiler. Your package's build system needs to find Python headers, link against the right libraries, and query Python's `sysconfig` for the target platform — not the host. The **cross-build environment** (xbuildenv) provides all of this: + +- **CPython headers and sysconfig data** compiled for Emscripten/WebAssembly +- **Pre-built package stubs** for packages like NumPy and SciPy that other packages link against at build time +- **Emscripten SDK** — the compiler toolchain itself (installed automatically) + +When you run `pyodide build`, pyodide-build automatically downloads and sets up the cross-build environment if one isn't already installed. It's cached in your platform's user cache directory so subsequent builds are fast. + +You can also manage the cross-build environment explicitly: + +```bash +pyodide xbuildenv install # install (or update) the cross-build environment +pyodide xbuildenv install 0.27.0 # install a specific Pyodide version +pyodide xbuildenv versions # list installed versions +``` + +See [Managing Cross-Build Environments](../how-to/xbuildenv.md) for more details. + +## Emscripten + +[Emscripten](https://emscripten.org/) is the compiler toolchain that turns C and C++ code into WebAssembly. It provides drop-in replacements for standard compilers: + +| Standard tool | Emscripten equivalent | +|---|---| +| `gcc` / `cc` | `emcc` | +| `g++` / `c++` | `em++` | +| `ar` | `emar` | +| `ranlib` | `emranlib` | + +pyodide-build manages Emscripten automatically — it installs the correct version as part of the cross-build environment and handles all compiler redirection. You don't need to install or configure Emscripten yourself. + +```{important} +Each Pyodide version requires a **specific** Emscripten version. pyodide-build enforces this to ensure ABI compatibility. You can check the required version with `pyodide config get emscripten_version`. +``` + +## Platform tags + +Python wheels include a [platform tag](https://packaging.python.org/en/latest/specifications/platform-compatibility-tags/) that identifies which systems they can run on. For example: + +- `manylinux_2_17_x86_64` — Linux on x86_64 +- `macosx_14_0_arm64` — macOS on Apple Silicon +- `pyemscripten_2025_0_wasm32` — Emscripten/WebAssembly + +The Emscripten platform tag, standardized by [PEP 783](https://peps.python.org/pep-0783/), has the format: + +``` +pyemscripten_{year}_{patch}_wasm32 +``` + +Where `{year}_{patch}` is the platform ABI version (e.g., `2025_0`). This version determines which Emscripten SDK version and CPython build are used. Wheels built for one ABI version are **not** compatible with another. + +A complete wheel filename looks like: + +``` +numpy-2.2.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl + │ │ │ │ + │ │ │ └── platform tag + │ │ └── Python ABI tag + │ └── Python version tag + └── package version +``` + +```{note} +Older Pyodide versions (before PEP 783) used the tag `pyodide_{year}_{patch}_wasm32`. The `pyemscripten_*` tag is the standardized form going forward. +``` + +## `pyodide build` vs `python -m build` + +`pyodide build` is designed to be a drop-in replacement for `python -m build` when targeting WebAssembly. Here's what's the same and what's different: + +**The same:** +- Uses your existing `pyproject.toml` build configuration +- Supports the same build backends (setuptools, meson-python, scikit-build-core, hatchling, etc.) +- Produces a standard `.whl` file +- Supports `-C` / `--config-setting` to pass options to the build backend +- Supports `--no-isolation` for custom build environments + +**Different:** +- Compiler calls are intercepted and redirected to Emscripten +- Some compiler flags are filtered out (e.g., `-pthread`, x86 SIMD flags) because they don't apply to WebAssembly +- The output wheel has an Emscripten platform tag instead of a native one +- A cross-build environment must be available (installed automatically on first use) + +## What's next? + +- [Quick Start](quickstart.md) — build your first WebAssembly wheel +- [Managing Cross-Build Environments](../how-to/xbuildenv.md) — advanced xbuildenv management +- [Platform Tags & Compatibility](../reference/platform.md) — full compatibility matrix diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md new file mode 100644 index 00000000..036312f2 --- /dev/null +++ b/docs/getting-started/installation.md @@ -0,0 +1,42 @@ +# Installation + +## Requirements + +- **Linux or macOS** — pyodide-build works best on Linux and macOS. Windows is not supported. +- **Python 3.12 or later** — **must** match the Python version targeted by the Pyodide cross-build environment you install. +- **Node.js** — required for testing with [`pyodide venv`](testing.md). Not needed for building. Node.js >= 24 is recommended. + +## Install pyodide-build + +::::{tab-set} + +:::{tab-item} pip +```bash +pip install pyodide-build +``` +::: + +:::{tab-item} pipx +```bash +pipx install pyodide-build +``` +::: + +:::{tab-item} uv +```bash +uv tool install pyodide-cli --with pyodide-build +``` +::: + +:::: + +Verify the installation: + +```bash +pyodide --version +``` + +## What's next? + +- [Concepts](concepts.md) — understand cross-compilation, the cross-build environment, and platform tags +- [Quick Start](quickstart.md) — build your first WebAssembly wheel diff --git a/docs/getting-started/quickstart.md b/docs/getting-started/quickstart.md new file mode 100644 index 00000000..5d8a4328 --- /dev/null +++ b/docs/getting-started/quickstart.md @@ -0,0 +1,71 @@ +# Quick Start + +This guide walks you through building a Python package with C extensions for WebAssembly using pyodide-build. + +```{note} +**Pure-Python packages do not need pyodide-build.** If your package has no C, C++, or Rust extensions, a standard wheel built with `python -m build` already works with Pyodide. +``` + +## Build from your source tree + +If you have a package with compiled extensions locally, build it the same way you would with `python -m build`: + +```bash +pyodide build . +``` + +The output wheel is placed in `./dist/` by default: + +``` +dist/your_package-1.0.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl +``` + +On the first run, pyodide-build automatically downloads and sets up the cross-build environment and Emscripten SDK. This may take a minute — subsequent builds are fast. + +You can specify a different output directory with `--outdir` / `-o`: + +```bash +pyodide build . -o wheelhouse/ +``` + +## Passing options to the build backend + +Use `-C` / `--config-setting` to pass options to your build backend, just like with `python -m build`: + +```bash +# Meson project: pass the cross-compilation file +pyodide build . -C setup-args=-Dblas=none -C setup-args=-Dlapack=none + +# setuptools project: pass extra compile args +pyodide build . -C "--build-option=--some-flag" +``` + +## Verify the wheel + +You can inspect the built wheel to confirm it has the correct platform tag: + +```bash +unzip -l dist/your_package-*.whl | head -20 +``` + +The wheel should contain `.so` files (compiled extensions) alongside your Python source, and the filename should include the `pyemscripten_*_wasm32` platform tag. + +## Test the wheel + +Create a [Pyodide virtual environment](testing.md) to test the wheel: + +```bash +pyodide venv .venv-pyodide +source .venv-pyodide/bin/activate +pip install dist/your_package-*.whl +python -c "import your_package; print('it works!')" +``` + +See [Testing with `pyodide venv`](testing.md) for a full walkthrough. + +## What's next? + +- [Testing with `pyodide venv`](testing.md) — verify your wheel in a Pyodide environment +- [CI with cibuildwheel](../how-to/cibuildwheel.md) — automate Pyodide builds in CI +- [Tutorial: CMake/Meson Package](../tutorials/cmake-meson.md) — building packages with CMake or Meson build systems +- [Tutorial: Rust Package](../tutorials/rust.md) — building packages with Rust/PyO3 extensions diff --git a/docs/getting-started/testing.md b/docs/getting-started/testing.md new file mode 100644 index 00000000..ece644b6 --- /dev/null +++ b/docs/getting-started/testing.md @@ -0,0 +1,78 @@ +# Testing with `pyodide venv` + +After building a WebAssembly wheel, you'll want to verify it actually works. `pyodide venv` creates a virtual environment where `python` runs on [Pyodide](https://pyodide.org/) via Node.js, so you can test your package in a real WebAssembly runtime without opening a browser. + +## Create a Pyodide virtual environment + +```bash +pyodide venv .venv-pyodide +``` + +This creates a virtual environment at `.venv-pyodide/`. Under the hood, it: + +1. Creates a virtualenv using the Pyodide interpreter (which runs on Node.js) +2. Configures `pip` to only accept WebAssembly-compatible wheels +3. Installs the Pyodide standard library and [micropip](https://micropip.pyodide.org/) + +## Activate and install your wheel + +```bash +source .venv-pyodide/bin/activate +pip install dist/your_package-*.whl +``` + +## Run your code + +Once activated, `python` runs on Pyodide/Node.js: + +```bash +python -c "import your_package; print('it works!')" +``` + +Run your test suite (install pytest first — it's not pre-installed in the venv): + +```bash +pip install pytest +python -m pytest tests/ +``` + +```{important} +Use `python -m pytest` (not bare `pytest`). CLI entry points may not work correctly inside the Pyodide venv — always invoke tools as Python modules. +``` + +## How the venv works + +The Pyodide venv looks like a normal virtualenv, but there are important differences: + +| | Standard venv | Pyodide venv | +|---|---|---| +| `python` | Runs CPython natively | Runs Pyodide on Node.js | +| `pip` | Runs on host Python | Runs on **host Python**, but installs WebAssembly-compatible packages | +| Package compatibility | Any wheel for your platform | Only pure-Python wheels or `pyemscripten_*_wasm32` wheels | + +Key things to know: + +- **`pip` runs on host Python** — it uses your system Python to resolve and download packages, but only installs wheels compatible with WebAssembly. This means `pip install` is fast (no cross-compilation at install time). +- **`python` runs on Pyodide/Node.js** — when you run `python` or `python -c "..."`, it launches Node.js with the Pyodide runtime. This is the real WebAssembly environment. +- **Only binary-compatible wheels are installable** — `pip install` is configured with `only-binary=:all:`, so it won't attempt to build packages from source. If a WebAssembly wheel isn't available, the install will fail. + +## Limitations + +- **Requires Node.js** — the Pyodide venv needs Node.js to run the WebAssembly interpreter. Node.js >= 24 is recommended. +- **No threading** — `threading` and `multiprocessing` are not available in Pyodide. +- **No networking** — `socket`, `http.client`, and similar networking modules don't work. Use `pyodide.http` or `micropip` for HTTP requests. +- **Some tests may need skipping** — tests that rely on threads, subprocesses, networking, or platform-specific behavior will need to be skipped or adapted. Use markers like `@pytest.mark.skipif(sys.platform == "emscripten", ...)`. + +## Recreating the venv + +To recreate the venv from scratch (e.g., after updating pyodide-build): + +```bash +pyodide venv --clear .venv-pyodide +``` + +## What's next? + +- [CI with cibuildwheel](../how-to/cibuildwheel.md) — automate building and testing in CI +- [CI without cibuildwheel](../how-to/ci-direct.md) — set up GitHub Actions directly +- [Debugging Build Failures](../how-to/debugging.md) — troubleshooting when things go wrong From a895daa405bb2e6b1dc148abfbd8b4b7c1c61b42 Mon Sep 17 00:00:00 2001 From: Gyeongjae Choi Date: Tue, 24 Mar 2026 19:03:56 +0900 Subject: [PATCH 3/8] Add more docs --- docs/DOCUMENTATION_PLAN.md | 34 +++-- docs/changelog.md | 5 + docs/conf.py | 8 +- docs/explanation/architecture.md | 5 + docs/explanation/ecosystem.md | 5 + docs/faq.md | 5 + docs/getting-started/quickstart.md | 3 +- docs/how-to/ci-direct.md | 104 ++++++++++++++ docs/how-to/cibuildwheel.md | 111 +++++++++++++++ docs/how-to/compiler-flags.md | 5 + docs/how-to/debugging.md | 5 + docs/how-to/migrate.md | 5 + docs/how-to/publishing.md | 58 ++++++++ docs/how-to/xbuildenv.md | 5 + docs/index.md | 4 +- docs/recipes/authoring.md | 5 + docs/recipes/building.md | 5 + docs/reference/cli.md | 5 + docs/reference/configuration.md | 5 + docs/reference/meta-yaml.md | 5 + docs/reference/platform.md | 5 + docs/troubleshooting.md | 5 + docs/tutorials/c-extension.md | 216 +++++++++++++++++++++++++++++ docs/tutorials/cmake.md | 41 ++++++ docs/tutorials/meson.md | 61 ++++++++ docs/tutorials/rust.md | 81 +++++++++++ 26 files changed, 774 insertions(+), 22 deletions(-) create mode 100644 docs/changelog.md create mode 100644 docs/explanation/architecture.md create mode 100644 docs/explanation/ecosystem.md create mode 100644 docs/faq.md create mode 100644 docs/how-to/ci-direct.md create mode 100644 docs/how-to/cibuildwheel.md create mode 100644 docs/how-to/compiler-flags.md create mode 100644 docs/how-to/debugging.md create mode 100644 docs/how-to/migrate.md create mode 100644 docs/how-to/publishing.md create mode 100644 docs/how-to/xbuildenv.md create mode 100644 docs/recipes/authoring.md create mode 100644 docs/recipes/building.md create mode 100644 docs/reference/cli.md create mode 100644 docs/reference/configuration.md create mode 100644 docs/reference/meta-yaml.md create mode 100644 docs/reference/platform.md create mode 100644 docs/troubleshooting.md create mode 100644 docs/tutorials/c-extension.md create mode 100644 docs/tutorials/cmake.md create mode 100644 docs/tutorials/meson.md create mode 100644 docs/tutorials/rust.md diff --git a/docs/DOCUMENTATION_PLAN.md b/docs/DOCUMENTATION_PLAN.md index ac8eccd6..8db8759a 100644 --- a/docs/DOCUMENTATION_PLAN.md +++ b/docs/DOCUMENTATION_PLAN.md @@ -60,7 +60,7 @@ Explain the mental model before showing commands. This addresses a major user pa The "5-minute" path. Build a package with a C extension for Pyodide. -- Callout: **Pure-Python packages don't need pyodide-build.** A pure-Python wheel built with `python -m build` (or any standard build frontend) is already compatible with Pyodide — no special tooling required. pyodide-build is for packages that contain C, C++, Rust, or Fortran extensions. +- Callout: **Pure-Python packages don't need pyodide-build.** A pure-Python wheel built with `python -m build` (or any standard build frontend) is already compatible with Pyodide — no special tooling required. pyodide-build is for packages that contain C, C++, or Rust extensions. ``` pip install pyodide-build @@ -71,10 +71,7 @@ ls dist/ # -> your_package-1.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl - Step 1: Install pyodide-build - Step 2: Install the cross-build environment (one sentence explanation, link to Concepts) -- Step 3: Build — show the three source modes: - - From current directory (like `python -m build`) - - From PyPI (`pyodide build numpy==2.0`) - - From URL (`pyodide build https://...tar.gz`) +- Step 3: Build from your source tree (`pyodide build .`) - Step 4: Inspect the output wheel — what the platform tag means - Callout box: "From `python -m build` to `pyodide build`" migration comparison @@ -94,7 +91,7 @@ python -c "import your_package; print('works!')" - Running tests: `python -m pytest` inside the venv runs on Pyodide/Node.js - "What's weird about this venv": pip runs on host Python, but `python` invokes Pyodide/Node.js - Note: requires Node.js -- Windows notes (`Scripts\activate` path, known quirks) + --- @@ -109,15 +106,18 @@ Each tutorial walks through a complete scenario from start to finish. - Export modes explained in context: `pyinit` (default) vs `requested` vs `whole_archive` - Debugging a build failure (practical example with a real error) -#### 7. Tutorial: CMake/Meson Package (`tutorials/cmake-meson.md`) +#### 7a. Tutorial: Meson Package (`tutorials/meson.md`) -- How to pass the cross-compilation files: - - `pyodide config get meson_cross_file` - - `pyodide config get cmake_toolchain_file` -- The `-C setup-args=--cross-file=...` pattern +- `pyodide config get meson_cross_file` +- The `-Csetup-args=--cross-file=...` pattern +- Real-world example: NumPy - `--no-isolation` mode for complex build environments -- pybind11, nanobind, and Cython examples + +#### 7b. Tutorial: CMake Package (`tutorials/cmake.md`) + +- `pyodide config get cmake_toolchain_file` - scikit-build-core integration +- pybind11 and nanobind examples (via CMake and setuptools) #### 8. Tutorial: Rust Package (PyO3/Maturin) (`tutorials/rust.md`) @@ -145,7 +145,7 @@ Each guide solves a specific task. Assumes the reader has basic familiarity from This is likely the **highest-value section** after the quickstart — many users encounter pyodide-build through cibuildwheel. -- Why cibuildwheel: build for Linux, macOS, Windows, **and** Pyodide in one CI config +- Why cibuildwheel: build for Linux, macOS, **and** Pyodide in one CI config - Pyodide support history: added in cibuildwheel v2.19.0, current at v3.4.0 - Platform identifiers: `cp312-pyodide_wasm32`, `cp313-pyodide_wasm32` - Minimal `pyproject.toml` configuration: @@ -227,8 +227,7 @@ For power users who need to tweak the build. - `-pthread` (threading disabled) - macOS-specific flags (`-bundle`, `-undefined dynamic_lookup`) - x86 SIMD flags (`-mpopcnt`, `-mno-sse2`, etc.) - - Fortran-specific flags -- Fortran handling: `gfortran` calls are converted via f2c translation + - CMake toolchain file and Meson cross-file integration #### 16. Debugging Build Failures (`how-to/debugging.md`) @@ -353,10 +352,9 @@ For users who want to understand the internals. - The build pipeline: source -> pypa/build -> pywasmcross wrapper -> emcc -> .wasm -> wheel - The compiler wrapper (pywasmcross): intercepts cc/gcc/g++ calls, translates flags, redirects to emcc/em++ -- Symlinks created: `cc`, `c++`, `ld`, `ar`, `cmake`, `meson`, `cargo`, `gfortran`, etc. +- Symlinks created: `cc`, `c++`, `ld`, `ar`, `cmake`, `meson`, `cargo`, etc. - Why `SIDE_MODULE` and symbol exports matter - Flag filtering: what gets removed and why (pthreads, macOS flags, SIMD, etc.) -- Fortran-to-C translation pipeline (f2c) #### 24. The Pyodide Ecosystem (`explanation/ecosystem.md`) @@ -385,7 +383,7 @@ Organized by error message for searchability. - "PIP_CONSTRAINT contains spaces" -> move project to a path without spaces - Build failures with C extensions -> check filtered flags, threading, SIMD - Wheel is too large -> compression level, `unvendor-tests`, `-Oz` vs `-O2` tradeoff -- Windows-specific issues -> Makefile.envs parsing limitations + #### 26. FAQ (`faq.md`) diff --git a/docs/changelog.md b/docs/changelog.md new file mode 100644 index 00000000..3faf3751 --- /dev/null +++ b/docs/changelog.md @@ -0,0 +1,5 @@ +# Changelog + +```{warning} +This page is under construction. +``` diff --git a/docs/conf.py b/docs/conf.py index 568ae4e1..adc43448 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -28,7 +28,7 @@ } templates_path = ["_templates"] -exclude_patterns = ["_build", "Thumbs.db", ".*"] +exclude_patterns = ["_build", "Thumbs.db", ".*", "DOCUMENTATION_PLAN.md"] # -- Options for HTML output ------------------------------------------------- @@ -43,6 +43,12 @@ html_logo = "_static/img/pyodide-logo.png" html_static_path = ["_static"] +html_theme_options = { + "show_toc_level": 2, + "show_navbar_depth": 2, + "home_page_in_toc": True, +} + sys.path.append(Path(__file__).parent.parent.as_posix()) diff --git a/docs/explanation/architecture.md b/docs/explanation/architecture.md new file mode 100644 index 00000000..e15de236 --- /dev/null +++ b/docs/explanation/architecture.md @@ -0,0 +1,5 @@ +# How pyodide-build Works + +```{warning} +This page is under construction. +``` diff --git a/docs/explanation/ecosystem.md b/docs/explanation/ecosystem.md new file mode 100644 index 00000000..2c5a1330 --- /dev/null +++ b/docs/explanation/ecosystem.md @@ -0,0 +1,5 @@ +# The Pyodide Ecosystem + +```{warning} +This page is under construction. +``` diff --git a/docs/faq.md b/docs/faq.md new file mode 100644 index 00000000..1992ec4e --- /dev/null +++ b/docs/faq.md @@ -0,0 +1,5 @@ +# FAQ + +```{warning} +This page is under construction. +``` diff --git a/docs/getting-started/quickstart.md b/docs/getting-started/quickstart.md index 5d8a4328..81736e02 100644 --- a/docs/getting-started/quickstart.md +++ b/docs/getting-started/quickstart.md @@ -67,5 +67,6 @@ See [Testing with `pyodide venv`](testing.md) for a full walkthrough. - [Testing with `pyodide venv`](testing.md) — verify your wheel in a Pyodide environment - [CI with cibuildwheel](../how-to/cibuildwheel.md) — automate Pyodide builds in CI -- [Tutorial: CMake/Meson Package](../tutorials/cmake-meson.md) — building packages with CMake or Meson build systems +- [Tutorial: Meson Package](../tutorials/meson.md) — building packages with Meson +- [Tutorial: CMake Package](../tutorials/cmake.md) — building packages with CMake - [Tutorial: Rust Package](../tutorials/rust.md) — building packages with Rust/PyO3 extensions diff --git a/docs/how-to/ci-direct.md b/docs/how-to/ci-direct.md new file mode 100644 index 00000000..a02f5323 --- /dev/null +++ b/docs/how-to/ci-direct.md @@ -0,0 +1,104 @@ +# CI without cibuildwheel + +If you don't use [cibuildwheel](cibuildwheel.md), you can set up GitHub Actions (or any CI) to build Pyodide wheels directly with `pyodide build`. + +## GitHub Actions workflow + +```yaml +# .github/workflows/pyodide.yml +name: Build Pyodide wheel + +on: + push: + tags: ["v*"] + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - uses: actions/setup-node@v4 + with: + node-version: "24" + + - name: Install pyodide-build + run: pip install pyodide-build + + - name: Build wheel + run: pyodide build . + + - name: Test wheel + run: | + pyodide venv .venv-pyodide + source .venv-pyodide/bin/activate + pip install dist/*.whl + pip install pytest + python -m pytest tests/ -x + + - uses: actions/upload-artifact@v4 + with: + name: pyodide-wheel + path: dist/*.whl +``` + +## Caching the cross-build environment + +The cross-build environment and Emscripten SDK are downloaded on first use and can be large. Cache them to speed up subsequent runs: + +```yaml + - name: Cache xbuildenv + uses: actions/cache@v4 + with: + path: | + ~/.cache/pyodide + ~/.cache/emsdk + key: pyodide-xbuildenv-${{ hashFiles('**/pyproject.toml') }} + restore-keys: | + pyodide-xbuildenv- +``` + +Place this step before the "Build wheel" step. + +## Passing build options + +Pass options the same way you would locally: + +```yaml + # Meson project + - name: Build wheel + run: pyodide build . -Csetup-args=-Dsome-option=value + + # Custom export mode + - name: Build wheel + run: pyodide build . --exports pyinit +``` + +## Publishing + +Add a publish job that runs on tags: + +```yaml + publish: + needs: build + runs-on: ubuntu-latest + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + permissions: + id-token: write + steps: + - uses: actions/download-artifact@v4 + with: + name: pyodide-wheel + path: dist/ + - uses: pypa/gh-action-pypi-publish@release/v1 +``` + +## What's next? + +- [Publishing Wasm Wheels](publishing.md) — more details on distribution +- [CI with cibuildwheel](cibuildwheel.md) — if you also build native wheels diff --git a/docs/how-to/cibuildwheel.md b/docs/how-to/cibuildwheel.md new file mode 100644 index 00000000..7ff20d6f --- /dev/null +++ b/docs/how-to/cibuildwheel.md @@ -0,0 +1,111 @@ +# CI with cibuildwheel + +[cibuildwheel](https://cibuildwheel.pypa.io/) automates building Python wheels for multiple platforms in CI. Since v2.19.0, it supports Pyodide as a build target — meaning you can build native wheels for Linux, macOS, **and** WebAssembly wheels for Pyodide in the same CI pipeline. + +## Minimal configuration + +Add Pyodide to your `pyproject.toml`: + +```toml +[tool.cibuildwheel] +# Build for CPython 3.13 on all platforms +build = "cp313-*" + +[tool.cibuildwheel.pyodide] +# Test inside a Pyodide venv +test-requires = ["pytest"] +test-command = "python -m pytest {project}/tests -x" +``` + +```{important} +- Use `python -m pytest`, not bare `pytest` — CLI entry points may not work in the Pyodide venv. +``` + +## GitHub Actions workflow + +Pyodide builds must run as a **separate job** with `CIBW_PLATFORM=pyodide` — cibuildwheel won't auto-detect the Pyodide platform. + +```yaml +# .github/workflows/wheels.yml +name: Build wheels + +on: + push: + tags: ["v*"] + pull_request: + +jobs: + build-native: + name: Build wheels on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + steps: + - uses: actions/checkout@v4 + - uses: pypa/cibuildwheel@v2.22 + - uses: actions/upload-artifact@v4 + with: + name: wheels-${{ matrix.os }} + path: wheelhouse/*.whl + + build-pyodide: + name: Build Pyodide wheels + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pypa/cibuildwheel@v2.22 + env: + CIBW_PLATFORM: pyodide + - uses: actions/upload-artifact@v4 + with: + name: wheels-pyodide + path: wheelhouse/*.whl +``` + +## Key constraints + +| Constraint | Details | +|---|---| +| **Explicit platform** | Must set `CIBW_PLATFORM=pyodide` — auto-detection won't select Pyodide | +| **Wheel repair** | No default repair command — set `repair-wheel-command = ""` if needed | + +## Publishing the wheels + +Combine native and Pyodide wheels in a single publish step: + +```{important} +Publishing Pyodide wheels are not supported yet as of 2026/03/24. We are waiting for PEP 783 to be implemented in PyPI. +``` + +```yaml + publish: + needs: [build-native, build-pyodide] + runs-on: ubuntu-latest + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + permissions: + id-token: write # trusted publishing + steps: + - uses: actions/download-artifact@v4 + with: + pattern: wheels-* + merge-multiple: true + path: dist/ + - uses: pypa/gh-action-pypi-publish@release/v1 +``` + +## Real-world examples + +These projects use cibuildwheel with Pyodide: + +- **NumPy** — [cibuildwheel config](https://github.com/numpy/numpy/blob/main/pyproject.toml) +- **pandas** — [CI workflow](https://github.com/pandas-dev/pandas/blob/main/.github/workflows/wheels.yml) + +## Further reading + +- [cibuildwheel documentation — Pyodide platform](https://cibuildwheel.pypa.io/en/stable/options/#platform) + +## What's next? + +- [CI without cibuildwheel](ci-direct.md) — set up GitHub Actions with `pyodide build` directly +- [Publishing Wasm Wheels](publishing.md) — distribute your wheels to PyPI diff --git a/docs/how-to/compiler-flags.md b/docs/how-to/compiler-flags.md new file mode 100644 index 00000000..22b58d84 --- /dev/null +++ b/docs/how-to/compiler-flags.md @@ -0,0 +1,5 @@ +# Customizing Compiler Flags + +```{warning} +This page is under construction. +``` diff --git a/docs/how-to/debugging.md b/docs/how-to/debugging.md new file mode 100644 index 00000000..64bac351 --- /dev/null +++ b/docs/how-to/debugging.md @@ -0,0 +1,5 @@ +# Debugging Build Failures + +```{warning} +This page is under construction. +``` diff --git a/docs/how-to/migrate.md b/docs/how-to/migrate.md new file mode 100644 index 00000000..87dbb057 --- /dev/null +++ b/docs/how-to/migrate.md @@ -0,0 +1,5 @@ +# Migrating from Native Builds + +```{warning} +This page is under construction. +``` diff --git a/docs/how-to/publishing.md b/docs/how-to/publishing.md new file mode 100644 index 00000000..c595703f --- /dev/null +++ b/docs/how-to/publishing.md @@ -0,0 +1,58 @@ +# Publishing Wasm Wheels + +WebAssembly wheels built by pyodide-build are standard Python wheels — they follow the same packaging format and can be published to PyPI like any other wheel. + +```{admonition} PEP 783 +The Emscripten/WebAssembly platform tags are standardized by [PEP 783](https://peps.python.org/pep-0783/), which defines how Python supports the Emscripten platform. This means PyPI and standard Python tooling recognize these wheels as valid platform-specific distributions. +``` + +## Publishing to PyPI + +Upload with [twine](https://twine.readthedocs.io/) or any standard publishing tool: + +```bash +twine upload dist/your_package-*.whl +``` + +Or use [trusted publishing](https://docs.pypi.org/trusted-publishers/) in GitHub Actions (no API tokens needed): + +```yaml + publish: + runs-on: ubuntu-latest + permissions: + id-token: write + steps: + - uses: actions/download-artifact@v4 + with: + name: wheels + path: dist/ + - uses: pypa/gh-action-pypi-publish@release/v1 +``` + +## How users install your package + +Once published, Pyodide users can install your package in two ways: + +### In the browser (via micropip) + +```python +import micropip +await micropip.install("your-package") +``` + +[micropip](https://micropip.pyodide.org/) fetches the wheel from PyPI and installs it in the running Pyodide environment. + +### In a Pyodide venv (via pip) + +```bash +pyodide venv .venv-pyodide +source .venv-pyodide/bin/activate +pip install your-package +``` + +pip resolves the correct `pyemscripten_*_wasm32` wheel automatically. + +## What's next? + +- [CI with cibuildwheel](cibuildwheel.md) — automate building for all platforms +- [CI without cibuildwheel](ci-direct.md) — GitHub Actions with pyodide build directly diff --git a/docs/how-to/xbuildenv.md b/docs/how-to/xbuildenv.md new file mode 100644 index 00000000..16bd9523 --- /dev/null +++ b/docs/how-to/xbuildenv.md @@ -0,0 +1,5 @@ +# Managing Cross-Build Environments + +```{warning} +This page is under construction. +``` diff --git a/docs/index.md b/docs/index.md index 5bf74a1c..0efc713c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -76,9 +76,9 @@ getting-started/testing :caption: Tutorials tutorials/c-extension -tutorials/cmake-meson +tutorials/meson +tutorials/cmake tutorials/rust -tutorials/dependencies ``` ```{toctree} diff --git a/docs/recipes/authoring.md b/docs/recipes/authoring.md new file mode 100644 index 00000000..9338572b --- /dev/null +++ b/docs/recipes/authoring.md @@ -0,0 +1,5 @@ +# Recipe Authoring + +```{warning} +This page is under construction. +``` diff --git a/docs/recipes/building.md b/docs/recipes/building.md new file mode 100644 index 00000000..5d70ea86 --- /dev/null +++ b/docs/recipes/building.md @@ -0,0 +1,5 @@ +# Building Recipes + +```{warning} +This page is under construction. +``` diff --git a/docs/reference/cli.md b/docs/reference/cli.md new file mode 100644 index 00000000..93a04709 --- /dev/null +++ b/docs/reference/cli.md @@ -0,0 +1,5 @@ +# CLI Reference + +```{warning} +This page is under construction. +``` diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md new file mode 100644 index 00000000..b385b3b1 --- /dev/null +++ b/docs/reference/configuration.md @@ -0,0 +1,5 @@ +# Configuration Reference + +```{warning} +This page is under construction. +``` diff --git a/docs/reference/meta-yaml.md b/docs/reference/meta-yaml.md new file mode 100644 index 00000000..6f7c13fc --- /dev/null +++ b/docs/reference/meta-yaml.md @@ -0,0 +1,5 @@ +# meta.yaml Reference + +```{warning} +This page is under construction. +``` diff --git a/docs/reference/platform.md b/docs/reference/platform.md new file mode 100644 index 00000000..561c0607 --- /dev/null +++ b/docs/reference/platform.md @@ -0,0 +1,5 @@ +# Platform Tags and Compatibility + +```{warning} +This page is under construction. +``` diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md new file mode 100644 index 00000000..48238779 --- /dev/null +++ b/docs/troubleshooting.md @@ -0,0 +1,5 @@ +# Troubleshooting + +```{warning} +This page is under construction. +``` diff --git a/docs/tutorials/c-extension.md b/docs/tutorials/c-extension.md new file mode 100644 index 00000000..74c5be89 --- /dev/null +++ b/docs/tutorials/c-extension.md @@ -0,0 +1,216 @@ +# Tutorial: Package with C Extension + +This tutorial walks through building a Python package with a C extension for WebAssembly. We'll start with a minimal example, build it, test it, and then cover what to do when things go wrong. + +## Example package + +Consider a package `fastcount` with this layout: + +``` +fastcount/ +├── pyproject.toml +├── fastcount/ +│ ├── __init__.py +│ └── _core.c +``` + +`pyproject.toml`: + +```toml +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = "fastcount" +version = "1.0.0" + +[tool.setuptools] +ext-modules = [ + {name = "fastcount._core", sources = ["fastcount/_core.c"]} +] +``` + +`fastcount/__init__.py`: + +```python +from fastcount._core import count_chars +``` + +`fastcount/_core.c`: + +```c +#define PY_SSIZE_T_CLEAN +#include + +static PyObject* count_chars(PyObject* self, PyObject* args) { + const char* str; + char target; + if (!PyArg_ParseTuple(args, "sC", &str, &target)) + return NULL; + + long count = 0; + for (const char* p = str; *p; p++) { + if (*p == target) count++; + } + return PyLong_FromLong(count); +} + +static PyMethodDef methods[] = { + {"count_chars", count_chars, METH_VARARGS, "Count occurrences of a character."}, + {NULL, NULL, 0, NULL} +}; + +static struct PyModuleDef module = { + PyModuleDef_HEAD_INIT, "_core", NULL, -1, methods +}; + +PyMODINIT_FUNC PyInit__core(void) { + return PyModule_Create(&module); +} +``` + +## Build it + +```bash +pyodide build . +``` + +That's it. pyodide-build: + +1. Invokes setuptools to compile `_core.c` +2. Intercepts the `gcc`/`cc` call and redirects it to Emscripten's `emcc` +3. Links the compiled WebAssembly into a `.so` file (which is actually a Wasm binary) +4. Packages everything into a wheel with the `pyemscripten_*_wasm32` platform tag + +Output: + +``` +dist/fastcount-1.0.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl +``` + +## Test it + +```bash +pyodide venv .venv-pyodide +source .venv-pyodide/bin/activate +pip install dist/fastcount-*.whl +python -c "from fastcount import count_chars; print(count_chars('hello world', 'l'))" +# Output: 3 +``` + +## What happens under the hood + +When pyodide-build intercepts a compiler call, it does more than just swap `gcc` for `emcc`. It also: + +- **Filters incompatible flags** — flags like `-pthread`, `-mpopcnt`, `-mno-sse2`, and macOS-specific flags (`-bundle`, `-undefined dynamic_lookup`) are silently removed because they don't apply to WebAssembly. +- **Adds Emscripten flags** — flags like `-s SIDE_MODULE=1` are added to produce a loadable WebAssembly module. + +You can see exactly what compiler commands are being run by setting `EMCC_DEBUG=1`: + +```bash +EMCC_DEBUG=1 pyodide build . +``` + +## Export modes + +When linking a `.so` file for WebAssembly, pyodide-build needs to know which symbols to export (make visible to the Python runtime). The `--exports` flag controls this: + +| Mode | What it exports | When to use | +|---|---|---| +| `pyinit` | Only `PyInit_*` functions | Minimal exports. Works for standard Python C extensions that don't need to share symbols. | +| `requested` | All public symbols from object files | **Default.** Use when other extensions or packages may need to link against your symbols at runtime. | +| `whole_archive` | Everything | No filtering at all. Use for shared libraries or when the other modes cause missing symbol errors. Produces larger files. | + +The default is `requested`. For most packages, you don't need to change this: + +```bash +# Only if you need a different export mode: +pyodide build . --exports pyinit +pyodide build . --exports whole_archive +``` + +You can also export specific symbols by name: + +```bash +pyodide build . --exports "my_func1,my_func2" +``` + +## Common build issues + +### Missing header files + +``` +fatal error: 'some_library.h' file not found +``` + +This means your C code includes a header that isn't available in the Emscripten. + +If it's a system library, it needs to be cross-compiled for Emscripten first. pyodide-build does not allow reading headers from the host system's include paths. +This is bacause linking the library built for the host system to the WebAssembly module will cause build time / runtime errors. + +### Undefined symbols at link time + +``` +wasm-ld: error: undefined symbol: some_function +``` + +This usually means your extension depends on a C library that hasn't been compiled for WebAssembly. Check: +- Is the library available in the Emscripten sysroot? +- Does the library need to be cross-compiled for WebAssembly first? +- Try `--exports whole_archive` if the symbol should be coming from your own code. + +### Unsupported compiler features + +``` +error: unsupported option '-pthread' +``` + +pyodide-build filters out most incompatible flags automatically, but some may slip through. +You may need to conditionally disable them: + +```python +# setup.py +import os + +extra_compile_args = ["-O2"] +if os.environ.get("PYODIDE"): + # Skip flags that don't work in WebAssembly + pass +else: + extra_compile_args.append("-pthread") +``` + +The `PYODIDE` environment variable is set by pyodide-build during the build process. + +### Function pointer type mismatch + +``` +RuntimeError: function signature mismatch +``` + +WebAssembly enforces strict function pointer typing. If your C code casts function pointers to incompatible types (common in older C code), you'll get this error at runtime, not at build time. The fix is to ensure function pointer types match exactly. + +```{Tip} +This error is very common but often very tricky to debug by human eyes. Usually LLMs are quite helpful in identifying and fixing this issue. +``` + +## Using Cython + +Cython extensions work the same way — pyodide-build intercepts the C compilation step that Cython generates: + +```toml +[build-system] +requires = ["setuptools", "cython"] +build-backend = "setuptools.build_meta" +``` + +No special configuration is needed for Cython. Just run `pyodide build .` as usual. + +## What's next? + +- [Tutorial: Meson Package](meson.md) — building packages with Meson +- [Tutorial: CMake Package](cmake.md) — building packages with CMake +- [Tutorial: Rust Package](rust.md) — building packages with PyO3/Maturin +- [Customizing Compiler Flags](../how-to/compiler-flags.md) — fine-tuning the build +- [Debugging Build Failures](../how-to/debugging.md) — systematic troubleshooting diff --git a/docs/tutorials/cmake.md b/docs/tutorials/cmake.md new file mode 100644 index 00000000..e8f89255 --- /dev/null +++ b/docs/tutorials/cmake.md @@ -0,0 +1,41 @@ +# Tutorial: CMake Package + +Python packages that use [CMake](https://cmake.org/) — typically via [scikit-build-core](https://scikit-build-core.readthedocs.io/) — are supported by pyodide-build. + +## Basic usage + +If your package uses scikit-build-core or another build system that invokes CMake, you can build it directly with pyodide-build: + +```bash +pyodide build . +``` + +pyodide-build automatically intercepts `cmake` calls and configures the Emscripten toolchain, including compiler paths and build flags. + +## What the toolchain provides + +pyodide-build has a custom CMake toolchain that is used to configure the build to target Emscripten. + +The CMake toolchain that pyodide-build injects: + +- Inherits from Emscripten's own CMake toolchain +- It sets the compiler and linkers +- Sets up library search paths for the cross-build environment + +```{tip} +If automatic toolchain injection doesn't work for your setup, you can pass it explicitly: + + CMAKE_TOOLCHAIN_FILE=$(pyodide config get cmake_toolchain_file) + pyodide build . -Ccmake.toolchain="$CMAKE_TOOLCHAIN_FILE" + +Or via the `CMAKE_ARGS` environment variable: + + export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=$(pyodide config get cmake_toolchain_file)" + pyodide build . +``` + +## What's next? + +- [Tutorial: Meson Package](meson.md) — building packages with Meson / meson-python +- [Tutorial: Rust Package](rust.md) — building packages with PyO3/Maturin +- [Customizing Compiler Flags](../how-to/compiler-flags.md) — fine-tuning compiler and linker flags diff --git a/docs/tutorials/meson.md b/docs/tutorials/meson.md new file mode 100644 index 00000000..1a63eed1 --- /dev/null +++ b/docs/tutorials/meson.md @@ -0,0 +1,61 @@ +# Tutorial: Meson Package + +Many scientific Python packages use [Meson](https://mesonbuild.com/) via [meson-python](https://meson-python.readthedocs.io/) as their build system. pyodide-build supports Meson out of the box. + +## Basic usage + +For most Meson packages, just run: + +```bash +pyodide build . +``` + +pyodide-build automatically intercepts `meson setup` calls and injects the Meson cross file, which tells Meson the build is targeting Emscripten. No manual configuration is needed. + +## Passing Meson options + +Use `-Csetup-args=` to pass options to Meson: + +```bash +pyodide build . \ + -Csetup-args=-Dsome-option=value \ + -Csetup-args=-Danother-option=false +``` + +Each Meson option needs its own `-Csetup-args=` prefix. + +## Real-world example: NumPy + +NumPy uses meson-python. Here's how to build it for WebAssembly: + +```bash +pyodide build . -Csetup-args=-Dallow-noblas=true +``` + +The `-Dallow-noblas=true` disables BLAS/LAPACK (which aren't available as Emscripten libraries by default). This pattern — disabling optional native dependencies — is common when cross-compiling. + +## What the cross file provides + +The Meson cross file that pyodide-build injects tells Meson: + +- The host machine is `emscripten` / `wasm32` +- Use `node` as the executable wrapper +- Skip the compiler sanity check (Emscripten's output can't run natively) + +```{tip} +If automatic cross file injection doesn't work for your setup, you can pass it explicitly: + + MESON_CROSS_FILE=$(pyodide config get meson_cross_file) + pyodide build . -Csetup-args=--cross-file="$MESON_CROSS_FILE" + +Or via the `MESON_CROSS_FILE` environment variable: + + export MESON_CROSS_FILE=$(pyodide config get meson_cross_file) + pyodide build . +``` + +## What's next? + +- [Tutorial: CMake Package](cmake.md) — building packages with CMake / scikit-build-core +- [Tutorial: Rust Package](rust.md) — building packages with PyO3/Maturin +- [Customizing Compiler Flags](../how-to/compiler-flags.md) — fine-tuning compiler and linker flags diff --git a/docs/tutorials/rust.md b/docs/tutorials/rust.md new file mode 100644 index 00000000..7ba2dfbf --- /dev/null +++ b/docs/tutorials/rust.md @@ -0,0 +1,81 @@ +# Tutorial: Rust Package + +Python packages with Rust extensions — typically built with [PyO3](https://pyo3.rs/) and [Maturin](https://www.maturin.rs/) — can be cross-compiled for WebAssembly using pyodide-build. + +```{note} +Rust support in pyodide-build requires some manual setup compared to C/C++ packages. You need to install the correct Rust toolchain and Emscripten target yourself. +``` + +## Prerequisites + +### 1. Install Rust + +If you don't have Rust installed, use [rustup](https://rustup.rs/): + +```bash +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh +``` + +### 2. Install the correct Rust toolchain + +pyodide-build requires a specific minimum Rust toolchain version. Query it with: + +```bash +pyodide config get rust_toolchain +``` + +Install and activate it: + +```bash +RUST_TOOLCHAIN=$(pyodide config get rust_toolchain) +rustup toolchain install "$RUST_TOOLCHAIN" +rustup default "$RUST_TOOLCHAIN" +``` + +### 3. Add the Emscripten target + +The `wasm32-unknown-emscripten` target must be available for your Rust toolchain: + +```bash +RUST_TOOLCHAIN=$(pyodide config get rust_toolchain) +rustup target add wasm32-unknown-emscripten --toolchain "$RUST_TOOLCHAIN" +``` + +## Build a Rust package + +With the toolchain set up, build your Maturin/PyO3 package: + +```bash +pyodide build . +``` + +pyodide-build sets the following environment variables automatically during the build: + +| Variable | Value | Purpose | +|---|---|---| +| `CARGO_BUILD_TARGET` | `wasm32-unknown-emscripten` | Tells Cargo to cross-compile for Emscripten | +| `CARGO_TARGET_WASM32_UNKNOWN_EMSCRIPTEN_LINKER` | `emcc` | Uses Emscripten as the linker | +| `PYO3_CROSS_INCLUDE_DIR` | `/include` | PyO3 cross-compilation: Python headers location | +| `PYO3_CROSS_LIB_DIR` | `/lib` | PyO3 cross-compilation: Python library location | +| `PYO3_CROSS_PYTHON_VERSION` | `3.x` | PyO3 cross-compilation: target Python version | + +You don't need to set these manually — they come from the cross-build environment. + +## Querying Rust configuration + +Use `pyodide config` to inspect the Rust-related build settings: + +```bash +pyodide config get rust_toolchain # e.g., nightly-2025-02-01 +pyodide config get rustflags # e.g., -C link-arg=-sSIDE_MODULE=2 ... +``` + +## Limitations + +- **Nightly Rust required** — Before Python 3.14, the `wasm32-unknown-emscripten` target is not available on stable Rust. The specific nightly version must match what pyodide-build expects. + +## What's next? + +- [Tutorial: C Extension](c-extension.md) — building packages with C extensions +- [Customizing Compiler Flags](../how-to/compiler-flags.md) — fine-tuning compiler and linker flags +- [Configuration Reference](../reference/configuration.md) — all `pyodide config` values From f7c74e7680c501cdd9f748158e19a54759fd1e08 Mon Sep 17 00:00:00 2001 From: Gyeongjae Choi Date: Tue, 24 Mar 2026 19:04:27 +0900 Subject: [PATCH 4/8] remove plan file --- docs/DOCUMENTATION_PLAN.md | 434 ------------------------------------- 1 file changed, 434 deletions(-) delete mode 100644 docs/DOCUMENTATION_PLAN.md diff --git a/docs/DOCUMENTATION_PLAN.md b/docs/DOCUMENTATION_PLAN.md deleted file mode 100644 index 8db8759a..00000000 --- a/docs/DOCUMENTATION_PLAN.md +++ /dev/null @@ -1,434 +0,0 @@ -# pyodide-build Documentation Plan - -> Status: Draft -> Last updated: 2026-03-24 - -## Background - -pyodide-build has virtually no user-facing documentation. The `docs/` directory contains an empty Sphinx skeleton, and the README is 12 lines. Relevant content currently lives on pyodide.org (scattered across the Pyodide project docs) — this will be migrated here, and pyodide.org will link to these docs instead. - -This plan proposes a comprehensive documentation structure for pyodide-build as the **canonical source** for all package building documentation, following the [Diataxis framework](https://diataxis.fr/) (tutorials, how-to guides, reference, explanation). - -### Target Audience - -**Primary**: Python package maintainers who want their package to work in Pyodide/WebAssembly. -**Secondary**: Pyodide ecosystem contributors who author recipes. - -pyodide-build docs are the **canonical home** for everything related to building, testing, and publishing Python packages for Pyodide. pyodide.org will link here for build-related content. - -### Guiding Principles - -1. **This is the canonical source** — All package building docs live here. Existing content on pyodide.org (building packages, out-of-tree builds, meta.yaml spec, CLI reference) will be migrated here, and pyodide.org will link to these docs instead. -2. **Lead with the happy path** — Quickstart should be 4 commands with a working result. -3. **Explain the "why" before the "how"** — Concepts page before CLI reference. -4. **Real-world examples** — Use NumPy, pandas, matplotlib configs as proof points, not hypothetical examples. -5. **Progressive disclosure** — 80% of users need Getting Started + CI guide + Publishing. The rest serves progressively smaller audiences. - ---- - -## Document Structure - -### Part I — Getting Started - -#### 1. Overview (`index.md`) - -The landing page. Sets expectations and orients the reader. - -- What is pyodide-build? (one paragraph: "the `python -m build` for WebAssembly") -- Who is this for? (Python package maintainers, not Pyodide end-users) -- Ecosystem map diagram: pyodide-build -> pyodide-cli -> Emscripten -> Pyodide runtime -- Quick links to the three main workflows: Build -> Test -> Ship - -#### 2. Installation (`getting-started/installation.md`) - -- `pip install pyodide-build` (also: `pipx install`, `uv tool install`, `uvx`) -- Version requirements: Python >= 3.12, Node.js (for venv testing) -- Verify installation: `pyodide --version` -- Optional extras: `pip install pyodide-build[resolve]` for dependency resolution - -#### 3. Concepts (`getting-started/concepts.md`) - -Explain the mental model before showing commands. This addresses a major user pain point — people don't understand what xbuildenv is or why they need Emscripten. - -- **Why cross-compilation?** Python packages with C extensions must be compiled for the target platform. Pyodide's target is Emscripten/WebAssembly. -- **The cross-build environment (xbuildenv)**: pre-built CPython headers, sysconfig data, and package stubs. Analogous to a sysroot in cross-compilation. -- **Emscripten SDK**: the compiler toolchain that turns C/C++ into WebAssembly. Managed automatically by pyodide-build. -- **Platform tags**: `pyemscripten_2025_0_wasm32` — what each part means, ABI versioning, the PEP 783 specification. -- **Side-by-side comparison**: `python -m build` vs `pyodide build` — what's the same, what's different. - -#### 4. Quick Start (`getting-started/quickstart.md`) - -The "5-minute" path. Build a package with a C extension for Pyodide. - -- Callout: **Pure-Python packages don't need pyodide-build.** A pure-Python wheel built with `python -m build` (or any standard build frontend) is already compatible with Pyodide — no special tooling required. pyodide-build is for packages that contain C, C++, or Rust extensions. - -``` -pip install pyodide-build -pyodide xbuildenv install -pyodide build . -ls dist/ # -> your_package-1.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl -``` - -- Step 1: Install pyodide-build -- Step 2: Install the cross-build environment (one sentence explanation, link to Concepts) -- Step 3: Build from your source tree (`pyodide build .`) -- Step 4: Inspect the output wheel — what the platform tag means -- Callout box: "From `python -m build` to `pyodide build`" migration comparison - -#### 5. Testing with `pyodide venv` (`getting-started/testing.md`) - -Immediately after building, show how to verify the wheel works. - -``` -pyodide venv .venv-pyodide -source .venv-pyodide/bin/activate -pip install dist/your_package-*.whl -python -c "import your_package; print('works!')" -``` - -- What `pyodide venv` does differently from `python -m venv` (Node.js + Pyodide runtime as interpreter) -- Installing your wheel — pip inside the venv only accepts Wasm-compatible wheels -- Running tests: `python -m pytest` inside the venv runs on Pyodide/Node.js -- "What's weird about this venv": pip runs on host Python, but `python` invokes Pyodide/Node.js -- Note: requires Node.js - - ---- - -### Part II — Tutorials (learning-oriented, end-to-end walkthroughs) - -Each tutorial walks through a complete scenario from start to finish. - -#### 6. Tutorial: Package with C Extension (`tutorials/c-extension.md`) - -- Setuptools/distutils package with a `.c` file -- What happens under the hood: pywasmcross intercepts `gcc` calls and redirects to `emcc` -- Export modes explained in context: `pyinit` (default) vs `requested` vs `whole_archive` -- Debugging a build failure (practical example with a real error) - -#### 7a. Tutorial: Meson Package (`tutorials/meson.md`) - -- `pyodide config get meson_cross_file` -- The `-Csetup-args=--cross-file=...` pattern -- Real-world example: NumPy -- `--no-isolation` mode for complex build environments - -#### 7b. Tutorial: CMake Package (`tutorials/cmake.md`) - -- `pyodide config get cmake_toolchain_file` -- scikit-build-core integration -- pybind11 and nanobind examples (via CMake and setuptools) - -#### 8. Tutorial: Rust Package (PyO3/Maturin) (`tutorials/rust.md`) - -- Rust toolchain auto-setup (`wasm32-unknown-emscripten` target) -- Key environment variables: `CARGO_BUILD_TARGET`, `RUSTFLAGS`, `PYO3_CROSS_*` -- `pyodide config get rust_toolchain` and `rustflags` -- Example: building a simple PyO3 extension - -#### 9. Tutorial: Building with Dependencies (`tutorials/dependencies.md`) - -- Installing the resolve extra: `pip install pyodide-build[resolve]` -- `pyodide build --build-dependencies` — auto-resolves and builds the dependency tree -- Skipping built-in packages (`--skip-built-in-packages`) and specific deps (`--skip-dependency `) -- Building from a requirements file: `-r requirements.txt` -- Exporting resolved dependencies: `--output-lockfile` -- Practical example: building a package that needs numpy + scipy at runtime - ---- - -### Part III — How-to Guides (task-oriented, for working developers) - -Each guide solves a specific task. Assumes the reader has basic familiarity from Parts I-II. - -#### 10. CI with cibuildwheel (`how-to/cibuildwheel.md`) - -This is likely the **highest-value section** after the quickstart — many users encounter pyodide-build through cibuildwheel. - -- Why cibuildwheel: build for Linux, macOS, **and** Pyodide in one CI config -- Pyodide support history: added in cibuildwheel v2.19.0, current at v3.4.0 -- Platform identifiers: `cp312-pyodide_wasm32`, `cp313-pyodide_wasm32` -- Minimal `pyproject.toml` configuration: - ```toml - [tool.cibuildwheel] - build = ["cp312-*", "cp313-*"] - - [tool.cibuildwheel.pyodide] - test-command = "python -m pytest {project}/tests -x" - test-requires = ["pytest"] - ``` -- Complete GitHub Actions workflow (copy-paste-ready, Pyodide as separate job) -- Key constraints: - - Must explicitly set `CIBW_PLATFORM=pyodide` — auto-detection won't select it - - `pip` frontend NOT supported — only `build` or `build[uv]` - - Linux/macOS only — cannot build on Windows runners - - Tests must use `python -m pytest`, not bare `pytest` - - No default wheel repair — most projects set `repair-wheel-command = ""` -- Real-world config examples from: NumPy, pandas, matplotlib, Rust+Pyodide projects -- Link to cibuildwheel's Pyodide platform docs - -#### 11. CI without cibuildwheel (`how-to/ci-direct.md`) - -For projects that don't use cibuildwheel or want more control. - -- Direct GitHub Actions workflow using `pyodide build` commands -- Matrix builds across Pyodide versions -- Caching the xbuildenv for faster CI runs -- Testing step with `pyodide venv` - -#### 12. Publishing Wasm Wheels (`how-to/publishing.md`) - -- Publishing to PyPI: standard `twine upload` / trusted publishing works — Wasm wheels are regular wheels -- Platform tag format: `pyemscripten_YYYY_P_wasm32` (per PEP 783; older versions used `pyodide_YYYY_P_wasm32`) -- How Pyodide users consume your wheel: `micropip.install("your-package")` in the browser, or `pip install` inside a `pyodide venv` -- Complete CI example: build with cibuildwheel -> publish with trusted publishing -- Admonition (single note): PEP 783 formalizes the Emscripten platform tags — link to the PEP for details on the platform specification - -#### 13. Migrating from Native Builds (`how-to/migrate.md`) - -Addresses a major user pain point: "I already build native wheels, what do I change?" - -- Side-by-side comparison: `python -m build` workflow vs `pyodide build` workflow -- Common issues when adapting: - - `pthreads` (not supported in Wasm) - - SIMD intrinsics / inline assembly - - Filesystem assumptions (limited in Wasm) - - Networking code (no sockets in Wasm) - - 64-bit integer assumptions -- Conditional compilation: detecting Pyodide at build time: - - C/C++: `#ifdef __EMSCRIPTEN__` - - Python: `os.environ.get("PYODIDE")` (build-time), `sys.platform == "emscripten"` (runtime) - -#### 14. Managing Cross-Build Environments (`how-to/xbuildenv.md`) - -- Install: `pyodide xbuildenv install [version]` -- List installed: `pyodide xbuildenv versions` -- Switch active: `pyodide xbuildenv use ` -- Uninstall: `pyodide xbuildenv uninstall [version]` -- Search available: `pyodide xbuildenv search [--all] [--json]` -- Path resolution order: `PYODIDE_XBUILDENV_PATH` env var -> pyproject.toml -> platform cache dir -> cwd -- Pinning a version in pyproject.toml (`xbuildenv_path` or `default_cross_build_env_url`) -- Emscripten SDK management: `pyodide xbuildenv install-emscripten` -- Lazy cross-build package installation (packages installed on first use, not eagerly) - -#### 15. Customizing Compiler Flags (`how-to/compiler-flags.md`) - -For power users who need to tweak the build. - -- Default flags and what they do: - - `-Oz` (optimize for size), `SIDE_MODULE=1` (Emscripten side module) -- Overriding via `pyproject.toml` `[tool.pyodide.build]`: - ```toml - [tool.pyodide.build] - cflags = "$(CFLAGS_BASE) -I$(PYTHONINCLUDE) -O2" - ``` -- Overriding via environment variables: `CFLAGS`, `CXXFLAGS`, `LDFLAGS` (appended to defaults) -- What pywasmcross silently filters out: - - `-pthread` (threading disabled) - - macOS-specific flags (`-bundle`, `-undefined dynamic_lookup`) - - x86 SIMD flags (`-mpopcnt`, `-mno-sse2`, etc.) - -- CMake toolchain file and Meson cross-file integration - -#### 16. Debugging Build Failures (`how-to/debugging.md`) - -Systematic troubleshooting guide organized by failure phase. - -- **Phase 1: Environment errors** - - "No Emscripten compiler found" -> install xbuildenv - - "Version X is not compatible" -> Python/pyodide-build version mismatch - - "local Python version does not match" -> Python changed after xbuildenv install -- **Phase 2: Compilation errors** - - Missing headers -> check include paths - - Incompatible C/C++ code -> pthread, SIMD, inline assembly - - Function pointer cast errors -> Wasm strict typing -- **Phase 3: Link errors** - - Missing symbols -> check export mode (`pyinit` vs `requested` vs `whole_archive`) - - Duplicate symbols -> wasm-ld doesn't allow duplicate `-l` flags (pywasmcross deduplicates) -- **Phase 4: Build system errors** - - CMake/Meson configuration failures -> cross-file not passed - - scikit-build-core issues -> `CMAKE_EXECUTABLE` env var -- **Phase 5: Runtime errors** - - "Wheel works in browser but fails in venv" -> testing environment differences - ---- - -### Part IV — Recipe System (for Pyodide ecosystem contributors) - -Separate audience — most users never need this. - -#### 17. Recipe Authoring (`recipes/authoring.md`) - -- What is a recipe? A `meta.yaml` file that declares how to build a package for Pyodide's package ecosystem. -- When do you need a recipe vs. just `pyodide build`? - - Recipe: contributing to the Pyodide built-in packages set - - `pyodide build`: building your own package for distribution -- Generating a recipe: `pyodide skeleton pypi ` -- `meta.yaml` walkthrough with annotated example -- Build types: `package`, `static_library`, `shared_library`, `cpython_module` -- Source handling: URL vs local path, sha256 checksums, patches, extras -- Build customization: `cflags`, `ldflags`, `backend-flags`, `script`, `post` -- Requirements: `run` (runtime), `host` (build-time), `executable` (e.g., rustc), `constraint` -- Cross-build support: `cross-build-env`, `cross-build-files` -- Test imports validation - -#### 18. Building Recipes (`recipes/building.md`) - -- `pyodide build-recipes` — dependency graph resolution + parallel builds -- `pyodide build-recipes-no-deps` — building individual packages without resolution -- `pyodide clean recipes` — cleaning build artifacts -- Recipe lifecycle management: - - `pyodide skeleton enable ` / `disable -m "reason"` - - `pyodide skeleton pin -m "reason"` - ---- - -### Part V — Reference (information-oriented, exhaustive) - -#### 19. CLI Reference (`reference/cli.md`) - -Complete option tables for every command. Consider auto-generating from Click's `--help` output. - -Commands to document: -- `pyodide build` — all arguments and options with defaults, env var mappings -- `pyodide venv` — arguments and options -- `pyodide xbuildenv` — all subcommands: `install`, `version`, `versions`, `uninstall`, `use`, `search`, `install-emscripten` -- `pyodide config` — subcommands: `list`, `get` -- `pyodide build-recipes` — all options -- `pyodide build-recipes-no-deps` — all options -- `pyodide skeleton` — subcommands: `pypi`, `enable`, `disable`, `pin` -- `pyodide py-compile` — arguments and options -- `pyodide clean recipes` — arguments and options - -#### 20. Configuration Reference (`reference/configuration.md`) - -- Configuration precedence: env vars > pyproject.toml > Makefile.envs > defaults -- Complete `[tool.pyodide.build]` key reference table: - - | Key | Env Var | Default | Description | - |---|---|---|---| - | `cflags` | `SIDE_MODULE_CFLAGS` | `$(CFLAGS_BASE) -I$(PYTHONINCLUDE) -Oz` | C compiler flags | - | `cxxflags` | `SIDE_MODULE_CXXFLAGS` | `$(CFLAGS_BASE) -Oz` | C++ compiler flags | - | `ldflags` | `SIDE_MODULE_LDFLAGS` | `$(LDFLAGS_BASE) -s SIDE_MODULE=1 -Oz` | Linker flags | - | `rustflags` | `RUSTFLAGS` | `-C link-arg=-sSIDE_MODULE=2 ...` | Rust compiler flags | - | `rust_toolchain` | `RUST_TOOLCHAIN` | `nightly-2025-02-01` | Rust toolchain version | - | `meson_cross_file` | `MESON_CROSS_FILE` | `/emscripten.meson.cross` | Meson cross file | - | `xbuildenv_path` | `PYODIDE_XBUILDENV_PATH` | platform cache dir | xbuildenv location | - | `ignored_build_requirements` | `IGNORED_BUILD_REQUIREMENTS` | `patchelf oldest-supported-numpy` | Build deps to ignore | - | ... | ... | ... | ... | - -- Environment variables reference table (all `PYODIDE_*` vars) -- `$(VAR)` substitution syntax in config values - -#### 21. meta.yaml Reference (`reference/meta-yaml.md`) - -- Complete field reference with types, defaults, validation rules -- All sections: `package`, `source`, `build`, `requirements`, `test`, `about`, `extra` -- Validation error messages and what triggers them -- Migrated from pyodide.org's meta.yaml spec — this becomes the canonical reference - -#### 22. Platform Tags & Compatibility (`reference/platform.md`) - -- Platform version <-> Python version <-> Emscripten version matrix: - - | Platform Tag | Python | Notes | - |---|---|---| - | `pyodide_2024_0_wasm32` | 3.12 | Legacy tag name | - | `pyemscripten_2025_0_wasm32` | 3.13 | PEP 783 standardized name | - | `pyemscripten_2026_0_wasm32` | 3.14 | PEP 783 standardized name | - -- Wheel naming format explained -- PEP 783 (Emscripten/WebAssembly platform) — the formal specification for these tags -- ABI compatibility rules: wheels are NOT cross-version compatible -- cibuildwheel identifier mapping: `cp312-pyodide_wasm32`, `cp313-pyodide_wasm32` - ---- - -### Part VI — Explanation (understanding-oriented) - -#### 23. How pyodide-build Works (`explanation/architecture.md`) - -For users who want to understand the internals. - -- The build pipeline: source -> pypa/build -> pywasmcross wrapper -> emcc -> .wasm -> wheel -- The compiler wrapper (pywasmcross): intercepts cc/gcc/g++ calls, translates flags, redirects to emcc/em++ -- Symlinks created: `cc`, `c++`, `ld`, `ar`, `cmake`, `meson`, `cargo`, etc. -- Why `SIDE_MODULE` and symbol exports matter -- Flag filtering: what gets removed and why (pthreads, macOS flags, SIMD, etc.) - -#### 24. The Pyodide Ecosystem (`explanation/ecosystem.md`) - -- Package relationships: - - `pyodide-cli`: the dispatcher that routes `pyodide ` to plugins - - `pyodide-build`: registers all build commands as pyodide-cli plugins - - `pyodide-lock`: the lockfile format library - - `auditwheel-emscripten`: wheel repair/inspection for Wasm wheels - - `micropip`: runtime package installer (browser-side) -- How users consume your wheel: `micropip.install()` in the browser or `pip install` in a pyodide venv -- The relationship between pyodide-build and the main Pyodide project - ---- - -### Appendix - -#### 25. Troubleshooting (`troubleshooting.md`) - -Organized by error message for searchability. - -- "No Emscripten compiler found" -> install xbuildenv or check `PYODIDE_SKIP_EMSCRIPTEN_INSTALL` -- "Version X is not compatible with the current environment" -> Python/pyodide-build version mismatch, use `--force` -- "local Python version does not match" -> Python changed after xbuildenv install, reinstall xbuildenv -- "MissingOptionalDependencyError" -> `pip install pyodide-build[resolve]` -- "Can't find package: " -> PyPI resolution failure -- "PIP_CONSTRAINT contains spaces" -> move project to a path without spaces -- Build failures with C extensions -> check filtered flags, threading, SIMD -- Wheel is too large -> compression level, `unvendor-tests`, `-Oz` vs `-O2` tradeoff - - -#### 26. FAQ (`faq.md`) - -- "Which packages work with Pyodide?" — Pure Python = always. C extensions = usually. Threading/multiprocessing = no. Filesystem-heavy = maybe. Networking = no. -- "What's the difference between `pyodide build` and `pyodide build-recipes`?" — Out-of-tree single package build vs in-tree recipe system with dependency resolution. -- "Can I use maturin/meson-python/scikit-build-core?" — Yes, with cross-file configuration. -- "Do I need the full Pyodide repo?" — No, pyodide-build is standalone. -- "What Node.js version do I need?" — v22+ recommended (for pyodide venv). -- "Should I use `pyodide build` directly or cibuildwheel?" — cibuildwheel if you already build native wheels and want one CI config. `pyodide build` directly if you only target Pyodide or want more control. -- "Can I publish Wasm wheels to PyPI?" — Yes. Upload with `twine` or trusted publishing like any other wheel. - -#### 27. Changelog - -Link to `CHANGELOG.md`. Highlight breaking changes between versions: -- **Unreleased**: `-Oz` replaces `-O2` default, `vendor_sharedlib` defaults to `true` -- **v0.33.0**: Emscripten auto-install -- **v0.32.0**: typer -> click CLI framework migration -- **v0.31.0**: Windows support for `pyodide venv` -- **v0.30.0**: uv support, xbuildenv moved to cache dir - ---- - -## Reader Journey Map - -| Reader Profile | Sections They Need | Time | -|---|---|---| -| "I have 5 minutes, show me it works" | 1, 2, 4, 5 | 10 min | -| "I have a C extension package" | + 6, 7 | + 30 min | -| "I want CI for my project" | + 10 or 11 | + 15 min | -| "I want to publish" | + 12 | + 10 min | -| "My build is failing" | 16, 25 | lookup | -| "I need custom compiler flags" | 15, 20 | lookup | -| "I want to contribute a Pyodide recipe" | 17, 18, 21 | 30 min | -| "I want to understand the internals" | 23, 24 | 30 min | - -**80% of users** need only: **Getting Started (1-5) + CI guide (10) + Publishing (12)**. - -## Implementation Notes - -- The `docs/` directory already has Sphinx + myst-parser configured (`.readthedocs.yaml`, `conf.py`). Write in Markdown (`.md`), not reStructuredText. -- Consider auto-generating the CLI Reference (Section 20) from Click's `--help` output to stay in sync. -- Real-world examples (NumPy, pandas, matplotlib cibuildwheel configs) should be kept up-to-date or link to the source repos directly. -- PEP 783 is assumed accepted throughout the docs. A single admonition in the Publishing guide (Section 13) links to the PEP for the formal platform specification. No scattered caveats elsewhere. -- **Migration from pyodide.org**: The following pyodide.org pages should be migrated here and replaced with redirects/links: - - `development/building-packages.html` → Sections 4, 6, 10 - - `development/building-packages-from-source.html` → Sections 6, 7, 16 - - `development/meta-yaml.html` → Section 21 - - `usage/api/pyodide-cli.html` (build-related commands) → Section 19 From 4c963846a37a2b06dc1e0e1b2d70b95e5efbfb62 Mon Sep 17 00:00:00 2001 From: Gyeongjae Choi Date: Fri, 27 Mar 2026 17:07:17 +0900 Subject: [PATCH 5/8] More docs --- .../img/debugging/signature-mismatch1.png | Bin 0 -> 156769 bytes .../img/debugging/signature-mismatch2.png | Bin 0 -> 17580 bytes .../img/debugging/signature-mismatch3.png | Bin 0 -> 46340 bytes .../img/debugging/signature-mismatch4.png | Bin 0 -> 8576 bytes docs/changelog.md | 4 +- docs/conf.py | 2 +- docs/explanation/architecture.md | 93 +++++++- docs/explanation/ecosystem.md | 5 - docs/faq.md | 39 +++- docs/how-to/compiler-flags.md | 87 +++++++- docs/how-to/debugging.md | 208 +++++++++++++++++- docs/how-to/migrate.md | 134 ++++++++++- docs/how-to/xbuildenv.md | 128 ++++++++++- docs/index.md | 12 - docs/recipes/authoring.md | 5 - docs/recipes/building.md | 5 - docs/reference/cli.md | 148 ++++++++++++- docs/reference/configuration.md | 56 ++++- docs/reference/meta-yaml.md | 5 - docs/reference/platform.md | 63 +++++- docs/troubleshooting.md | 5 - 21 files changed, 939 insertions(+), 60 deletions(-) create mode 100644 docs/_static/img/debugging/signature-mismatch1.png create mode 100644 docs/_static/img/debugging/signature-mismatch2.png create mode 100644 docs/_static/img/debugging/signature-mismatch3.png create mode 100644 docs/_static/img/debugging/signature-mismatch4.png delete mode 100644 docs/explanation/ecosystem.md delete mode 100644 docs/recipes/authoring.md delete mode 100644 docs/recipes/building.md delete mode 100644 docs/reference/meta-yaml.md delete mode 100644 docs/troubleshooting.md diff --git a/docs/_static/img/debugging/signature-mismatch1.png b/docs/_static/img/debugging/signature-mismatch1.png new file mode 100644 index 0000000000000000000000000000000000000000..4e5708500e1a2544f979a50303dda8d232d0468e GIT binary patch literal 156769 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ΞJ2MUQDEWEP5j5 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 G{{IEx$}+h?wzaWso4Iy3(lPZft>x9th7|`% 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 literal 0 HcmV?d00001 diff --git a/docs/_static/img/debugging/signature-mismatch3.png b/docs/_static/img/debugging/signature-mismatch3.png new file mode 100644 index 0000000000000000000000000000000000000000..c658f7cd80a9450ee2c9466cc92eaca0783e84d7 GIT binary patch literal 46340 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%0DMGX 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 literal 0 HcmV?d00001 diff --git a/docs/changelog.md b/docs/changelog.md index 3faf3751..667ccf08 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,5 +1,5 @@ # Changelog -```{warning} -This page is under construction. +```{include} ../CHANGELOG.md +:start-line: 2 ``` diff --git a/docs/conf.py b/docs/conf.py index adc43448..9db41351 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -28,7 +28,7 @@ } templates_path = ["_templates"] -exclude_patterns = ["_build", "Thumbs.db", ".*", "DOCUMENTATION_PLAN.md"] +exclude_patterns = ["_build", "Thumbs.db", ".*"] # -- Options for HTML output ------------------------------------------------- diff --git a/docs/explanation/architecture.md b/docs/explanation/architecture.md index e15de236..7ff29bac 100644 --- a/docs/explanation/architecture.md +++ b/docs/explanation/architecture.md @@ -1,5 +1,94 @@ # How pyodide-build Works -```{warning} -This page is under construction. +This page explains the internals of pyodide-build — how it turns a regular Python package into a WebAssembly wheel. + +## The build pipeline + +When you run `pyodide build .`, the following happens: + ``` +┌────────────────┐ +│ pyodide build │ CLI entry point +└───────┬────────┘ + │ + ▼ +┌────────────────┐ +│ Environment │ Install xbuildenv + Emscripten SDK (if needed) +│ setup │ Set up sysconfig, headers, env vars +└───────┬────────┘ + │ + ▼ +┌────────────────┐ +│ pypa/build │ Standard PEP 517 build frontend +│ │ Invokes your build backend (setuptools, meson-python, etc.) +└───────┬────────┘ + │ Build backend calls gcc, g++, cmake, meson, cargo... + ▼ +┌────────────────┐ +│ pywasmcross │ Compiler wrapper — intercepts all tool calls +│ │ Redirects to Emscripten (emcc, em++, emar, etc.) +│ │ Filters incompatible flags, adds Wasm flags +└───────┬────────┘ + │ + ▼ +┌────────────────┐ +│ Emscripten │ Compiles C/C++ → WebAssembly (.o, .a, .so) +│ (emcc/em++) │ Links as SIDE_MODULE +└───────┬────────┘ + │ + ▼ +┌────────────────┐ +│ Wheel output │ .so files (Wasm) + Python files → .whl +│ │ Tagged: pyemscripten_YYYY_P_wasm32 +└────────────────┘ +``` + +## The compiler wrapper (pywasmcross) + +The core of pyodide-build is `pywasmcross` — a compiler wrapper that transparently redirects native compiler calls to Emscripten. + +### How it works + +When pyodide-build sets up the build environment, it creates symlinks named after common compiler tools: + +| Symlink | Redirects to | +|---|---| +| `cc`, `gcc` | `emcc` | +| `c++`, `g++` | `em++` | +| `ar` | `emar` | +| `ranlib` | `emranlib` | +| `strip` | `emstrip` | +| `cmake` | `emcmake cmake` (with toolchain flags) | +| `meson` | `meson` (with cross file injected) | +| `cargo` | `cargo` (with Emscripten target) | + +These symlinks all point to `pywasmcross.py`. When invoked, pywasmcross: + +1. Detects which tool it's impersonating (from the symlink name) +2. Rewrites the command line for Emscripten +3. Filters out incompatible flags +4. Adds WebAssembly-specific flags +5. Executes the real Emscripten tool + +When `pyodide build` runs: + +1. `Makefile.envs` is parsed to set compiler flags, paths, and environment variables +2. The `sysconfig` module is patched to return target-platform values instead of host values +3. `PATH` is modified so pywasmcross symlinks take priority over native compilers +4. Environment variables (`SIDE_MODULE_CFLAGS`, `CMAKE_TOOLCHAIN_FILE`, `MESON_CROSS_FILE`, etc.) are set + +## Build isolation + +By default, `pyodide build` uses [pypa/build](https://build.pypa.io/) in isolated mode — just like `python -m build`. This means: + +1. A temporary virtual environment is created +2. Build dependencies from `[build-system].requires` are installed +3. The build backend is invoked +4. The virtual environment is discarded + +The `--no-isolation` flag skips this and uses the current environment, which is useful for complex builds where you need to manage dependencies yourself. + +## Further reading + +- [Emscripten documentation](https://emscripten.org/docs/) — the underlying compiler toolchain +- [PEP 517](https://peps.python.org/pep-0517/) — Python build system interface diff --git a/docs/explanation/ecosystem.md b/docs/explanation/ecosystem.md deleted file mode 100644 index 2c5a1330..00000000 --- a/docs/explanation/ecosystem.md +++ /dev/null @@ -1,5 +0,0 @@ -# The Pyodide Ecosystem - -```{warning} -This page is under construction. -``` diff --git a/docs/faq.md b/docs/faq.md index 1992ec4e..e828d1b2 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -1,5 +1,38 @@ # FAQ -```{warning} -This page is under construction. -``` +## Do I need the full Pyodide repository? + +No. pyodide-build is a standalone package. Install it with `pip install pyodide-build` and you're ready to build. You don't need to clone the Pyodide repository. + +## Do I need pyodide-build for pure-Python packages? + +No. A pure-Python wheel built with `python -m build`, `hatch`, `flit`, or any standard build frontend is already compatible with Pyodide. pyodide-build is only needed for packages with compiled extensions (C, C++, Rust). + +## Should I use `pyodide build` directly or cibuildwheel? + +- **cibuildwheel** — if you already build native wheels for Linux/macOS and want to add Pyodide as another platform in the same CI config. +- **`pyodide build` directly** — if you only target Pyodide, want more control, or don't use cibuildwheel yet. + +See [CI with cibuildwheel](how-to/cibuildwheel.md) and [CI without cibuildwheel](how-to/ci-direct.md). + +## Can I use meson-python / scikit-build-core / maturin? + +Yes. pyodide-build supports all major Python build backends: + +- **setuptools** — works out of the box +- **meson-python** — cross file injected automatically. See [Tutorial: Meson](tutorials/meson.md). +- **scikit-build-core** — CMake toolchain handled automatically. See [Tutorial: CMake](tutorials/cmake.md). +- **maturin** — Rust target and flags set automatically. See [Tutorial: Rust](tutorials/rust.md). +- **hatchling / flit** — pure-Python only (no compiled extensions), so no pyodide-build needed. + +## What Node.js version do I need? + +Node.js >= 24 is recommended for `pyodide venv`. Node.js is only needed for testing — not for building. + +## What Python versions are supported? + +pyodide-build requires Python 3.12 or later. The Python version must match the target Pyodide cross-build environment version. + +## What's the difference between `pyodide build` and `python -m build`? + +`pyodide build` wraps `python -m build` with a cross-compilation layer. Your build configuration stays the same — pyodide-build intercepts compiler calls and redirects them to Emscripten. See [Concepts](getting-started/concepts.md) for a detailed comparison. diff --git a/docs/how-to/compiler-flags.md b/docs/how-to/compiler-flags.md index 22b58d84..0aa32239 100644 --- a/docs/how-to/compiler-flags.md +++ b/docs/how-to/compiler-flags.md @@ -1,5 +1,88 @@ # Customizing Compiler Flags -```{warning} -This page is under construction. +pyodide-build sets default compiler and linker flags required/optimized for WebAssembly modules. +You can inspect, override, and extend these flags for your build. + +## Default flags + +You can inspect the default values we use by running: + +```bash +pyodide config get cflags +pyodide config get cxxflags +pyodide config get ldflags +``` + +Note that the default flag differs per Pyodide version you target. + +## Overriding flags + +You can override flags in multiple ways: + +### via pyproject.toml + +```toml +[tool.pyodide.build] +cflags = "-O2 -g2" +cxxflags = "-O2 -g2" +ldflags = "-O2 -g2" +``` + +## via environment variables + +Set environment variables before running `pyodide build`: + +```bash +export CFLAGS="$(pyodide config get cflags) -DMY_DEFINE=1" +pyodide build . ``` + +Environment variables take precedence over `pyproject.toml` settings. + +## Configuration precedence + +Flags are resolved in this order (highest priority first): + +1. Environment variables +2. `pyproject.toml` `[tool.pyodide.build]` +3. Cross-build environment defaults + +## Flags that are automatically filtered + +pyodide-build's compiler wrapper automatically removes flags that are incompatible with Emscripten/WebAssembly: + +These are the non-exhaustive list of flags that are filtered. +If you find any flags that are not filtered but should be or vice versa, please let us know. + +| Filtered flag | Reason | +|---|---| +| `-pthread` | Threading is not supported | +| `-bundle`, `-undefined dynamic_lookup` | macOS-specific linker flags | +| `-mpopcnt`, `-mno-sse2`, `-mno-avx2` | x86 SIMD flags (not applicable to Wasm) | +| `-Bsymbolic-functions` | GCC-specific flag not supported by Clang | +| `-fstack-protector` | Not supported in Emscripten | +| `-L/usr/*` | System library paths (not valid for cross-compilation) | + +These are stripped silently — you don't need to remove them from your build scripts. + +## Rust flags + +Rust compiler flags are configured separately: + +```bash +pyodide config get rustflags +# e.g., -C link-arg=-sSIDE_MODULE=2 -C link-arg=-sWASM_BIGINT +``` + +Override in `pyproject.toml`: + +```toml +[tool.pyodide.build] +rustflags = "-C link-arg=-sSIDE_MODULE=2 -C link-arg=-sWASM_BIGINT -C opt-level=2" +``` + +## What's next? + +- [Debugging Build Failures](debugging.md) — troubleshooting when the build fails +- [Configuration Reference](../reference/configuration.md) — all configuration options +- [How pyodide-build Works](../explanation/architecture.md) — how the compiler wrapper works diff --git a/docs/how-to/debugging.md b/docs/how-to/debugging.md index 64bac351..0e3e0001 100644 --- a/docs/how-to/debugging.md +++ b/docs/how-to/debugging.md @@ -1,5 +1,209 @@ # Debugging Build Failures -```{warning} -This page is under construction. +There are several common failures that can occur when building packages with pyodide-build. This guide helps you identify the phase and apply the right fix. + +## Configuration errors + +### CMake: "Could not find toolchain file" + +The CMake toolchain file wasn't found or passed correctly. + +**Fix**: pyodide-build injects the toolchain automatically. If it doesn't work: + +```bash +CMAKE_TOOLCHAIN_FILE=$(pyodide config get cmake_toolchain_file) +pyodide build . -Ccmake.toolchain="$CMAKE_TOOLCHAIN_FILE" +``` + +### Meson: "Cross file not found" or wrong target architecture + +The Meson cross file wasn't injected or passed correctly. + +**Fix**: + +```bash +MESON_CROSS_FILE=$(pyodide config get meson_cross_file) +pyodide build . -Csetup-args=--cross-file="$MESON_CROSS_FILE" +``` + +## Compilation errors + +### "'something.h' file not found" + +These may fall into two categories: + +1. system headers that is not supported by Emscripten +2. a third party header that is not linked properly + +If the header is from a system library, search it in the Emscripten repository to check +if it's available. If it's not available, you need to update your code to use a different approach. + +If the header is from a third party library, check if it's searched and linked properly. +As you need a cross-compiled version of the library, you need to check if `pkg-config` or `CMake` +or other build systems are configured to find the cross-compiled version correctly. + +### "error: unsupported option '-some-config'" + +It means that the Emscripten compiler doesn't support the option. + +**Fix**: Conditionally disable the flag using the `PYODIDE` environment variable: + +```python +import os +if not os.environ.get("PYODIDE"): + extra_compile_args.append("-some-config") +``` + +### "error: use of undeclared identifier" (platform-specific code) + +Code uses platform-specific APIs (Linux, macOS, Windows) that don't exist in Emscripten. + +**Fix**: Guard with `__EMSCRIPTEN__`: + +```c +#ifdef __EMSCRIPTEN__ +// Emscripten-compatible code +#else +// Platform-specific code +#endif +``` + +## Link errors + +### "wasm-ld: error: undefined symbol: some_function" + +A function is referenced but not defined in any linked object. + +**Fixes**: +- Check if a library needs to be compiled for Emscripten first. +- Make sure you are linking the correct library at the link step. +- Try a different export mode: `pyodide build . --exports whole_archive` +- If the symbol comes from Python itself, it should be available — file an issue + +### "wasm-ld: error: function signature mismatch" + +This is a very common error coming from legacy C/C++ code that was not designed with WebAssembly in mind. + +In C, function signatures are not strictly checked at compile time, but WebAssembly requires strict signature matching. + +``` +wasm-ld: error: function signature mismatch: some_func +>>> defined as (i32, i32) -> i32 in some_static_lib.a(a.o) +>>> defined as (i32) -> i32 in b.o +``` + +**Fix**: Check the signatures of the conflicting functions and fix them to match. + +### "wasm-ld: error: duplicate symbol" + +The same symbol is defined in multiple objects. + +This commonly happens when you are linking the same static library multiple times into different object files. + +**Fixes**: +- Try to switch to the shared library if available. +- Try to avoid linking the same static library multiple times. +- If you are using `--exports whole_archive`, try using `--exports default` instead. It will reduce the number of symbols that are exported. + +### "RuntimeError: function signature mismatch" + +This is a **runtime** error (not a build error) that occurs when calling a function pointer with the wrong type. WebAssembly enforces strict function pointer typing — unlike native platforms which may silently allow mismatches. The most common cause is confusion between `i32` return type and `void` return type in C function pointer casts. + +This is a common but also a tricky error to debug. Here are some steps to help you diagnose and fix it: + +1. Rebuild the package with debug symbols enabled. + +use `CFLAGS='-g2'` compiler flag set to enable debug symbols. This will rename the symbols in the Wasm file to make them more readable. + +2. Open the browser's developer tools and look at the stack trace. + +Use a Chromium-based browser (they have the best Wasm debugging support). +The browser console will show a stack trace — click on the innermost stack frame: + +```{image} /_static/img/debugging/signature-mismatch1.png +:alt: Function signature mismatch stack trace +``` + +Clicking the offset will take you to the corresponding Wasm instruction, which should be a `call_indirect`. This shows the expected function signature: + +```{image} /_static/img/debugging/signature-mismatch2.png +:alt: Wasm call_indirect instruction showing expected signature +``` + +So we think we are calling a function pointer with signature `(param i32 i32) (result i32)` — two `i32` inputs, one `i32` output. Set a breakpoint by clicking on the address, then refresh the page and reproduce the crash. + +Once stopped at the breakpoint, the bottom value on the stack is the function pointer. You can look it up in the console: + +```{image} /_static/img/debugging/signature-mismatch3.png +:alt: Inspecting the function pointer value on the stack +``` + +```javascript +> pyodide._module.wasmTable.get(stack[4].value) // stack[4].value === 13109 +< ƒ $one() { [native code] } +``` + +The bad function pointer's symbol is `one`. Clicking on `$one` brings you to its source, showing the actual signature: + +```{image} /_static/img/debugging/signature-mismatch4.png +:alt: Function pointer actual signature +``` + +The function has signature `(param $var0 i32) (result i32)` — one `i32` input, one `i32` output. This mismatch (called with two args, defined with one) is the cause of the crash. + +3. Find the caller and callee symbols in the source code and fix the type mismatch. If you are not familiar with the codebase, often AI code agents are really good at this kind of task, so delegating this to them can be a good idea. + +## Build system errors + +### pip/build isolation failures + +If the build fails during dependency installation in the isolated environment: + +**Fix**: Use `--no-isolation` and manage dependencies manually: + +```bash +pip install setuptools numpy cython # install build deps +pyodide build . --no-isolation +``` + +## Getting more information + +### Verbose output + +Use `export EMCC_DEBUG=1` to get more detailed output from the Emscripten compiler. + +This can be useful for debugging linker errors and other build issues. + +```bash +export EMCC_DEBUG=1 +pyodide build . +``` + +Increase verbosity to see exactly what commands are being run: + +```bash +# setuptools +pyodide build . -C "--global-option=--verbose" + +# Meson +pyodide build . -Csetup-args=-Dwerror=false -Cbuildtype=debug +``` + +### Check active configuration + +```bash +pyodide config list ``` + +This shows all active build variables including compiler flags, paths, and versions. + +## Useful tools + +- **[Wasm Binary Toolkit (wabt)](https://github.com/WebAssembly/wabt)** — `wasm-objdump`, `wasm2wat`, and other tools for analyzing `.wasm`, `.so`, `.a`, and `.o` files. Essential for diagnosing linker errors and symbol issues. +- **[Emscripten debugging guide](https://emscripten.org/docs/porting/Debugging.html)** — extensive documentation on debugging options available in Emscripten. +- **Chromium DevTools** — use a Chromium-based browser for debugging WebAssembly runtime errors. They have the best Wasm debugging support. + +## What's next? + +- [Customizing Compiler Flags](compiler-flags.md) — adjust flags to fix compilation issues +- [Migrating from Native Builds](migrate.md) — platform differences that cause build failures diff --git a/docs/how-to/migrate.md b/docs/how-to/migrate.md index 87dbb057..d444553c 100644 --- a/docs/how-to/migrate.md +++ b/docs/how-to/migrate.md @@ -1,5 +1,135 @@ # Migrating from Native Builds -```{warning} -This page is under construction. +If you already build native wheels with `python -m build` and want to add Pyodide/WebAssembly support, this guide shows what to change and what to watch out for. + +## The short version + +For many packages, the migration is just: + +```bash +pip install pyodide-build +pyodide build . +``` + +Your existing `pyproject.toml`, `setup.py`, `CMakeLists.txt`, or `meson.build` works as-is — pyodide-build handles the cross-compilation transparently. If the build succeeds, you're done. + +This page covers what to do when it doesn't. + +## What works differently in WebAssembly + +WebAssembly (via Emscripten) is a different platform with different capabilities than Linux, macOS, or Windows. Some things your code may rely on are not available: + +### No threading + +`pthread`, `std::thread`, Python's `threading`, and `multiprocessing` are not available. Code that uses them will fail at runtime if not handled properly. + +You need to guard threaded code paths like this: + +```python +import sys + +if sys.platform != "emscripten": + import threading + # threaded implementation +else: + # single-threaded fallback +``` + +### No networking + +`socket`, `http.client`, `urllib.request` (with network I/O), and similar modules don't work. Network access in Pyodide goes through the browser's fetch API. + +**Fix** — guard network code or provide alternative implementations: + +```python +import sys + +if sys.platform == "emscripten": + from pyodide.http import pyfetch + # use pyfetch for HTTP +else: + import urllib.request + # standard networking +``` + + +```{note} +Third party networking libraries such as `requests`, `aiohttp`, `urllib3`, `httpx` +has a Pyodide-specific code path that uses `pyodide.http.pyfetch` or similar alternatives. + +Therefore, if you are using these libraries, your code should work for common use cases. +``` + +### No subprocesses + +`subprocess`, `os.system`, `os.popen`, and related calls don't work in WebAssembly. + +**Fix** — skip or mock subprocess-dependent functionality on Emscripten. + +### 32-bit integers + +WebAssembly is a 32-bit platform. Code that assumes 64-bit pointer sizes or uses pointer-to-int casts may behave differently. + +## Detecting Pyodide at build time + +pyodide-build sets the `PYODIDE` environment variable during the build. Use it to conditionally adjust your build configuration: + +```python +# setup.py or build script +import os + +if os.environ.get("PYODIDE"): + # WebAssembly-specific build adjustments + ... +``` + +For C/C++ code, use the Emscripten preprocessor macro: + +```c +#ifdef __EMSCRIPTEN__ +// WebAssembly-specific code +#else +// Native code +#endif +``` + +## Detecting Pyodide at runtime + +```python +import sys + +if sys.platform == "emscripten": + # Running on Pyodide + ... ``` + +## Common migration patterns + +### Skipping unsupported tests + +Mark tests that require threads, networking, subprocesses, or platform-specific behavior: + +```python +import sys +import pytest + +@pytest.mark.skipif(sys.platform == "emscripten", reason="No threads on Emscripten") +def test_concurrent_access(): + ... + +@pytest.mark.skipif(sys.platform == "emscripten", reason="No sockets on Emscripten") +def test_http_client(): + ... +``` + +## Adding Pyodide to your CI + +Once your build works locally, add it to CI alongside your native builds: + +- [CI with cibuildwheel](cibuildwheel.md) — add Pyodide as a platform in your existing cibuildwheel config +- [CI without cibuildwheel](ci-direct.md) — add a separate GitHub Actions job + +## What's next? + +- [Debugging Build Failures](debugging.md) — systematic troubleshooting +- [Customizing Compiler Flags](compiler-flags.md) — fine-tuning the build diff --git a/docs/how-to/xbuildenv.md b/docs/how-to/xbuildenv.md index 16bd9523..664cde1a 100644 --- a/docs/how-to/xbuildenv.md +++ b/docs/how-to/xbuildenv.md @@ -1,5 +1,129 @@ # Managing Cross-Build Environments -```{warning} -This page is under construction. +The cross-build environment (xbuildenv) contains everything needed to cross-compile Python packages for WebAssembly: +CPython headers, sysconfig data, and the Emscripten SDK. pyodide-build installs it automatically on first use, but you can also manage it explicitly. + +## Installing + +The `pyodide xbuildenv install` command installs the cross-build environment. + +You *must* have the same host Python version as the one used to build the cross-build environment. +If you have a different Python version, the installation will fail. + +We recommend using `uv` or `pyenv` to manage your Python versions. + +```bash +# Install the latest compatible version +pyodide xbuildenv install + +# Install a specific Pyodide version +pyodide xbuildenv install 0.27.0 + +# Install from a custom URL +pyodide xbuildenv install --url https://example.com/xbuildenv-0.27.0.tar + +# Force install even if version compatibility check fails +pyodide xbuildenv install --force +``` + +## Listing installed versions + +```bash +# List all installed versions (active version marked with *) +pyodide xbuildenv versions +``` + +Output: + +``` +* 0.27.0 + 0.26.4 +``` + +## Switching between versions + +```bash +pyodide xbuildenv use 0.26.4 +``` + +## Checking the current version + +```bash +pyodide xbuildenv version +``` + +## Uninstalling + +```bash +# Uninstall the current version +pyodide xbuildenv uninstall + +# Uninstall a specific version +pyodide xbuildenv uninstall 0.26.4 +``` + +## Searching for available versions + +```bash +# Show versions compatible with your Python and pyodide-build +pyodide xbuildenv search + +# Show all available versions +pyodide xbuildenv search --all + +# Output as JSON (useful for scripting) +pyodide xbuildenv search --json +``` + +The search output shows version compatibility information: + +``` +┌────────────┬────────────┬────────────┬───────────────────────────┬────────────┐ +│ Version │ Python │ Emscripten │ pyodide-build │ Compatible │ +├────────────┼────────────┼────────────┼───────────────────────────┼────────────┤ +│ 0.27.7 │ 3.12.7 │ 3.1.58 │ 0.26.0 - │ Yes │ +│ 0.27.6 │ 3.12.7 │ 3.1.58 │ 0.26.0 - │ Yes │ +└────────────┴────────────┴────────────┴───────────────────────────┴────────────┘ +``` + +## Where the xbuildenv is stored + +pyodide-build resolves the xbuildenv path in this order: + +1. `PYODIDE_XBUILDENV_PATH` environment variable +2. `xbuildenv_path` in `pyproject.toml` under `[tool.pyodide.build]` +3. Platform cache directory (`~/.cache/pyodide` on Linux, `~/Library/Caches/pyodide` on macOS) + +Therefore, to pin a custom location for caching, etc: + +```bash +export PYODIDE_XBUILDENV_PATH=/path/to/xbuildenv +``` + +Or in `pyproject.toml`: + +```toml +[tool.pyodide.build] +xbuildenv_path = "/path/to/xbuildenv" ``` + +## Emscripten SDK + +Each Pyodide version requires a specific Emscripten version. The Emscripten SDK is installed automatically when you run `pyodide build`. +You can also install it manually: + +```bash +pyodide xbuildenv install-emscripten +``` + +Check the required Emscripten version: + +```bash +pyodide config get emscripten_version +``` + +## What's next? + +- [Concepts](../getting-started/concepts.md) — understand what the cross-build environment provides +- [Customizing Compiler Flags](compiler-flags.md) — fine-tuning build flags +- [Configuration Reference](../reference/configuration.md) — all configuration options diff --git a/docs/index.md b/docs/index.md index 0efc713c..dd3bfc1f 100644 --- a/docs/index.md +++ b/docs/index.md @@ -95,15 +95,6 @@ how-to/compiler-flags how-to/debugging ``` -```{toctree} -:maxdepth: 2 -:hidden: -:caption: Recipe System - -recipes/authoring -recipes/building -``` - ```{toctree} :maxdepth: 2 :hidden: @@ -111,7 +102,6 @@ recipes/building reference/cli reference/configuration -reference/meta-yaml reference/platform ``` @@ -121,7 +111,6 @@ reference/platform :caption: Explanation explanation/architecture -explanation/ecosystem ``` ```{toctree} @@ -129,7 +118,6 @@ explanation/ecosystem :hidden: :caption: Appendix -troubleshooting faq changelog ``` diff --git a/docs/recipes/authoring.md b/docs/recipes/authoring.md deleted file mode 100644 index 9338572b..00000000 --- a/docs/recipes/authoring.md +++ /dev/null @@ -1,5 +0,0 @@ -# Recipe Authoring - -```{warning} -This page is under construction. -``` diff --git a/docs/recipes/building.md b/docs/recipes/building.md deleted file mode 100644 index 5d70ea86..00000000 --- a/docs/recipes/building.md +++ /dev/null @@ -1,5 +0,0 @@ -# Building Recipes - -```{warning} -This page is under construction. -``` diff --git a/docs/reference/cli.md b/docs/reference/cli.md index 93a04709..7a955adc 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -1,5 +1,149 @@ # CLI Reference -```{warning} -This page is under construction. +All commands are accessed through the `pyodide` CLI, provided by the [pyodide-cli](https://pypi.org/project/pyodide-cli/) package (installed automatically with pyodide-build). + +## pyodide build + +Build a Python package for WebAssembly. + +``` +pyodide build [OPTIONS] [SOURCE_LOCATION] +``` + +**Arguments:** + +| Argument | Description | +|---|---| +| `SOURCE_LOCATION` | Build source: a directory. Defaults to the current directory. | + +**Options:** + +| Option | Default | Description | +|---|---|---| +| `-o`, `--outdir` | `./dist` | Output directory for the built wheel | +| `--exports` | `requested` | Symbol export mode: `pyinit`, `requested`, `whole_archive`, or comma-separated list | +| `-C`, `--config-setting` | | Pass settings to the build backend (same as `pypa/build`) | +| `-n`, `--no-isolation` | `false` | Disable build isolation; build deps must be installed manually | +| `-x`, `--skip-dependency-check` | `false` | Skip build dependency check (only with `--no-isolation`) | +| `--compression-level` | `6` | Zip compression level for the wheel | +| `--xbuildenv-path` | platform cache | Path to the cross-build environment, inferred from platform cache if not specified | + +## pyodide venv + +Create a Pyodide virtual environment for testing. + +``` +pyodide venv [OPTIONS] DEST +``` + +**Arguments:** + +| Argument | Description | +|---|---| +| `DEST` | Directory to create the virtualenv at | + +**Options:** + +| Option | Default | Description | +|---|---|---| +| `--clear` / `--no-clear` | `no-clear` | Remove destination directory if it exists | +| `--no-vcs-ignore` | | Don't create VCS ignore directive (e.g., `.gitignore`) | +| `--download` / `--no-download` | | Enable/disable download of latest pip/setuptools from PyPI | +| `--extra-search-dir` | | Path containing additional wheels | +| `--pip` | `bundle` | pip version: `embed`, `bundle`, or exact version | +| `--setuptools` | | setuptools version: `embed`, `bundle`, `none`, or exact version | +| `--no-setuptools` | | Do not install setuptools | + +## pyodide config + +Query build configuration values. + +### pyodide config list + +``` +pyodide config list +``` + +Lists all config variables and their current values. + +### pyodide config get + +``` +pyodide config get CONFIG_VAR +``` + +Get a single config variable's value. Common variables: + +| Variable | Description | +|---|---| +| `cflags` | C compiler flags | +| `cxxflags` | C++ compiler flags | +| `ldflags` | Linker flags | +| `rustflags` | Rust compiler flags | +| `cmake_toolchain_file` | Path to CMake toolchain file | +| `meson_cross_file` | Path to Meson cross file | +| `rust_toolchain` | Required Rust nightly toolchain | +| `emscripten_version` | Required Emscripten version | +| `python_version` | Target Python version | +| `xbuildenv_path` | Cross-build environment path | +| `pyodide_abi_version` | Pyodide ABI version | + +## pyodide xbuildenv + +Manage the cross-build environment. + +### pyodide xbuildenv install + +``` +pyodide xbuildenv install [OPTIONS] [VERSION] +``` + +| Option | Env var | Description | +|---|---|---| +| `--path` | `PYODIDE_XBUILDENV_PATH` | Destination directory | +| `--url` | | Download from a custom URL | +| `-f`, `--force` | | Force install even if version is incompatible | + +### pyodide xbuildenv version + +``` +pyodide xbuildenv version [--path PATH] +``` + +Print the current active version. + +### pyodide xbuildenv versions + ``` +pyodide xbuildenv versions [--path PATH] +``` + +List all installed versions. Active version is marked with `*`. + +### pyodide xbuildenv use + +``` +pyodide xbuildenv use VERSION [--path PATH] +``` + +Switch to a specific installed version. + +### pyodide xbuildenv uninstall + +``` +pyodide xbuildenv uninstall [VERSION] [--path PATH] +``` + +Uninstall a version. Defaults to the current version if not specified. + +### pyodide xbuildenv search + +``` +pyodide xbuildenv search [OPTIONS] +``` + +| Option | Description | +|---|---| +| `--metadata` | Custom metadata file URL or path | +| `-a`, `--all` | Show all versions, including incompatible ones | +| `--json` | Output as JSON | diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index b385b3b1..90fff9fc 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -1,5 +1,57 @@ # Configuration Reference -```{warning} -This page is under construction. +pyodide-build reads configuration from multiple sources. This page documents all available settings. + +## Precedence + +Configuration is resolved in this order (highest priority first): + +1. **Environment variables** +2. **`pyproject.toml`** under `[tool.pyodide.build]` +3. **Cross-build environment** defaults +4. **Built-in defaults** + +## pyproject.toml + +Add configuration under `[tool.pyodide.build]`: + +```toml +[tool.pyodide.build] +cflags = "-O2" +cxxflags = "-O2" +ldflags = "-s SIDE_MODULE=1 -O2" +xbuildenv_path = "/path/to/xbuildenv" +``` + +## User-overridable settings + +These keys can be set in `pyproject.toml` or via environment variables: + +| pyproject.toml key | Env variable | Description | +|---|---|---| +| `cflags` | `CFLAGS` | C compiler flags | +| `cxxflags` | `CXXFLAGS` | C++ compiler flags | +| `ldflags` | `LDFLAGS` | Linker flags | +| `rustflags` | `RUSTFLAGS` | Rust compiler flags | +| `rust_toolchain` | `RUST_TOOLCHAIN` | Rust nightly toolchain version | +| `meson_cross_file` | `MESON_CROSS_FILE` | Path to Meson cross file | +| `xbuildenv_path` | `PYODIDE_XBUILDENV_PATH` | Path to cross-build environment | +| `ignored_build_requirements` | `IGNORED_BUILD_REQUIREMENTS` | Build requirements to ignore | + +## Environment variables + +### Querying configuration + +Use `pyodide config` to inspect active values: + +```bash +# List all settings +pyodide config list + +# Get a specific value +pyodide config get cflags +pyodide config get meson_cross_file +pyodide config get rust_toolchain ``` + +See the [CLI Reference](cli.md) for details. diff --git a/docs/reference/meta-yaml.md b/docs/reference/meta-yaml.md deleted file mode 100644 index 6f7c13fc..00000000 --- a/docs/reference/meta-yaml.md +++ /dev/null @@ -1,5 +0,0 @@ -# meta.yaml Reference - -```{warning} -This page is under construction. -``` diff --git a/docs/reference/platform.md b/docs/reference/platform.md index 561c0607..f1ad0425 100644 --- a/docs/reference/platform.md +++ b/docs/reference/platform.md @@ -1,5 +1,62 @@ -# Platform Tags and Compatibility +# Platform Tags & Compatibility -```{warning} -This page is under construction. +The Emscripten/WebAssembly platform for Python is standardized by [PEP 783](https://peps.python.org/pep-0783/). + +## Platform tag format + +Wheels built by pyodide-build use the platform tag: + +``` +pyemscripten_{year}_{patch}_wasm32 +``` + +A complete wheel filename: + +``` +numpy-2.2.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl + │ │ │ │ + │ │ │ └── platform tag + │ │ └── Python ABI tag + │ └── Python version tag + └── package version ``` + +## Compatibility matrix + +Each platform version is tied to a specific Python version and Emscripten SDK version. Wheels built for one platform version are **not** compatible with another. + +| Platform tag | Python | Emscripten | Notes | +|---|---|---|---| +| `pyodide_2024_0_wasm32` | 3.12 | 3.1.58 | Legacy tag name | +| `pyemscripten_2025_0_wasm32` | 3.13 | 4.0.9 | PEP 783 standardized name | +| `pyemscripten_2026_0_wasm32` | 3.14 | TBD | Under development | + +```{note} +Older Pyodide versions used the tag `pyodide_{year}_{patch}_wasm32`. The `pyemscripten_*` tag is the standardized form going forward per PEP 783. +``` + +## ABI compatibility rules + +- Wheels are **not cross-version compatible** — a wheel built for `pyemscripten_2025_0_wasm32` will not work with `pyemscripten_2024_0_wasm32` or `pyemscripten_2026_0_wasm32`. +- Pure-Python wheels (`py3-none-any`) work on all versions. +- The ABI version determines which Emscripten SDK and CPython build are used. Mixing versions will cause load-time or runtime errors. + +## cibuildwheel identifiers + +When using [cibuildwheel](../how-to/cibuildwheel.md), the platform identifiers are: + +| cibuildwheel identifier | Platform tag | +|---|---| +| `cp312-pyodide_wasm32` | `pyodide_2024_0_wasm32` | +| `cp313-pyodide_wasm32` | `pyemscripten_2025_0_wasm32` | + +## Checking your platform version + +```bash +pyodide config get pyodide_abi_version +``` + +## Further reading + +- [PEP 783 — The Emscripten Platform](https://peps.python.org/pep-0783/) — formal specification +- [Concepts — Platform Tags](../getting-started/concepts.md) — introductory explanation diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md deleted file mode 100644 index 48238779..00000000 --- a/docs/troubleshooting.md +++ /dev/null @@ -1,5 +0,0 @@ -# Troubleshooting - -```{warning} -This page is under construction. -``` From 2fbe7be24662dd14758f04fdb8d96081fed9d654 Mon Sep 17 00:00:00 2001 From: Gyeongjae Choi Date: Fri, 27 Mar 2026 17:33:12 +0900 Subject: [PATCH 6/8] Tidy up --- docs/faq.md | 9 +++++++++ docs/getting-started/quickstart.md | 2 +- docs/how-to/cibuildwheel.md | 8 ++------ docs/how-to/migrate.md | 1 + docs/index.md | 11 ++--------- 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/docs/faq.md b/docs/faq.md index e828d1b2..7a60650e 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -1,5 +1,14 @@ # FAQ +## Which packages work with Pyodide? + +- **Pure Python** — always works. No special tooling needed. +- **C/C++ extensions** — usually works with pyodide-build. Some packages need minor adjustments (e.g., disabling optional native dependencies, guarding platform-specific code). +- **Rust extensions (PyO3)** — works with pyodide-build and the correct Rust nightly toolchain. +- **Threading / multiprocessing** — not supported. Packages that require threads will not work. +- **Networking (sockets)** — not supported. Packages that open raw sockets will not work. High-level HTTP libraries like `requests` and `httpx` have Pyodide-specific fallbacks. +- **Subprocesses** — not supported. Packages that call `subprocess.run()` will not work. + ## Do I need the full Pyodide repository? No. pyodide-build is a standalone package. Install it with `pip install pyodide-build` and you're ready to build. You don't need to clone the Pyodide repository. diff --git a/docs/getting-started/quickstart.md b/docs/getting-started/quickstart.md index 81736e02..064075bc 100644 --- a/docs/getting-started/quickstart.md +++ b/docs/getting-started/quickstart.md @@ -1,6 +1,6 @@ # Quick Start -This guide walks you through building a Python package with C extensions for WebAssembly using pyodide-build. +This guide walks you through building a Python package with C extensions for WebAssembly using pyodide-build. Make sure you've [installed pyodide-build](installation.md) first. ```{note} **Pure-Python packages do not need pyodide-build.** If your package has no C, C++, or Rust extensions, a standard wheel built with `python -m build` already works with Pyodide. diff --git a/docs/how-to/cibuildwheel.md b/docs/how-to/cibuildwheel.md index 7ff20d6f..88bd774a 100644 --- a/docs/how-to/cibuildwheel.md +++ b/docs/how-to/cibuildwheel.md @@ -43,7 +43,7 @@ jobs: os: [ubuntu-latest, macos-latest] steps: - uses: actions/checkout@v4 - - uses: pypa/cibuildwheel@v2.22 + - uses: pypa/cibuildwheel@v3.4.0 - uses: actions/upload-artifact@v4 with: name: wheels-${{ matrix.os }} @@ -54,7 +54,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: pypa/cibuildwheel@v2.22 + - uses: pypa/cibuildwheel@v3.4.0 env: CIBW_PLATFORM: pyodide - uses: actions/upload-artifact@v4 @@ -74,10 +74,6 @@ jobs: Combine native and Pyodide wheels in a single publish step: -```{important} -Publishing Pyodide wheels are not supported yet as of 2026/03/24. We are waiting for PEP 783 to be implemented in PyPI. -``` - ```yaml publish: needs: [build-native, build-pyodide] diff --git a/docs/how-to/migrate.md b/docs/how-to/migrate.md index d444553c..f097829c 100644 --- a/docs/how-to/migrate.md +++ b/docs/how-to/migrate.md @@ -131,5 +131,6 @@ Once your build works locally, add it to CI alongside your native builds: ## What's next? +- [Tutorial: C Extension](../tutorials/c-extension.md) — detailed walkthrough for C extension packages - [Debugging Build Failures](debugging.md) — systematic troubleshooting - [Customizing Compiler Flags](compiler-flags.md) — fine-tuning the build diff --git a/docs/index.md b/docs/index.md index dd3bfc1f..42cda20b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -103,13 +103,6 @@ how-to/debugging reference/cli reference/configuration reference/platform -``` - -```{toctree} -:maxdepth: 2 -:hidden: -:caption: Explanation - explanation/architecture ``` @@ -124,8 +117,8 @@ changelog ## Communication +- Discord: [Pyodide Discord](https://dsc.gg/pyodide) - Blog: [blog.pyodide.org](https://blog.pyodide.org/) - Mailing list: [mail.python.org/mailman3/lists/pyodide.python.org/](https://mail.python.org/mailman3/lists/pyodide.python.org/) -- Gitter: [gitter.im/pyodide/community](https://gitter.im/pyodide/community) -- Twitter: [twitter.com/pyodide](https://twitter.com/pyodide) +- X: [x.com/pyodide](https://x.com/pyodide) - Stack Overflow: [stackoverflow.com/questions/tagged/pyodide](https://stackoverflow.com/questions/tagged/pyodide) From f4b9e760b4aeb92639fcda9d6a0093b12501b1c4 Mon Sep 17 00:00:00 2001 From: Gyeongjae Choi Date: Fri, 27 Mar 2026 17:43:40 +0900 Subject: [PATCH 7/8] Add auditwheel --- docs/how-to/auditwheel.md | 90 +++++++++++++++++++++++++++++++++++++++ docs/index.md | 1 + 2 files changed, 91 insertions(+) create mode 100644 docs/how-to/auditwheel.md diff --git a/docs/how-to/auditwheel.md b/docs/how-to/auditwheel.md new file mode 100644 index 00000000..638a2c44 --- /dev/null +++ b/docs/how-to/auditwheel.md @@ -0,0 +1,90 @@ +# Auditing and Repairing Wheels + +When a Python extension links against shared libraries (`.so` files), those libraries must be available at runtime. On native platforms, `auditwheel` handles this by copying the shared libraries into the wheel. For WebAssembly wheels, pyodide-build uses [auditwheel-emscripten](https://github.com/pyodide/auditwheel-emscripten) via the `pyodide auditwheel` command. + +## Install + +`auditwheel-emscripten` is included as a dependency of pyodide-build and is available as a `pyodide` CLI plugin: + +```bash +pip install pyodide-build +pyodide auditwheel --help +``` + +## When do you need this? + +If your package links against a shared library that isn't included in the wheel after running `python -m build`, +you need to vendor that library into the wheel. Otherwise, the `.so` file will fail to load at runtime with an error like: + +``` +ImportError: unable to load shared library 'libfoo.so' +``` + +## Inspecting a wheel + +Before repairing, inspect the wheel to see what shared libraries it depends on: + +```bash +pyodide auditwheel show dist/your_package-*.whl +``` + +This lists all shared library dependencies of the wheel's `.so` files and shows which are already included and which need to be vendored. + +## Repairing a wheel + +The `repair` command finds the shared library dependencies and copies them into the wheel: + +```bash +pyodide auditwheel repair dist/your_package-*.whl --libdir /path/to/libdir +``` + +The `--libdir` option specifies the directory where the shared libraries are located. + +By default, the wheel is repaired in place, but you can specify an output directory with `-o`: + +```bash +pyodide auditwheel repair dist/your_package-*.whl -o repaired/ +``` + +The repair process: +1. Scans all `.so` files in the wheel for shared library dependencies +2. Locates the required libraries in the specified `--libdir` +3. Copies them into a `.libs/` directory inside the wheel +4. Updates the RPATH of the `.so` files to point to the vendored libraries + +## Typical workflow + +```bash +# 1. Build the wheel +pyodide build . + +# 2. Inspect shared library dependencies +pyodide auditwheel show dist/your_package-*.whl + +# 3. Vendor shared libraries into the wheel +pyodide auditwheel repair dist/your_package-*.whl -w dist/ + +# 4. Test the repaired wheel +pyodide venv .venv-pyodide +source .venv-pyodide/bin/activate +pip install dist/your_package-*.whl +python -m pytest tests/ +``` + +## In cibuildwheel + +Unlike manylinux, cibuildwheel doesn't automatically run auditwheel repair for Pyodide. +This is because we don't know where to locate the shared libraries that the `.so` files depend on. +We cannot find them from the host system paths since we need cross-compiled libraries not the host's libraries. + +Therefore, you need to set the libdir explicitly in the cibuildwheel configuration. + +```toml +[tool.cibuildwheel.pyodide] +repair-wheel-command = "pyodide auditwheel repair --libdir /path/to/libraries --output-dir {dest_dir} {wheel}" +``` + +## What's next? + +- [CI with cibuildwheel](cibuildwheel.md) — cibuildwheel can run auditwheel repair automatically via `repair-wheel-command` +- [Debugging Build Failures](debugging.md) — troubleshooting shared library errors diff --git a/docs/index.md b/docs/index.md index 42cda20b..5d70434e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -92,6 +92,7 @@ how-to/publishing how-to/migrate how-to/xbuildenv how-to/compiler-flags +how-to/auditwheel how-to/debugging ``` From b454e83e5cf7c94ef8d9411dc3c63a8a0d1526f3 Mon Sep 17 00:00:00 2001 From: Gyeongjae Choi Date: Fri, 27 Mar 2026 17:44:23 +0900 Subject: [PATCH 8/8] typo --- docs/tutorials/c-extension.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/c-extension.md b/docs/tutorials/c-extension.md index 74c5be89..c8c54731 100644 --- a/docs/tutorials/c-extension.md +++ b/docs/tutorials/c-extension.md @@ -147,7 +147,7 @@ fatal error: 'some_library.h' file not found This means your C code includes a header that isn't available in the Emscripten. If it's a system library, it needs to be cross-compiled for Emscripten first. pyodide-build does not allow reading headers from the host system's include paths. -This is bacause linking the library built for the host system to the WebAssembly module will cause build time / runtime errors. +This is because linking the library built for the host system to the WebAssembly module will cause build time / runtime errors. ### Undefined symbols at link time