gh-126898: Emscripten support: Use es6 modules (#126903)

Modify Emscripten support to use ES6 modules.
This commit is contained in:
Hood Chatham 2024-11-21 05:10:46 +01:00 committed by GitHub
parent 32428cf9ea
commit 1629d2ca56
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 60 additions and 30 deletions

View File

@ -0,0 +1 @@
The Emscripten build of Python is now based on ES6 modules.

View File

@ -4,20 +4,22 @@
import contextlib import contextlib
import functools import functools
import os import os
try:
from os import process_cpu_count as cpu_count
except ImportError:
from os import cpu_count
from pathlib import Path
import shutil import shutil
import subprocess import subprocess
import sys import sys
import sysconfig import sysconfig
import tempfile import tempfile
from pathlib import Path
from textwrap import dedent
WASM_DIR = Path(__file__).parent.parent try:
CHECKOUT = WASM_DIR.parent.parent from os import process_cpu_count as cpu_count
except ImportError:
from os import cpu_count
EMSCRIPTEN_DIR = Path(__file__).parent
CHECKOUT = EMSCRIPTEN_DIR.parent.parent.parent
CROSS_BUILD_DIR = CHECKOUT / "cross-build" CROSS_BUILD_DIR = CHECKOUT / "cross-build"
BUILD_DIR = CROSS_BUILD_DIR / "build" BUILD_DIR = CROSS_BUILD_DIR / "build"
@ -72,7 +74,7 @@ def wrapper(context):
print("" * terminal_width) print("" * terminal_width)
print("📁", working_dir) print("📁", working_dir)
if clean_ok and getattr(context, "clean", False) and working_dir.exists(): if clean_ok and getattr(context, "clean", False) and working_dir.exists():
print(f"🚮 Deleting directory (--clean)...") print("🚮 Deleting directory (--clean)...")
shutil.rmtree(working_dir) shutil.rmtree(working_dir)
working_dir.mkdir(parents=True, exist_ok=True) working_dir.mkdir(parents=True, exist_ok=True)
@ -207,9 +209,21 @@ def configure_emscripten_python(context, working_dir):
quiet=context.quiet, quiet=context.quiet,
) )
python_js = working_dir / "python.js" shutil.copy(EMSCRIPTEN_DIR / "node_entry.mjs", working_dir / "node_entry.mjs")
node_entry = working_dir / "node_entry.mjs"
exec_script = working_dir / "python.sh" exec_script = working_dir / "python.sh"
exec_script.write_text(f'#!/bin/sh\nexec {host_runner} {python_js} "$@"\n') exec_script.write_text(
dedent(
f"""\
#!/bin/sh
# We compute our own path, not following symlinks and pass it in so that
# node_entry.mjs can set sys.executable correctly.
exec {host_runner} {node_entry} "$(realpath -s $0)" "$@"
"""
)
)
exec_script.chmod(0o755) exec_script.chmod(0o755)
print(f"🏃‍♀️ Created {exec_script} ... ") print(f"🏃‍♀️ Created {exec_script} ... ")
sys.stdout.flush() sys.stdout.flush()

View File

@ -0,0 +1,30 @@
import EmscriptenModule from "./python.mjs";
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
if (process?.versions?.node) {
const nodeVersion = Number(process.versions.node.split(".", 1)[0]);
if (nodeVersion < 18) {
process.stderr.write(
`Node version must be >= 18, got version ${process.version}\n`,
);
process.exit(1);
}
}
const settings = {
preRun(Module) {
const __dirname = dirname(fileURLToPath(import.meta.url));
Module.FS.mkdirTree("/lib/");
Module.FS.mount(Module.FS.filesystems.NODEFS, { root: __dirname + "/lib/" }, "/lib/");
},
// The first three arguments are: "node", path to this file, path to
// python.sh. After that come the arguments the user passed to python.sh.
arguments: process.argv.slice(3),
// Ensure that sys.executable, sys._base_executable, etc point to python.sh
// not to this file. To properly handle symlinks, python.sh needs to compute
// its own path.
thisProgram: process.argv[2],
};
await EmscriptenModule(settings);

View File

@ -1,15 +0,0 @@
// If process is undefined, we're not running in the node runtime let it go I
// guess?
if (typeof process !== "undefined") {
const nodeVersion = Number(process.versions.node.split(".", 1)[0]);
if (nodeVersion < 18) {
process.stderr.write(
`Node version must be >= 18, got version ${process.version}\n`,
);
process.exit(1);
}
Module.preRun = () => {
FS.mkdirTree("/lib/");
FS.mount(NODEFS, { root: __dirname + "/lib/" }, "/lib/");
};
}

4
configure generated vendored
View File

