Skip to content

Commit 1629d2c

Browse files
authored
gh-126898: Emscripten support: Use es6 modules (#126903)
Modify Emscripten support to use ES6 modules.
1 parent 32428cf commit 1629d2c

File tree

6 files changed

+60
-30
lines changed

6 files changed

+60
-30
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
The Emscripten build of Python is now based on ES6 modules.

Tools/wasm/emscripten/__main__.py

+25-11
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,22 @@
44
import contextlib
55
import functools
66
import os
7-
8-
try:
9-
from os import process_cpu_count as cpu_count
10-
except ImportError:
11-
from os import cpu_count
12-
from pathlib import Path
137
import shutil
148
import subprocess
159
import sys
1610
import sysconfig
1711
import tempfile
12+
from pathlib import Path
13+
from textwrap import dedent
14+
15+
try:
16+
from os import process_cpu_count as cpu_count
17+
except ImportError:
18+
from os import cpu_count
1819

19-
WASM_DIR = Path(__file__).parent.parent
20-
CHECKOUT = WASM_DIR.parent.parent
20+
21+
EMSCRIPTEN_DIR = Path(__file__).parent
22+
CHECKOUT = EMSCRIPTEN_DIR.parent.parent.parent
2123

2224
CROSS_BUILD_DIR = CHECKOUT / "cross-build"
2325
BUILD_DIR = CROSS_BUILD_DIR / "build"
@@ -72,7 +74,7 @@ def wrapper(context):
7274
print("⎯" * terminal_width)
7375
print("📁", working_dir)
7476
if clean_ok and getattr(context, "clean", False) and working_dir.exists():
75-
print(f"🚮 Deleting directory (--clean)...")
77+
print("🚮 Deleting directory (--clean)...")
7678
shutil.rmtree(working_dir)
7779

7880
working_dir.mkdir(parents=True, exist_ok=True)
@@ -207,9 +209,21 @@ def configure_emscripten_python(context, working_dir):
207209
quiet=context.quiet,
208210
)
209211

210-
python_js = working_dir / "python.js"
212+
shutil.copy(EMSCRIPTEN_DIR / "node_entry.mjs", working_dir / "node_entry.mjs")
213+
214+
node_entry = working_dir / "node_entry.mjs"
211215
exec_script = working_dir / "python.sh"
212-
exec_script.write_text(f'#!/bin/sh\nexec {host_runner} {python_js} "$@"\n')
216+
exec_script.write_text(
217+
dedent(
218+
f"""\
219+
#!/bin/sh
220+
221+
# We compute our own path, not following symlinks and pass it in so that
222+
# node_entry.mjs can set sys.executable correctly.
223+
exec {host_runner} {node_entry} "$(realpath -s $0)" "$@"
224+
"""
225+
)
226+
)
213227
exec_script.chmod(0o755)
214228
print(f"🏃‍♀️ Created {exec_script} ... ")
215229
sys.stdout.flush()

Tools/wasm/emscripten/node_entry.mjs

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import EmscriptenModule from "./python.mjs";
2+
import { dirname } from 'node:path';
3+
import { fileURLToPath } from 'node:url';
4+
5+
if (process?.versions?.node) {
6+
const nodeVersion = Number(process.versions.node.split(".", 1)[0]);
7+
if (nodeVersion < 18) {
8+
process.stderr.write(
9+
`Node version must be >= 18, got version ${process.version}\n`,
10+
);
11+
process.exit(1);
12+
}
13+
}
14+
15+
const settings = {
16+
preRun(Module) {
17+
const __dirname = dirname(fileURLToPath(import.meta.url));
18+
Module.FS.mkdirTree("/lib/");
19+
Module.FS.mount(Module.FS.filesystems.NODEFS, { root: __dirname + "/lib/" }, "/lib/");
20+
},
21+
// The first three arguments are: "node", path to this file, path to
22+
// python.sh. After that come the arguments the user passed to python.sh.
23+
arguments: process.argv.slice(3),
24+
// Ensure that sys.executable, sys._base_executable, etc point to python.sh
25+
// not to this file. To properly handle symlinks, python.sh needs to compute
26+
// its own path.
27+
thisProgram: process.argv[2],
28+
};
29+
30+
await EmscriptenModule(settings);

Tools/wasm/emscripten/node_pre.js

-15
This file was deleted.

configure

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

configure.ac

+2-2
Original file line numberDiff line numberDiff line change
@@ -1327,7 +1327,7 @@ AC_ARG_WITH([suffix],
13271327
)
13281328
], [
13291329
AS_CASE([$ac_sys_system],
1330-
[Emscripten], [EXEEXT=.js],
1330+
[Emscripten], [EXEEXT=.mjs],
13311331
[WASI], [EXEEXT=.wasm],
13321332
[EXEEXT=]
13331333
)
@@ -2328,6 +2328,7 @@ AS_CASE([$ac_sys_system],
23282328
23292329
dnl Include file system support
23302330
AS_VAR_APPEND([LDFLAGS_NODIST], [" -sFORCE_FILESYSTEM -lidbfs.js -lnodefs.js -lproxyfs.js -lworkerfs.js"])
2331+
AS_VAR_APPEND([LDFLAGS_NODIST], [" -sEXPORTED_RUNTIME_METHODS=FS"])
23312332
23322333
AS_VAR_IF([enable_wasm_dynamic_linking], [yes], [
23332334
AS_VAR_APPEND([LINKFORSHARED], [" -sMAIN_MODULE"])
@@ -2341,7 +2342,6 @@ AS_CASE([$ac_sys_system],
23412342
AS_VAR_APPEND([LDFLAGS_NODIST], [" -sALLOW_MEMORY_GROWTH"])
23422343
dnl not completely sure whether or not we want -sEXIT_RUNTIME, keeping it for now.
23432344
AS_VAR_APPEND([LDFLAGS_NODIST], [" -sEXIT_RUNTIME"])
2344-
AS_VAR_APPEND([LDFLAGS_NODIST], [" --pre-js=\$(srcdir)/Tools/wasm/emscripten/node_pre.js"])
23452345
WASM_LINKFORSHARED_DEBUG="-gseparate-dwarf --emit-symbol-map"
23462346
23472347
AS_VAR_IF([wasm_debug], [yes], [

0 commit comments

Comments
 (0)