Skip to content
Open
Show file tree
Hide file tree
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
76 changes: 70 additions & 6 deletions Tools/wasm/emscripten/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

EMSCRIPTEN_DIR = Path(__file__).parent
CHECKOUT = EMSCRIPTEN_DIR.parent.parent.parent
EMSCRIPTEN_VERSION_FILE = EMSCRIPTEN_DIR / "emscripten_version.txt"

CROSS_BUILD_DIR = CHECKOUT / "cross-build"
NATIVE_BUILD_DIR = CROSS_BUILD_DIR / "build"
Expand All @@ -36,7 +37,56 @@
LOCAL_SETUP_MARKER = b"# Generated by Tools/wasm/emscripten.py\n"


def updated_env(updates={}):
@functools.cache
def get_required_emscripten_version():
"""Read the required emscripten version from emscripten_version.txt."""
return EMSCRIPTEN_VERSION_FILE.read_text().strip()


@functools.cache
def get_emsdk_activate_path(emsdk_cache):
required_version = get_required_emscripten_version()
return Path(emsdk_cache) / required_version / "emsdk_env.sh"


def validate_emsdk_version(emsdk_cache):
"""Validate that the emsdk cache contains the required emscripten version."""
required_version = get_required_emscripten_version()
emsdk_env = get_emsdk_activate_path(emsdk_cache)
if not emsdk_env.is_file():
print(
f"Required emscripten version {required_version} not found in {emsdk_cache}",
file=sys.stderr,
)
sys.exit(1)
print(f"✅ Emscripten version {required_version} found in {emsdk_cache}")


def parse_env(text):
result = {}
for line in text.splitlines():
key, val = line.split("=", 1)
result[key] = val
return result


@functools.cache
def get_emsdk_environ(emsdk_cache):
"""Returns os.environ updated by sourcing emsdk_env.sh"""
if not emsdk_cache:
return os.environ
env_text = subprocess.check_output(
[
"bash",
"-c",
f"EMSDK_QUIET=1 source {get_emsdk_activate_path(emsdk_cache)} && env",
],
text=True,
)
return parse_env(env_text)


def updated_env(updates, emsdk_cache):
"""Create a new dict representing the environment to use.

The changes made to the execution environment are printed out.
Expand All @@ -52,8 +102,7 @@ def updated_env(updates={}):
except subprocess.CalledProcessError:
pass # Might be building from a tarball.
# This layering lets SOURCE_DATE_EPOCH from os.environ takes precedence.
environment = env_defaults | os.environ | updates

environment = env_defaults | get_emsdk_environ(emsdk_cache) | updates
env_diff = {}
for key, value in environment.items():
if os.environ.get(key) != value:
Expand Down Expand Up @@ -204,7 +253,7 @@ def make_emscripten_libffi(context, working_dir):
)
call(
[EMSCRIPTEN_DIR / "make_libffi.sh"],
env=updated_env({"PREFIX": PREFIX_DIR}),
env=updated_env({"PREFIX": PREFIX_DIR}, context.emsdk_cache),
cwd=libffi_dir,
quiet=context.quiet,
)
Expand All @@ -231,6 +280,7 @@ def make_mpdec(context, working_dir):
],
cwd=mpdec_dir,
quiet=context.quiet,
env=updated_env({}, context.emsdk_cache),
)
call(
["make", "install"],
Expand Down Expand Up @@ -300,7 +350,7 @@ def configure_emscripten_python(context, working_dir):
configure.extend(context.args)
call(
configure,
env=updated_env(env_additions),
env=updated_env(env_additions, context.emsdk_cache),
quiet=context.quiet,
)

Expand Down Expand Up @@ -358,7 +408,7 @@ def make_emscripten_python(context, working_dir):
"""Run `make` for the emscripten/host build."""
call(
["make", "--jobs", str(cpu_count()), "all"],
env=updated_env(),
env=updated_env({}, context.emsdk_cache),
quiet=context.quiet,
)

Expand Down Expand Up @@ -439,6 +489,14 @@ def main():
dest="quiet",
help="Redirect output from subprocesses to a log file",
)
subcommand.add_argument(
"--emsdk-cache",
action="store",
default=None,
dest="emsdk_cache",
help="Path to emsdk cache directory. If provided, validates that "
"the required emscripten version is installed.",
)
for subcommand in configure_build, configure_host:
subcommand.add_argument(
"--clean",
Expand All @@ -463,6 +521,12 @@ def main():

context = parser.parse_args()

if context.emsdk_cache:
validate_emsdk_version(context.emsdk_cache)
context.emsdk_cache = Path(context.emsdk_cache).absolute()
else:
print("Build will use EMSDK from current environment.")

dispatch = {
"make-libffi": make_emscripten_libffi,
"make-mpdec": make_mpdec,
Expand Down
1 change: 1 addition & 0 deletions Tools/wasm/emscripten/emscripten_version.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
4.0.12
Loading