| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
parent directory.. | ||||
WARNING: WASM support is work-in-progress! Lots of features are not working yet.
This directory contains configuration and helpers to facilitate cross compilation of CPython to WebAssembly (WASM). Python supports Emscripten (wasm32-emscripten) and WASI (wasm32-wasi) targets. Emscripten builds run in modern browsers and JavaScript runtimes like Node.js. WASI builds use WASM runtimes such as wasmtime.
Users and developers are encouraged to use the script Tools/wasm/wasm_build.py. The tool automates the build process and provides assistance with installation of SDKs.
For now the build system has two target flavors. The Emscripten/browser target (--with-emscripten-target=browser) is optimized for browsers. It comes with a reduced and preloaded stdlib without tests and threading support. The Emscripten/node target has threading enabled and can access the file system directly.
Cross compiling to the wasm32-emscripten platform needs the Emscripten SDK and a build Python interpreter. Emscripten 3.1.19 or newer are recommended. All commands below are relative to a repository checkout.
Christian Heimes maintains a container image with Emscripten SDK, Python build dependencies, WASI-SDK, wasmtime, and several additional tools.
From within your local CPython repo clone, run one of the following commands:
# Fedora, RHEL, CentOS podman run --rm -ti -v $(pwd):/python-wasm/cpython:Z -w /python-wasm/cpython quay.io/tiran/cpythonbuild:emsdk3 # other docker run --rm -ti -v $(pwd):/python-wasm/cpython -w /python-wasm/cpython quay.io/tiran/cpythonbuild:emsdk3
From within the container, run the following command:
./Tools/wasm/wasm_build.py buildThe command is roughly equivalent to:
mkdir -p builddir/build
pushd builddir/build
../../configure -C
make -j$(nproc)
popd./Tools/wasm/wasm_build.py emscripten-browserThe command is roughly equivalent to:
mkdir -p builddir/emscripten-browser
pushd builddir/emscripten-browser
CONFIG_SITE=../../Tools/wasm/config.site-wasm32-emscripten \
emconfigure ../../configure -C \
--host=wasm32-unknown-emscripten \
--build=$(../../config.guess) \
--with-emscripten-target=browser \
--with-build-python=$(pwd)/../build/python
emmake make -j$(nproc)
popdServe python.html with a local webserver and open the file in a browser. Python comes with a minimal web server script that sets necessary HTTP headers like COOP, COEP, and mimetypes. Run the script outside the container and from the root of the CPython checkout.
./Tools/wasm/wasm_webserver.pyand open http://localhost:8000/builddir/emscripten-browser/python.html . This directory structure enables the C/C++ DevTools Support (DWARF) to load C and header files with debug builds.
./Tools/wasm/wasm_build.py emscripten-browser-dlThe command is roughly equivalent to:
mkdir -p builddir/emscripten-node-dl
pushd builddir/emscripten-node-dl
CONFIG_SITE=../../Tools/wasm/config.site-wasm32-emscripten \
emconfigure ../../configure -C \
--host=wasm32-unknown-emscripten \
--build=$(../../config.guess) \
--with-emscripten-target=node \
--enable-wasm-dynamic-linking \
--with-build-python=$(pwd)/../build/python
emmake make -j$(nproc)
popdnode --experimental-wasm-threads --experimental-wasm-bulk-memory --experimental-wasm-bigint builddir/emscripten-node-dl/python.js(--experimental-wasm-bigint is not needed with recent NodeJS versions)
Emscripten before 3.1.8 has known bugs that can cause memory corruption and resource leaks. 3.1.8 contains several fixes for bugs in date and time functions.
Node builds use NODERAWFS.
The simple REPL terminal uses SharedArrayBuffer. For security reasons browsers only provide the feature in secure environents 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.
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 builds require WASI SDK 16.0+.
The script wasi-env sets necessary compiler and linker flags as well as pkg-config overrides. The script assumes that WASI-SDK is installed in /opt/wasi-sdk or $WASI_SDK_PATH.
./Tools/wasm/wasm_build.py wasiThe command is roughly equivalent to:
mkdir -p builddir/wasi
pushd builddir/wasi
CONFIG_SITE=../../Tools/wasm/config.site-wasm32-wasi \
../../Tools/wasm/wasi-env ../../configure -C \
--host=wasm32-unknown-wasi \
--build=$(../../config.guess) \
--with-build-python=$(pwd)/../build/python
make -j$(nproc)
popdA lot of Emscripten limitations also apply to WASI. Noticeable restrictions are:
import os, sys
if sys.platform == "emscripten":
# Python on Emscripten
if sys.platform == "wasi":
# Python on WASI
if os.name == "posix":
# WASM platforms identify as POSIX-like.
# Windows does not provide os.uname().
machine = os.uname().machine
if machine.startswith("wasm"):
# WebAssembly (wasm32, wasm64 in the future)>>> import os, sys
>>> os.uname()
posix.uname_result(
sysname='Emscripten',
nodename='emscripten',
release='3.1.19',
version='#1',
machine='wasm32'
)
>>> os.name
'posix'
>>> sys.platform
'emscripten'
>>> sys._emscripten_info
sys._emscripten_info(
emscripten_version=(3, 1, 10),
runtime='Mozilla/5.0 (X11; Linux x86_64; rv:104.0) Gecko/20100101 Firefox/104.0',
pthreads=False,
shared_memory=False
)>>> sys._emscripten_info
sys._emscripten_info(
emscripten_version=(3, 1, 19),
runtime='Node.js v14.18.2',
pthreads=True,
shared_memory=True
)>>> import os, sys
>>> os.uname()
posix.uname_result(
sysname='wasi',
nodename='(none)',
release='0.0.0',
version='0.0.0',
machine='wasm32'
)
>>> os.name
'posix'
>>> sys.platform
'wasi'Emscripten SDK and WASI SDK define several built-in macros. You can dump a full list of built-ins with emcc -dM -E - < /dev/null and /path/to/wasi-sdk/bin/clang -dM -E - < /dev/null.
#ifdef __EMSCRIPTEN__
// Python on Emscripten
#endifFeature detection flags:
In some cases (e.g. build bots) you may prefer to install build dependencies directly on the system instead of using the container image. Total disk size of SDKs and cached libraries is about 1.6 GB.
# Debian/Ubuntu
apt update
apt install -y git make xz-utils bzip2 curl python3-minimal ccache# Fedora
dnf install -y git make xz bzip2 which ccacheNOTE: Follow the on-screen instructions how to add the SDK to PATH.
git clone https://github.com/emscripten-core/emsdk.git /opt/emsdk
/opt/emsdk/emsdk install latest
/opt/emsdk/emsdk activate latestThe EM_COMPILER_WRAPPER must be set after the EMSDK environment is sourced. Otherwise the source script removes the environment variable.
. /opt/emsdk/emsdk_env.sh EM_COMPILER_WRAPPER=ccache
Emscripten SDK provides static builds of core libraries without PIC (position-independent code). Python builds with dlopen support require PIC. To populate the build cache, run:
. /opt/emsdk/emsdk_env.sh
embuilder build zlib bzip2 MINIMAL_PIC
embuilder build --pic zlib bzip2 MINIMAL_PICNOTE: WASI-SDK's clang may show a warning on Fedora: /lib64/libtinfo.so.6: no version information available, RHBZ#1875587. The warning can be ignored.
export WASI_VERSION=16
export WASI_VERSION_FULL=${WASI_VERSION}.0
curl -sSf -L -O https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_VERSION}/wasi-sdk-${WASI_VERSION_FULL}-linux.tar.gz
mkdir -p /opt/wasi-sdk
tar --strip-components=1 -C /opt/wasi-sdk -xvf wasi-sdk-${WASI_VERSION_FULL}-linux.tar.gz
rm -f wasi-sdk-${WASI_VERSION_FULL}-linux.tar.gzwasmtime 0.38 or newer is required.
curl -sSf -L -o ~/install-wasmtime.sh https://wasmtime.dev/install.sh
chmod +x ~/install-wasmtime.sh
~/install-wasmtime.sh --version v0.38.0
ln -srf -t /usr/local/bin/ ~/.wasmtime/bin/wasmtime| Back | FazBrowse Home | New Git URL |