Skip to content
Merged
Changes from all 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
55 changes: 31 additions & 24 deletions cibuildwheel/platforms/pyodide.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,21 +94,28 @@ def ensure_node(major_version: str) -> Path:
return path


def install_emscripten(tmp: Path, version: str) -> Path:
url = f"https://github.com/emscripten-core/emsdk/archive/refs/tags/{version}.zip"
installation_path = CIBW_CACHE_PATH / f"emsdk-{version}"
emsdk_path = installation_path / f"emsdk-{version}/emsdk"
emcc_path = installation_path / f"emsdk-{version}/upstream/emscripten/emcc"
with FileLock(f"{installation_path}.lock"):
if installation_path.exists():
def install_emscripten(
env: dict[str, str], version: str, xbuildenv_cache_path: Path, pyodide_version: str
) -> Path:
"""Install Emscripten via pyodide-build, which also applies Pyodide-specific patches."""
emcc_path = (
xbuildenv_cache_path / pyodide_version / "emsdk" / "upstream" / "emscripten" / "emcc"
Comment on lines +101 to +102
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.

Maybe we can make a config variable something like pyodide config get emscripten-path in the future so that this path is not hardcoded in cibuildwheel.

Copy link
Copy Markdown
Member Author

@agriyakhetarpal agriyakhetarpal Apr 3, 2026

Choose a reason for hiding this comment

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

Maybe we can make a config variable something like pyodide config get emscripten-path in the future so that this path is not hardcoded in cibuildwheel.

Agreed. We already have one that points to the xbuildenv path, so why not!

Edit: working on this rn

)
with FileLock(CIBW_CACHE_PATH / "emscripten.lock"):
if emcc_path.exists():
return emcc_path
emsdk_zip = tmp / "emsdk.zip"
download(url, emsdk_zip)
installation_path.mkdir()
extract_zip(emsdk_zip, installation_path)
call(emsdk_path, "install", version)
call(emsdk_path, "activate", version)

call(
"pyodide",
"xbuildenv",
"install-emscripten",
"--version",
version,
"--path",
str(xbuildenv_cache_path),
env=env,
cwd=CIBW_CACHE_PATH,
)
assert emcc_path.exists()
return emcc_path


Expand Down Expand Up @@ -180,12 +187,8 @@ def validate_pyodide_build_version(
raise errors.FatalError(msg)


def install_xbuildenv(env: dict[str, str], pyodide_build_version: str, pyodide_version: str) -> str:
def install_xbuildenv(env: dict[str, str], xbuildenv_cache_path: Path, pyodide_version: str) -> str:
"""Install a particular Pyodide xbuildenv version and set a path to the Pyodide root."""
# Since pyodide-build was unvendored from Pyodide v0.27.0, the versions of
# pyodide-build are uncoupled from the versions of Pyodide. So, we specify
# both the pyodide-build version and the Pyodide version in the temp path.
xbuildenv_cache_path = CIBW_CACHE_PATH / f"pyodide-build-{pyodide_build_version}"
pyodide_root = xbuildenv_cache_path / pyodide_version / "xbuildenv" / "pyodide-root"

with FileLock(CIBW_CACHE_PATH / "xbuildenv.lock"):
Expand Down Expand Up @@ -303,15 +306,19 @@ def setup_python(
pyodide_build_version=pyodide_build_version,
)

xbuildenv_cache_path = CIBW_CACHE_PATH / f"pyodide-build-{pyodide_build_version}"

log.step(f"Installing Pyodide xbuildenv version: {pyodide_version} ...")
env["PYODIDE_ROOT"] = install_xbuildenv(env, xbuildenv_cache_path, pyodide_version)

emscripten_version = xbuildenv_info["emscripten"]
log.step(f"Installing Emscripten version: {emscripten_version} ...")
emcc_path = install_emscripten(tmp, emscripten_version)
log.step(
f"Installing Emscripten {emscripten_version} and applying Pyodide-specific patches ..."
)
emcc_path = install_emscripten(env, emscripten_version, xbuildenv_cache_path, pyodide_version)

env["PATH"] = os.pathsep.join([str(emcc_path.parent), env["PATH"]])

log.step(f"Installing Pyodide xbuildenv version: {pyodide_version} ...")
env["PYODIDE_ROOT"] = install_xbuildenv(env, pyodide_build_version, pyodide_version)

return env


Expand Down
Loading