summaryrefslogtreecommitdiffstats
path: root/Tools/wasm/README.md
diff options
context:
space:
mode:
authorHood Chatham <roberthoodchatham@gmail.com>2024-12-02 23:30:24 (GMT)
committerGitHub <noreply@github.com>2024-12-02 23:30:24 (GMT)
commitbfb0788bfcaab7474c1be0605552744e15082ee9 (patch)
tree455a8e723f50b1f9e6782c4210c5d39b57f23b3b /Tools/wasm/README.md
parentedefb8678a11a20bdcdcbb8bb6a62ae22101bb51 (diff)
downloadcpython-bfb0788bfcaab7474c1be0605552744e15082ee9.zip
cpython-bfb0788bfcaab7474c1be0605552744e15082ee9.tar.gz
cpython-bfb0788bfcaab7474c1be0605552744e15082ee9.tar.bz2
gh-127111: Emscripten Make web example work again (#127113)
Moves the Emscripten web example into a standalone folder, and updates Makefile targets to build the web example. Instructions for usage have also been added.
Diffstat (limited to 'Tools/wasm/README.md')
-rw-r--r--Tools/wasm/README.md122
1 files changed, 86 insertions, 36 deletions
diff --git a/Tools/wasm/README.md b/Tools/wasm/README.md
index 3f4211f..4802d96 100644
--- a/Tools/wasm/README.md
+++ b/Tools/wasm/README.md
@@ -23,9 +23,9 @@ https://github.com/psf/webassembly for more information.
To cross compile to the ``wasm32-emscripten`` platform you need
[the Emscripten compiler toolchain](https://emscripten.org/),
-a Python interpreter, and an installation of Node version 18 or newer. Emscripten
-version 3.1.42 or newer is recommended. All commands below are relative to a checkout
-of the Python repository.
+a Python interpreter, and an installation of Node version 18 or newer.
+Emscripten version 3.1.73 or newer is recommended. All commands below are
+relative to a checkout of the Python repository.
#### Install [the Emscripten compiler toolchain](https://emscripten.org/docs/getting_started/downloads.html)
@@ -50,7 +50,7 @@ sourced. Otherwise the source script removes the environment variable.
export EM_COMPILER_WRAPPER=ccache
```
-### Compile and build Python interpreter
+#### Compile and build Python interpreter
You can use `python Tools/wasm/emscripten` to compile and build targetting
Emscripten. You can do everything at once with:
@@ -70,6 +70,88 @@ instance, to do a debug build, you can use:
python Tools/wasm/emscripten build --with-py-debug
```
+### Running from node
+
+If you want to run the normal Python CLI, you can use `python.sh`. It takes the
+same options as the normal Python CLI entrypoint, though the REPL does not
+function and will crash.
+
+`python.sh` invokes `node_entry.mjs` which imports the Emscripten module for the
+Python process and starts it up with the appropriate settings. If you wish to
+make a node application that "embeds" the interpreter instead of acting like the
+CLI you will need to write your own alternative to `node_entry.mjs`.
+
+
+### The Web Example
+
+When building for Emscripten, the web example will be built automatically. It is
+in the ``web_example`` directory. To run the web example, ``cd`` into the
+``web_example`` directory, then run ``python server.py``. This will start a web
+server; you can then visit ``http://localhost:8000/python.html`` in a browser to
+see a simple REPL example.
+
+The web example relies on a bug fix in Emscripten version 3.1.73 so if you build
+with earlier versions of Emscripten it may not work. The web example uses
+``SharedArrayBuffer``. For security reasons browsers only provide
+``SharedArrayBuffer`` in secure environments with cross-origin isolation. The
+webserver must send cross-origin headers and correct MIME types for the
+JavaScript and WebAssembly files. Otherwise the terminal will fail to load with
+an error message like ``ReferenceError: SharedArrayBuffer is not defined``. See
+more information here:
+https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements
+
+Note that ``SharedArrayBuffer`` is _not required_ to use Python itself, only the
+web example. If cross-origin isolation is not appropriate for your use case you
+may make your own application embedding `python.mjs` which does not use
+``SharedArrayBuffer`` and serve it without the cross-origin isolation headers.
+
+### Embedding Python in a custom JavaScript application
+
+You can look at `python.worker.mjs` and `node_entry.mjs` for inspiration. At a
+minimum you must import ``createEmscriptenModule`` and you need to call
+``createEmscriptenModule`` with an appropriate settings object. This settings
+object will need a prerun hook that installs the Python standard library into
+the Emscripten file system.
+
+#### NodeJs
+
+In Node, you can use the NodeFS to mount the standard library in your native
+file system into the Emscripten file system:
+```js
+import createEmscriptenModule from "./python.mjs";
+
+await createEmscriptenModule({
+ preRun(Module) {
+ Module.FS.mount(
+ Module.FS.filesystems.NODEFS,
+ { root: "/path/to/python/stdlib" },
+ "/lib/",
+ );
+ },
+});
+```
+
+#### Browser
+
+In the browser, the simplest approach is to put the standard library in a zip
+file it and install it. With Python 3.14 this could look like:
+```js
+import createEmscriptenModule from "./python.mjs";
+
+await createEmscriptenModule({
+ async preRun(Module) {
+ Module.FS.mkdirTree("/lib/python3.14/lib-dynload/");
+ Module.addRunDependency("install-stdlib");
+ const resp = await fetch("python3.14.zip");
+ const stdlibBuffer = await resp.arrayBuffer();
+ Module.FS.writeFile(`/lib/python314.zip`, new Uint8Array(stdlibBuffer), {
+ canOwn: true,
+ });
+ Module.removeRunDependency("install-stdlib");
+ },
+});
+```
+
### Limitations and issues
#### Network stack
@@ -151,38 +233,6 @@ python Tools/wasm/emscripten build --with-py-debug
- Test modules are disabled by default. Use ``--enable-test-modules`` build
test modules like ``_testcapi``.
-### wasm32-emscripten in node
-
-Node builds use ``NODERAWFS``.
-
-- Node RawFS allows direct access to the host file system without need to
- perform ``FS.mount()`` call.
-
-### Hosting Python WASM builds
-
-The simple REPL terminal uses SharedArrayBuffer. For security reasons
-browsers only provide the feature in secure environments with cross-origin
-isolation. The webserver must send cross-origin headers and correct MIME types
-for the JavaScript and WASM files. Otherwise the terminal will fail to load
-with an error message like ``Browsers disable shared array buffer``.
-
-#### Apache HTTP .htaccess
-
-Place a ``.htaccess`` file in the same directory as ``python.wasm``.
-
-```
-# .htaccess
-Header set Cross-Origin-Opener-Policy same-origin
-Header set Cross-Origin-Embedder-Policy require-corp
-
-AddType application/javascript js
-AddType application/wasm wasm
-
-<IfModule mod_deflate.c>
- AddOutputFilterByType DEFLATE text/html application/javascript application/wasm
-</IfModule>
-```
-
## WASI (wasm32-wasi)
See [the devguide on how to build and run for WASI](https://devguide.python.org/getting-started/setup-building/#wasi).