Skip to content

Commit

Permalink
Add an Emscripten version check for out of tree builds (#2975)
Browse files Browse the repository at this point in the history
The out of tree build system applies an abi tag based on `PYODIDE_EMSCRIPTEN_VERSION`
in `Makefile.envs`. Prior to this PR, it will happily accept the version of emscripten (say 3.1.18)
and produce a wheel tagged like it was produced from the expected Emscripten version (say 3.1.14).
This causes confusing errors due to ABI mismatch see igraph/python-igraph#560. This error message
should help prevent such confusion.
  • Loading branch information
hoodmane authored Aug 18, 2022
1 parent 9cb6b96 commit 2ba11a8
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 0 deletions.
30 changes: 30 additions & 0 deletions pyodide_build/common.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import contextlib
import functools
import os
import re
import subprocess
import sys
from collections.abc import Generator, Iterable, Iterator, Mapping
Expand All @@ -17,6 +18,35 @@ def emscripten_version() -> str:
return get_make_flag("PYODIDE_EMSCRIPTEN_VERSION")


def get_emscripten_version_info() -> str:
"""Extracted for testing purposes."""
return subprocess.run(["emcc", "-v"], capture_output=True, encoding="utf8").stderr


def check_emscripten_version() -> None:
needed_version = emscripten_version()
try:
version_info = get_emscripten_version_info()
except FileNotFoundError:
raise RuntimeError(
f"No Emscripten compiler found. Need Emscripten version {needed_version}"
) from None
installed_version = None
try:
for x in reversed(version_info.partition("\n")[0].split(" ")):
if re.match(r"[0-9]+\.[0-9]+\.[0-9]+", x):
installed_version = x
break
except Exception:
raise RuntimeError("Failed to determine Emscripten version.")
if installed_version is None:
raise RuntimeError("Failed to determine Emscripten version.")
if installed_version != needed_version:
raise RuntimeError(
f"Incorrect Emscripten version {installed_version}. Need Emscripten version {needed_version}"
)


def platform() -> str:
emscripten_version = get_make_flag("PYODIDE_EMSCRIPTEN_VERSION")
version = emscripten_version.replace(".", "_")
Expand Down
1 change: 1 addition & 0 deletions pyodide_build/out_of_tree/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def run(exports, args):


def main(parser_args: argparse.Namespace) -> None:
common.check_emscripten_version()
run(parser_args.exports, parser_args.backend_args)


Expand Down
55 changes: 55 additions & 0 deletions pyodide_build/tests/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,58 @@ def test_search_pyodide_root(tmp_path):
pyproject_file.unlink()
with pytest.raises(FileNotFoundError):
search_pyodide_root(tmp_path)


def test_check_emscripten_version(monkeypatch):
from pyodide_build import common

s = None

def get_emscripten_version_info():
return s

needed_version = common.emscripten_version()
monkeypatch.setattr(
common, "get_emscripten_version_info", get_emscripten_version_info
)
s = """\
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.4 (14cd48e6ead13b02a79f47df1a252abc501a3269)
clang version 15.0.0 (https://github.com/llvm/llvm-project ce5588fdf478b6af724977c11a405685cebc3d26)
Target: wasm32-unknown-emscripten
Thread model: posix
"""
with pytest.raises(
RuntimeError,
match=f"Incorrect Emscripten version 3.1.4. Need Emscripten version {needed_version}",
):
common.check_emscripten_version()

s = """\
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 1.39.20
clang version 12.0.0 (/b/s/w/ir/cache/git/chromium.googlesource.com-external-jackfan.us.kg-llvm-llvm--project 55fa315b0352b63454206600d6803fafacb42d5e)
"""

with pytest.raises(
RuntimeError,
match=f"Incorrect Emscripten version 1.39.20. Need Emscripten version {needed_version}",
):
common.check_emscripten_version()

s = """\
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.14 (4343cbec72b7db283ea3bda1adc6cb1811ae9a73)
clang version 15.0.0 (https://github.com/llvm/llvm-project 7effcbda49ba32991b8955821b8fdbd4f8f303e2)
"""
common.check_emscripten_version()

def get_emscripten_version_info(): # type: ignore[no-redef]
raise FileNotFoundError()

monkeypatch.setattr(
common, "get_emscripten_version_info", get_emscripten_version_info
)

with pytest.raises(
RuntimeError,
match=f"No Emscripten compiler found. Need Emscripten version {needed_version}",
):
common.check_emscripten_version()

0 comments on commit 2ba11a8

Please sign in to comment.