Skip to content

Commit

Permalink
gh-127503: Emscripten make Python.sh function as proper Python CLI (#…
Browse files Browse the repository at this point in the history
…127506)

Modifies the python.sh script to work on macOS, and adapt to recent emscripten changes.
  • Loading branch information
hoodmane authored Dec 5, 2024
1 parent 43634fc commit 87faf0a
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 17 deletions.
21 changes: 19 additions & 2 deletions Tools/wasm/emscripten/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,26 @@ def configure_emscripten_python(context, working_dir):
f"""\
#!/bin/sh
# Macs come with FreeBSD coreutils which doesn't have the -s option
# so feature detect and work around it.
if which grealpath > /dev/null; then
# It has brew installed gnu core utils, use that
REALPATH="grealpath -s"
elif which realpath > /dev/null && realpath --version 2&>1 | grep GNU > /dev/null; then
# realpath points to GNU realpath so use it.
REALPATH="realpath -s"
else
# Shim for macs without GNU coreutils
abs_path () {{
echo "$(cd "$(dirname "$1")" || exit; pwd)/$(basename "$1")"
}}
REALPATH=abs_path
fi
# 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)" "$@"
# Intentionally allow word splitting on NODEFLAGS.
exec {host_runner} $NODEFLAGS {node_entry} --this-program="$($REALPATH "$0")" "$@"
"""
)
)
Expand All @@ -233,7 +250,7 @@ def configure_emscripten_python(context, working_dir):
def make_emscripten_python(context, working_dir):
"""Run `make` for the emscripten/host build."""
call(
["make", "--jobs", str(cpu_count()), "commoninstall"],
["make", "--jobs", str(cpu_count()), "all"],
env=updated_env(),
quiet=context.quiet,
)
Expand Down
43 changes: 30 additions & 13 deletions Tools/wasm/emscripten/node_entry.mjs
Original file line number Diff line number Diff line change
@@ -1,30 +1,47 @@
import EmscriptenModule from "./python.mjs";
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import fs from "node:fs";

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);
process.stderr.write(
`Node version must be >= 18, got version ${process.version}\n`,
);
process.exit(1);
}
}

function rootDirsToMount(Module) {
return fs
.readdirSync("/")
.filter((dir) => !["dev", "lib", "proc"].includes(dir))
.map((dir) => "/" + dir);
}

function mountDirectories(Module) {
for (const dir of rootDirsToMount(Module)) {
Module.FS.mkdirTree(dir);
Module.FS.mount(Module.FS.filesystems.NODEFS, { root: dir }, dir);
}
}

const thisProgram = "--this-program=";
const thisProgramIndex = process.argv.findIndex((x) =>
x.startsWith(thisProgram),
);

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/");
mountDirectories(Module);
Module.FS.chdir(process.cwd());
Object.assign(Module.ENV, process.env);
},
// 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],
thisProgram: process.argv[thisProgramIndex],
// After python.sh come the arguments thatthe user passed to python.sh.
arguments: process.argv.slice(thisProgramIndex + 1),
};

await EmscriptenModule(settings);
2 changes: 1 addition & 1 deletion configure

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2332,7 +2332,7 @@ AS_CASE([$ac_sys_system],
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], [" -sEXPORTED_RUNTIME_METHODS=FS,callMain"])
AS_VAR_APPEND([LDFLAGS_NODIST], [" -sEXPORTED_RUNTIME_METHODS=FS,callMain,ENV"])
AS_VAR_APPEND([LDFLAGS_NODIST], [" -sEXPORTED_FUNCTIONS=_main,_Py_Version"])
AS_VAR_APPEND([LDFLAGS_NODIST], [" -sSTACK_SIZE=5MB"])
Expand Down

0 comments on commit 87faf0a

Please sign in to comment.