Skip to content

Apply Pyodide-specific patches to our Emscripten toolchain installation#2800

Merged
agriyakhetarpal merged 5 commits intopypa:mainfrom
agriyakhetarpal:apply-pyodide-patches-to-emscripten
Apr 3, 2026
Merged

Apply Pyodide-specific patches to our Emscripten toolchain installation#2800
agriyakhetarpal merged 5 commits intopypa:mainfrom
agriyakhetarpal:apply-pyodide-patches-to-emscripten

Conversation

@agriyakhetarpal
Copy link
Copy Markdown
Member

@agriyakhetarpal agriyakhetarpal commented Mar 25, 2026

Our Emscripten toolchain installation here has mostly remained vanilla-like, but pyodide-build and pyodide-recipes also apply some Pyodide-specific patches. This makes both mechanisms of building Pyodide wheels uniform by applying the patches here as well.

I have been wanting to get to this for a while now, having used a pesky combination of sparse-checking out the patches with actions/checkout and then applying them in the before-build stage in GHA before. My motivation to do this today came from flintlib/python-flint#382, so I thought I'd just put it in here!

N.B: We also have an install-and-patch-emscripten command thingy somewhere IIRC... this change is not that because that would be a bigger change to incorporate and should be discussed first; it would move the Emscripten installation from cibuildwheel's control to pyodide-build and thus would make changes to that scheme difficult (say, if pyodide-build were to break at a particular version for whatever reason, it would then start impacting all Pyodide builds for downstream users of cibuildwheel). I've gone ahead and implemented the pyodide xbuildenv install-emscripten command as that's what we ended up agreeing with at the end, in that it doesn't expose any pyodide-build internals to cibuildwheel.

cc: @oscarbenjamin

Comment thread cibuildwheel/platforms/pyodide.py Outdated
Comment on lines +142 to +148
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.

@agriyakhetarpal
Copy link
Copy Markdown
Member Author

You may see it working here: https://github.com/pypa/cibuildwheel/actions/runs/23520265886/job/68462021117?pr=2800#step:7:665. Note that the Pyodide 0.28.0 xbuildenvs were the first to include the Emscripten patches, so this is not applicable to the Pyodide 0.27.7 xbuildenvs/builds.

When we release Pyodide 0.30 in the next couple of months or so (or before that, or later), we should drop Pyodide 0.27 here and keep only Pyodide 0.29 and Pyodide 0.30. It still makes sense to keep Pyodide 0.27 for now, as it is beneficial for cibuildwheel to retain support for building wheels for two different Pyodide ABIs at a time.

@agriyakhetarpal
Copy link
Copy Markdown
Member Author

I'll take a look at the failing tests later today. I don't immediately see what part of my changes might be causing them, though!

Copy link
Copy Markdown
Member

@ryanking13 ryanking13 left a comment

Choose a reason for hiding this comment

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

N.B: We also have an install-and-patch-emscripten command thingy somewhere IIRC... this change is not that because that would be a bigger change to incorporate and should be discussed first; it would move the Emscripten installation from cibuildwheel's control to pyodide-build and thus would make changes to that scheme difficult (say, if pyodide-build were to break at a particular version for whatever reason, it would then start impacting all Pyodide builds for downstream users of cibuildwheel).

I would like to go this way directly if possible. This PR already exposes pyodide-build internals (e.g. path to the emscripten patches) to cibuildwheel, which can silently be broken when we make changes in pyodide-build. I don't want to introduce more of that into cibuildwheel.

The pyodide-build >= 0.33 now installs emscripten and applies the patch in the background without calling any command explicitly. So I guess the thing we need to do is simply removing the emscripten installation part in cibuildwheel.

Comment thread cibuildwheel/platforms/pyodide.py Outdated
Comment on lines +142 to +148
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

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.

@joerick
Copy link
Copy Markdown
Contributor

joerick commented Apr 1, 2026

I would like to go this way directly if possible. This PR already exposes pyodide-build internals (e.g. path to the emscripten patches) to cibuildwheel, which can silently be broken when we make changes in pyodide-build. I don't want to introduce more of that into cibuildwheel.

Agreed re. the coupling. If there's special magic needed for pyodide builds, let's keep as much of that as we can in pyodide-build, so it can be used without cibuildwheel.

  • That might be calling a command from pyodide-build that patches an existing emscripten install, or,
  • If we move the emscripten installation to pyodide-build, that's fine with me too. One asterisk - might be good to keep the vresion pin, if we go that way perhaps each pyodide-build version could pin an emscripten version? Or I suppose we could pass the version pin to pyodide-build.