@ -7291,7 +7291,7 @@ else $as_nop
case $ac_sys_system in #( case $ac_sys_system in #(
Emscripten) : Emscripten) :
EXEEXT=.js ;; #( EXEEXT=.mjs ;; #(
WASI) : WASI) :
EXEEXT=.wasm ;; #( EXEEXT=.wasm ;; #(
*) : *) :
@ -9432,6 +9432,7 @@ fi
as_fn_append LDFLAGS_NODIST " -sWASM_BIGINT" as_fn_append LDFLAGS_NODIST " -sWASM_BIGINT"
as_fn_append LDFLAGS_NODIST " -sFORCE_FILESYSTEM -lidbfs.js -lnodefs.js -lproxyfs.js -lworkerfs.js" as_fn_append LDFLAGS_NODIST " -sFORCE_FILESYSTEM -lidbfs.js -lnodefs.js -lproxyfs.js -lworkerfs.js"
as_fn_append LDFLAGS_NODIST " -sEXPORTED_RUNTIME_METHODS=FS"
if test "x$enable_wasm_dynamic_linking" = xyes if test "x$enable_wasm_dynamic_linking" = xyes
then : then :
@ -9450,7 +9451,6 @@ then :
fi fi
as_fn_append LDFLAGS_NODIST " -sALLOW_MEMORY_GROWTH" as_fn_append LDFLAGS_NODIST " -sALLOW_MEMORY_GROWTH"
as_fn_append LDFLAGS_NODIST " -sEXIT_RUNTIME" as_fn_append LDFLAGS_NODIST " -sEXIT_RUNTIME"
as_fn_append LDFLAGS_NODIST " --pre-js=\$(srcdir)/Tools/wasm/emscripten/node_pre.js"
WASM_LINKFORSHARED_DEBUG="-gseparate-dwarf --emit-symbol-map" WASM_LINKFORSHARED_DEBUG="-gseparate-dwarf --emit-symbol-map"
if test "x$wasm_debug" = xyes if test "x$wasm_debug" = xyes

View File

@ -1327,7 +1327,7 @@ AC_ARG_WITH([suffix],
) )
], [ ], [
AS_CASE([$ac_sys_system], AS_CASE([$ac_sys_system],
[Emscripten], [EXEEXT=.js], [Emscripten], [EXEEXT=.mjs],
[WASI], [EXEEXT=.wasm], [WASI], [EXEEXT=.wasm],
[EXEEXT=] [EXEEXT=]
) )
@ -2328,6 +2328,7 @@ AS_CASE([$ac_sys_system],
dnl Include file system support dnl Include file system support
AS_VAR_APPEND([LDFLAGS_NODIST], [" -sFORCE_FILESYSTEM -lidbfs.js -lnodefs.js -lproxyfs.js -lworkerfs.js"]) AS_VAR_APPEND([LDFLAGS_NODIST], [" -sFORCE_FILESYSTEM -lidbfs.js -lnodefs.js -lproxyfs.js -lworkerfs.js"])
AS_VAR_APPEND([LDFLAGS_NODIST], [" -sEXPORTED_RUNTIME_METHODS=FS"])
AS_VAR_IF([enable_wasm_dynamic_linking], [yes], [ AS_VAR_IF([enable_wasm_dynamic_linking], [yes], [
AS_VAR_APPEND([LINKFORSHARED], [" -sMAIN_MODULE"]) AS_VAR_APPEND([LINKFORSHARED], [" -sMAIN_MODULE"])
@ -2341,7 +2342,6 @@ AS_CASE([$ac_sys_system],
AS_VAR_APPEND([LDFLAGS_NODIST], [" -sALLOW_MEMORY_GROWTH"]) AS_VAR_APPEND([LDFLAGS_NODIST], [" -sALLOW_MEMORY_GROWTH"])
dnl not completely sure whether or not we want -sEXIT_RUNTIME, keeping it for now. dnl not completely sure whether or not we want -sEXIT_RUNTIME, keeping it for now.
AS_VAR_APPEND([LDFLAGS_NODIST], [" -sEXIT_RUNTIME"]) AS_VAR_APPEND([LDFLAGS_NODIST], [" -sEXIT_RUNTIME"])
AS_VAR_APPEND([LDFLAGS_NODIST], [" --pre-js=\$(srcdir)/Tools/wasm/emscripten/node_pre.js"])
WASM_LINKFORSHARED_DEBUG="-gseparate-dwarf --emit-symbol-map" WASM_LINKFORSHARED_DEBUG="-gseparate-dwarf --emit-symbol-map"
AS_VAR_IF([wasm_debug], [yes], [ AS_VAR_IF([wasm_debug], [yes], [