]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-127503: Emscripten make Python.sh function as proper Python CLI (#127506)
authorHood Chatham <roberthoodchatham@gmail.com>
Thu, 5 Dec 2024 00:44:50 +0000 (01:44 +0100)
committerGitHub <noreply@github.com>
Thu, 5 Dec 2024 00:44:50 +0000 (08:44 +0800)
Modifies the python.sh script to work on macOS, and adapt to recent emscripten changes.

Tools/wasm/emscripten/__main__.py
Tools/wasm/emscripten/node_entry.mjs
configure
configure.ac

index 9ce8dd6a364ad6298a4b2e35f6cd5675e7ffc365..c998ed71309dad10eece3ce62ea9f0336feb09b8 100644 (file)
@@ -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")" "$@"
             """
         )
     )
@@ -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,
     )
index cb1c6ff3cba6aaf7b2e0d648f94b1e7cabb3858f..40ab1515cf28c113be43651b1e11aaad4bd7d60c 100644 (file)
@@ -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);
index c6790777793566baf23d611717380991c667f21e..2fa473b9fe32c0a62d7cb11feb66576c49796a8a 100755 (executable)
--- a/configure
+++ b/configure
@@ -9434,7 +9434,7 @@ fi
         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 " -sEXPORTED_RUNTIME_METHODS=FS,callMain"
+    as_fn_append LDFLAGS_NODIST " -sEXPORTED_RUNTIME_METHODS=FS,callMain,ENV"
     as_fn_append LDFLAGS_NODIST " -sEXPORTED_FUNCTIONS=_main,_Py_Version"
     as_fn_append LDFLAGS_NODIST " -sSTACK_SIZE=5MB"
 
index 9648e438cc74245ebc873d730fc8263c4ac9a85e..8ca8e0f78027426408ba30e01639076fcb3bfd04 100644 (file)
@@ -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"])