@ryanking13
Copy link
Copy Markdown
Member

might be good to keep the vresion pin, if we go that way perhaps each pyodide-build version could pin an emscripten version? Or I suppose we could pass the version pin to pyodide-build.

The Emscripten version is defined by the Python version. pyodide-build will choose the right emscripten version (and Pyodide version) when the Python version is selected.

@agriyakhetarpal
Copy link
Copy Markdown
Member Author

might be good to keep the vresion pin, if we go that way perhaps each pyodide-build version could pin an emscripten version? Or I suppose we could pass the version pin to pyodide-build.

The Emscripten version is defined by the Python version. pyodide-build will choose the right emscripten version (and Pyodide version) when the Python version is selected.

Yes, correct

N.B: We also have an install-and-patch-emscripten command thingy somewhere IIRC... this change is not that because that would be a bigger change to incorporate and should be discussed first; it would move the Emscripten installation from cibuildwheel's control to pyodide-build and thus would make changes to that scheme difficult (say, if pyodide-build were to break at a particular version for whatever reason, it would then start impacting all Pyodide builds for downstream users of cibuildwheel).

I would like to go this way directly if possible. This PR already exposes pyodide-build internals (e.g. path to the emscripten patches) to cibuildwheel, which can silently be broken when we make changes in pyodide-build. I don't want to introduce more of that into cibuildwheel.

Agreed re. the coupling. If there's special magic needed for pyodide builds, let's keep as much of that as we can in pyodide-build, so it can be used without cibuildwheel.

Okay, since both of you suggest that we should rely on pyodide-build's existing command-line machinery for the Emscripten installation, I'll update this PR to use it! We'll just have to ensure that pyodide-build doesn't start breaking :-) which it fortunately hasn't for a while now, so I'm all fine with it.

@agriyakhetarpal agriyakhetarpal marked this pull request as draft April 2, 2026 07:28
@agriyakhetarpal agriyakhetarpal marked this pull request as ready for review April 2, 2026 09:50
Comment thread cibuildwheel/platforms/pyodide.py Outdated
Co-authored-by: Joe Rickerby <joerick@mac.com>
@joerick joerick added the Hold for future release This PR might be complete, but is scheduled to be merged in a future release. Don't merge yet. label Apr 2, 2026
@agriyakhetarpal
Copy link
Copy Markdown
Member Author

@joerick, assuming that https://github.com/pypa/cibuildwheel/releases/tag/v3.4.1 was the upcoming release for which this PR was held, and that it occurred seven minutes after you added the label, this should be unblocked now – please let me know if I misunderstand! Thanks! :)

@joerick joerick removed the Hold for future release This PR might be complete, but is scheduled to be merged in a future release. Don't merge yet. label Apr 2, 2026
@joerick
Copy link
Copy Markdown
Contributor

joerick commented Apr 2, 2026

Yep you're right :)

Copy link
Copy Markdown
Member

@ryanking13 ryanking13 left a comment

Choose a reason for hiding this comment

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

LGTM. Plase make sure the pyodide-build version pinned in cibuildwheel supports install-emscripten command correctly.

Comment on lines +101 to +102
emcc_path = (
xbuildenv_cache_path / pyodide_version / "emsdk" / "upstream" / "emscripten" / "emcc"
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

@agriyakhetarpal
Copy link
Copy Markdown
Member Author

LGTM. Plase make sure the pyodide-build version pinned in cibuildwheel supports install-emscripten command correctly.

Yes, it does – pyodide-build is at version 0.33.0 for both the Pyodide 0.27.7 and Pyodide 0.29.3 builds, and also thanks to our backwards compatibility setup through which we can install the older xbuildenvs.

@agriyakhetarpal
Copy link
Copy Markdown
Member Author

I have opened pyodide/pyodide-build#321, and will make a release after merge.

@ryanking13
Copy link
Copy Markdown
Member

I have opened pyodide/pyodide-build#321, and will make a release after merge.

Thanks. Actually, you don't need to block this PR for pyodide-build change. My comment was a suggestion not a merge blocker.

@agriyakhetarpal
Copy link
Copy Markdown
Member Author

Oh, sounds good! Thanks for the reviews, @ryanking13 and @joerick! I'll put together a follow-up PR later :)

@agriyakhetarpal agriyakhetarpal merged commit 8d75eb7 into pypa:main Apr 3, 2026
73 of 74 checks passed
@agriyakhetarpal agriyakhetarpal deleted the apply-pyodide-patches-to-emscripten branch April 3, 2026 05:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants