-
Notifications
You must be signed in to change notification settings - Fork 244
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow the use of arbitrary Pyodide versions #2002
base: main
Are you sure you want to change the base?
Changes from 49 commits
2ae389d
0e3b3f1
394459f
dff7bf2
16057bc
f167c50
31a6be9
cbca40b
9003067
d8a8d5e
cf5dd3e
55459cb
4fe86e0
b6830ee
aaf32e5
bb6e0d6
735d5bb
b8ac6c0
7796311
97e22c8
d30eb6a
ce2a3f0
13fbf66
14ec071
aae64bb
6956121
e5d8443
95c3681
09af46f
66999cb
1af1e5d
ad3a203
d344548
b3143b4
738ed1f
41e466a
2a66ddd
dff72ca
9a78845
e551021
1fe8a04
8a8177c
fffb705
0df3c45
057e542
29b5eff
321e0de
92babdb
d73f71f
0f52a4b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
from __future__ import annotations | ||
|
||
import json | ||
import os | ||
import shutil | ||
import sys | ||
|
@@ -41,6 +42,7 @@ class PythonConfiguration: | |
version: str | ||
identifier: str | ||
pyodide_version: str | ||
pyodide_build_version: str | ||
emscripten_version: str | ||
node_version: str | ||
|
||
|
@@ -65,11 +67,58 @@ def install_emscripten(tmp: Path, version: str) -> Path: | |
return emcc_path | ||
|
||
|
||
def install_xbuildenv(env: dict[str, str], pyodide_version: str) -> str: | ||
def get_xbuildenv_versions(env: dict[str, str]) -> list[str]: | ||
"""Searches for the compatible xbuildenvs for the current pyodide-build version""" | ||
with FileLock(CIBW_CACHE_PATH / "xbuildenv.lock"): | ||
xbuildenvs = call( | ||
"pyodide", | ||
"xbuildenv", | ||
"search", | ||
"--json", | ||
"--all", | ||
env=env, | ||
cwd=CIBW_CACHE_PATH, | ||
capture_stdout=True, | ||
).strip() | ||
xbuildenvs_dict = json.loads(xbuildenvs) | ||
compatible_xbuildenv_versions = [ | ||
_["version"] for _ in xbuildenvs_dict["environments"] if _["compatible"] | ||
] | ||
|
||
return compatible_xbuildenv_versions | ||
|
||
|
||
# The xbuildenv version is brought in sync with the pyodide-build version in build-platforms.toml, | ||
# which will always be compatible. Hence, this condition really checks only for the case where the | ||
# version is supplied manually through a CIBW_PYODIDE_VERSION environment variable and raises an | ||
# error as appropriate. | ||
def validate_xbuildenv_version( | ||
cibw_pyodide_version: str, pyodide_build_version: str, compatible_versions: list[str] | ||
) -> None: | ||
"""Validate the Pyodide version if set manually for the current pyodide-build version | ||
against a list of compatible versions.""" | ||
|
||
if cibw_pyodide_version not in compatible_versions: | ||
msg = ( | ||
f"The xbuildenv version {cibw_pyodide_version} is not compatible with the pyodide-build" | ||
f" version {pyodide_build_version}. The compatible versions available to download are:\n" | ||
f"{compatible_versions}. Please use the 'pyodide xbuildenv search' command to" | ||
f" find the compatible versions for 'pyodide-build' {pyodide_build_version}." | ||
) | ||
raise errors.FatalError(msg) | ||
|
||
|
||
def install_xbuildenv(env: dict[str, str], pyodide_build_version: str, 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 | ||
# not guaranteed to match the versions of Pyodide or be in sync with them. Hence, we shall | ||
# specify the pyodide-build version in the root path, which will set up the xbuildenv for | ||
# the requested Pyodide version. | ||
pyodide_root = ( | ||
CIBW_CACHE_PATH | ||
/ f".pyodide-xbuildenv-{pyodide_version}/{pyodide_version}/xbuildenv/pyodide-root" | ||
/ f".pyodide-xbuildenv-{pyodide_build_version}/{pyodide_version}/xbuildenv/pyodide-root" | ||
) | ||
|
||
with FileLock(CIBW_CACHE_PATH / "xbuildenv.lock"): | ||
if pyodide_root.exists(): | ||
return str(pyodide_root) | ||
|
@@ -78,6 +127,8 @@ def install_xbuildenv(env: dict[str, str], pyodide_version: str) -> str: | |
# PYODIDE_ROOT so copy it first. | ||
env = dict(env) | ||
env.pop("PYODIDE_ROOT", None) | ||
|
||
# Install the xbuildenv | ||
call( | ||
"pyodide", | ||
"xbuildenv", | ||
|
@@ -165,13 +216,30 @@ def setup_python( | |
env=env, | ||
) | ||
|
||
log.step("Installing emscripten...") | ||
log.step(f"Installing Emscripten version: {python_configuration.emscripten_version} ...") | ||
emcc_path = install_emscripten(tmp, python_configuration.emscripten_version) | ||
|
||
env["PATH"] = os.pathsep.join([str(emcc_path.parent), env["PATH"]]) | ||
|
||
log.step("Installing Pyodide xbuildenv...") | ||
env["PYODIDE_ROOT"] = install_xbuildenv(env, python_configuration.pyodide_version) | ||
# Allow overriding the xbuildenv version with an environment variable. This allows | ||
# testing new Pyodide xbuildenv versions before they are officially released, or for | ||
# using a different Pyodide version other than the one that is listed to be compatible | ||
# with the pyodide-build version in the build-platforms.toml file. | ||
cibw_pyodide_version = os.environ.get( | ||
"CIBW_PYODIDE_VERSION", python_configuration.pyodide_version | ||
) | ||
# If there's a "v" prefix, remove it: both would be equally valid | ||
cibw_pyodide_version = cibw_pyodide_version.lstrip("v") | ||
log.step(f"Installing Pyodide xbuildenv version: {cibw_pyodide_version} ...") | ||
# Search for compatible xbuildenv versions | ||
compatible_versions = get_xbuildenv_versions(env) | ||
# and then validate the xbuildenv version | ||
validate_xbuildenv_version( | ||
cibw_pyodide_version, python_configuration.pyodide_build_version, compatible_versions | ||
) | ||
env["PYODIDE_ROOT"] = install_xbuildenv( | ||
env, python_configuration.pyodide_build_version, cibw_pyodide_version | ||
) | ||
|
||
return env | ||
|
||
|
@@ -219,7 +287,10 @@ def build(options: Options, tmp_path: Path) -> None: | |
|
||
log.build_start(config.identifier) | ||
|
||
identifier_tmp_dir = tmp_path / config.identifier | ||
# Include both the identifier and the Pyodide version in the temp directory name | ||
cibw_pyodide_version = os.environ.get("CIBW_PYODIDE_VERSION", config.pyodide_version) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again we should get the correct value into |
||
identifier_tmp_dir = tmp_path / f"{config.identifier}_{cibw_pyodide_version}" | ||
|
||
built_wheel_dir = identifier_tmp_dir / "built_wheel" | ||
repaired_wheel_dir = identifier_tmp_dir / "repaired_wheel" | ||
identifier_tmp_dir.mkdir() | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -890,6 +890,11 @@ | |
}, | ||
"test-requires": { | ||
"$ref": "#/properties/test-requires" | ||
}, | ||
"pyodide-version": { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This file gets generated, I don't see the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤔 Just tried There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't cibuildwheel/options.py also need updating? I don't see a |
||
"description": "Specify the Pyodide xbuildenv version to use for building", | ||
"type": "string", | ||
"title": "CIBW_PYODIDE_VERSION" | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -113,7 +113,14 @@ Pre-requisite: you need to have a matching host version of Python (unlike all | |
other cibuildwheel platforms). Linux host highly recommended; macOS hosts may | ||
work (e.g. invoking `pytest` directly in [`CIBW_TEST_COMMAND`](options.md#test-command) is [currently failing](https://github.com/pyodide/pyodide/issues/4802)) and Windows hosts will not work. | ||
|
||
You must target pyodide with `--platform pyodide` (or use `--only` on the identifier). | ||
You must target Pyodide with `--platform pyodide` (or use `--only` on the identifier). | ||
|
||
!!!tip | ||
|
||
It is also possible to target a specific Pyodide version by setting the `CIBW_PYODIDE_VERSION` environment variable to the desired version. Users are responsible for setting an appropriate Pyodide version according to the `pyodide-build` version. A list is available in Pyodide's [cross-build environments metadata file](https://github.com/pyodide/pyodide/blob/main/pyodide-cross-build-environments.json) or can be | ||
referenced using the `pyodide xbuildenv search` command. | ||
|
||
This option is **not available** in the `pyproject.toml` config. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a good reason that it isn't available in the pyproject.toml config? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems like it should be. |
||
|
||
## Configure a CI service | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other options can be passed either as a cli flag e.g.,
--pyodide-version
or as the corresponding environment variable in this caseCIBW_PYODIDE_VERSION
. They can also come from the cibuildwheel section inpyproject.toml
. We should handle this in the same way as all the other options. Then we can just usepython_configuration.pyodide_version
and it should already have the right value.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most options are not available as flags (and I wouldn't add this one), only stuff you often need on the command line, like
--platform
. Just env var and config.