Skip to content
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions cibuildwheel/platforms/pyodide.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import functools
import json
import os
import shlex
import shutil
import subprocess
import sys
Expand Down Expand Up @@ -112,6 +113,50 @@ def install_emscripten(tmp: Path, version: str) -> Path:
return emcc_path


def apply_emscripten_patches(emcc_path: Path, pyodide_root: str) -> None:
"""Apply Pyodide-specific patches to the Emscripten installation.

Pyodide maintains patches against Emscripten in the xbuildenv at
``{pyodide_root}/emsdk/patches/*.patch``. These are applied to the
``upstream/emscripten`` directory of the emsdk installation so that
cibuildwheel uses the same patched Emscripten as pyodide-build.
"""
patches_dir = Path(pyodide_root) / "emsdk" / "patches"
if not patches_dir.exists():
return

patches = sorted(patches_dir.glob("*.patch"))
if not patches:
return

emscripten_root = emcc_path.parent
# installation_path is two levels up: emsdk-{ver}/emsdk-{ver}/upstream/emscripten
installation_path = emscripten_root.parent.parent.parent
marker = installation_path / ".cibw_emscripten_patches_applied"

with FileLock(f"{installation_path}.lock"):
if marker.exists():
return

log.step("Applying Pyodide-specific patches to Emscripten installation...")
try:
subprocess.run(
f"cat {shlex.quote(str(patches_dir))}/*.patch | patch -p1 --verbose",
check=True,
shell=True,
cwd=emscripten_root,
)
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have some level of Windows support in pyodide-build, but not yet in cibuildwheel, so I stayed with the cat and patch commands here. We could think of a cross-platform solution later.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have some level of Windows support in pyodide-build

We never considered windows as a valid target so I think it is fine.

except subprocess.CalledProcessError as e:
msg = (
f"Failed to apply Emscripten patches from {patches_dir}. "
"This may occur if the Emscripten version does not match "
"the version for which the patches were generated."
)
raise errors.FatalError(msg) from e

marker.touch()


def get_all_xbuildenv_version_info(env: dict[str, str]) -> list[PyodideXBuildEnvInfo]:
xbuildenvs_info_str = call(
"pyodide",
Expand Down Expand Up @@ -312,6 +357,8 @@ def setup_python(
log.step(f"Installing Pyodide xbuildenv version: {pyodide_version} ...")
env["PYODIDE_ROOT"] = install_xbuildenv(env, pyodide_build_version, pyodide_version)

apply_emscripten_patches(emcc_path, env["PYODIDE_ROOT"])

return env


Expand Down
Loading