-
Notifications
You must be signed in to change notification settings - Fork 22
Add install-emscripten CLI command #243
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
base: main
Are you sure you want to change the base?
Add install-emscripten CLI command #243
Conversation
- Add new 'pyodide xbuildenv install-emscripten' command - Add clone_emscripten() method to clone emsdk repository - Add install_emscripten() method to install and activate Emscripten SDK - Add tests for new functionality
for more information, see https://pre-commit.ci
"--embedded", | ||
"--build=Release", |
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.
What's --embedded
and --build=Release
do?
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.
I believe the --embedded
flag tells emsdk to not modify your global shell startup files or system env. Essentially it places env variables into emsdk_env.sh
so the user can call source
on it later. The --build=Release
flag causes emsdk to build or fetch pre-built tools in release mode instead of debug mode. Not quite sure if either is necessary for pyodide's build but I kept the commands identical to @ryanking13's shared script just to be safe.
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.
I believe the --embedded flag tells emsdk to not modify your global shell startup files or system env.
This sounds like the default behavior. I think release build is also the default? Anyways we can leave it as is, but I normally would do this without either of these flags.
pyodide_build/xbuildenv.py
Outdated
) | ||
|
||
# Apply patches from xbuildenv/emsdk/patches directory to upstream/emscripten | ||
# Patches are applied after install but before activate |
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.
It doesn't matter if they are applied before or after activate.
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.
Noted and removed!
from pyodide_build.xbuildenv import CrossBuildEnvManager | ||
|
||
|
||
class TestInstallEmscripten: |
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.
This seems like a lot more tests than we need.
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.
I felt that as well but wanted to be thorough. Do you mean to get rid of all the tests or to keep some?
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.
My latest commit has the tests file stripped of some of the bloated cases, let me know if this works better!
Thanks for working on this @bulenty584! |
…in test_install_emscripten.py removed as well
for more information, see https://pre-commit.ci
from pyodide_build.xbuildenv import CrossBuildEnvManager | ||
|
||
|
||
class TestInstallEmscripten: |
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.
Remove the class? You don't seem to use it for anything.
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.
Ah yeah, you are completely correct. Removed!
…nd some basic reformatting
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.
Thanks for working on this. Could you also update the integration test?
Currently we are installing Emscripten in CI for integration test, but I think we can replace this with this new command to test if this new command works correctly.
pyodide_build/cli/xbuildenv.py
Outdated
@app.command("install-emscripten") | ||
def _install_emscripten( | ||
version: str = typer.Option( | ||
"latest", help="Emscripten SDK Version (default: latest)" |
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 default should be the one in the xbuildenv. Pyodide requires the same Emscripten version that is used to build the Pyodide runtime.
You can call get_build_flag("PYODIDE_EMSCRIPTEN_VERSION")
to get the proper version.
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.
Yup, added!
emsdk_dir = manager.install_emscripten(version) | ||
|
||
print("Installing emsdk complete.") | ||
print(f"Use `source {emsdk_dir}/emsdk_env.sh` to set up the environment.") |
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.
Instead of requiring people to manually source the directory, it would be nice to detect the emscripten installation directory and use it during the build.
Let's do that in a separate PR to reduce the diff, for now, it looks good.
pyodide_build/xbuildenv.py
Outdated
|
||
xbuild_root = self.symlink_dir.resolve() | ||
emsdk_dir = xbuild_root / "emsdk" | ||
patches_dir = emsdk_dir / "patches" |
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.
I think the patches should be under self.pyodide_root / "emsdk" / "patches"
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.
Ah yes, just saw that in the file as well. Edited in the new commit.
pyodide_build/xbuildenv.py
Outdated
|
||
# Apply patches from xbuildenv/emsdk/patches directory to upstream/emscripten | ||
subprocess.run( | ||
f"cat {patches_dir}/*.patch | patch -p1 --verbose", |
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.
Note that the patch might fail is that emscripten version passed by the user is different from the version that the patch is generated. I think we ned to gracefully catch those errors and show proper error message.
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.
Ah I must have overlooked that. I added some error handling for this case as well.
) | ||
|
||
|
||
def test_install_emscripten_patch_application(tmp_path, monkeypatch): |
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.
This test looks redundant as the full pipeline is already tested in the previous tests.
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.
Noted and changed!
manager.install_emscripten() | ||
|
||
|
||
def test_install_emscripten_patch_application_sequence(tmp_path, monkeypatch): |
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.
This also looks a bit redundant
pyodide_build/xbuildenv.py
Outdated
|
||
return version | ||
|
||
def clone_emscripten(self, emsdk_dir: Path | str | None = None) -> Path: |
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.
Let's make this function private, to avoid using it directly outside.
def clone_emscripten(self, emsdk_dir: Path | str | None = None) -> Path: | |
def _clone_emscripten(self, emsdk_dir: Path | str | None = None) -> Path: |
# Verify subprocess calls | ||
# install_emscripten makes 4 calls: clone + install + patch + activate |
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.
As these are already tested in test_install_emscripten.py
, I think these are unnecessary. Testing the outputs should be enough. Same for all other functions in this file.
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.
Yes after re-examining them I agree. Removed as well.
1. Changed default version to `get_build_flag("PYODIDE_EMSCRIPTEN_VERSION")` 2. Updated `clone_emscripten` to `_clone_emscripten` 3. Removed and edited redundant tests in both new test files 4. Updated patch path in `xbuildenv.py` and added new command to CI workflow
for more information, see https://pre-commit.ci
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.
Thanks! code wise looks good to me overall. I left some minor comments. Also, I added integration
label to trigger integration tests.
pyodide_build/cli/xbuildenv.py
Outdated
version: str = typer.Option( | ||
get_build_flag("PYODIDE_EMSCRIPTEN_VERSION"), | ||
help=f"Emscripten SDK Version (default: ${get_build_flag('PYODIDE_EMSCRIPTEN_VERSION')})", |
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.
Let's not call this inside the function's default value. Calling get_build_flag
requires installing xbuildenv and it is a heavy operation.
You can set the default to None, and call get_build_flag
inside the function explicitly when the version is not given.
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.
Oh ok, I took it out and added the default check in the function.
.github/workflows/main.yml
Outdated
with: | ||
version: ${{ env.EMSCRIPTEN_VERSION }} | ||
actions-cache-folder: ${{env.EMSDK_CACHE_FOLDER}} | ||
run: pyodide install-emscripten |
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.
This should be pyodide xbuildenv install-emscripten
.
Also as the current implementation does not activate the emsdk after running this command. It should be called manually.
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.
Ah yes, totally my bad. Added both in now!
Removed the get_build_flag command from xbuildenv cli and added default behavior as none
Message echoed after installation complete for user to show the path to the emsdk_env.sh so that user can activate it manually in their shell.