Skip to content

Exprimental WASI support for ports/unix #13676

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 27 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
2b45ae2
ports/unix/Makefile: Don't assume Linux by default.
yamt Feb 13, 2024
194e015
ports/unix/unix_mphal.c: Disable signal mask stuff for WASI.
yamt Feb 13, 2024
d26e552
ports/unix: Add build-wasi.sh script.
yamt Feb 15, 2024
3ff3f3d
ports/unix: Add wasi VARIANT.
yamt Feb 16, 2024
355f987
ports/unix: Make MICROPY_PY_SELECT_POSIX_OPTIMISATIONS overridable.
yamt Feb 16, 2024
6f0f91d
ports/unix: Make MICROPY_PY_OS_SYSTEM overridable.
yamt Feb 16, 2024
9822893
ports/unix/variants/wasi: Disable MICROPY_PY_SELECT_POSIX_OPTIMISATIONS.
yamt Feb 16, 2024
cb11272
ports/unix/variants/wasi: Disable MICROPY_PY_OS_SYSTEM.
yamt Feb 16, 2024
f50795d
ports/unix/variants/wasi: Disable MICROPY_PY_SYS_EXECUTABLE.
yamt Feb 16, 2024
7a88583
ports/unix: Make MICROPY_PY_SYS_EXECUTABLE overridable.
yamt Feb 16, 2024
7374363
ports/unix/variants/wasi/mpconfigvariant.mk: Disable several things.
yamt Feb 16, 2024
ab17034
ports/unix/build-wasi.sh: Switch to use VARIANT.
yamt Feb 16, 2024
70bf523
ports/unix/variants/wasi/mpconfigvariant.mk: Update a comment.
yamt Feb 16, 2024
9b549c3
ports/unix/build-wasi.sh: Update toolchain patches.
yamt Apr 2, 2024
e2274d7
ports/unix/build-wasi.sh: Update WASI-SDK.
yamt May 2, 2024
8509cba
ports/unix/build-wasi.sh: Use wasi-libc from wasi-sdk.
yamt May 2, 2024
7a7f6ec
ports/unix/build-wasi.sh: Update a wasm-opt option.
yamt Jun 10, 2024
5ab604d
ports/unix/build-wasi.sh: Fix comment grammer.
yamt Jul 5, 2024
437a392
ports/unix/build-wasi.sh: Rename the neweh binary.
yamt Jul 5, 2024
7015fc5
ports/unix/build-wasi.sh: Use wasi-sdk version of linker.
yamt Jul 29, 2024
9df64d0
ports/unix/build-wasi.sh: Specify the target explicitly.
yamt Jul 29, 2024
5f409b2
ports/unix/build-wasi.sh: Add a comment.
yamt Jul 29, 2024
9e05cf3
ports/unix: Make MICROPY_PY_WEBSOCKET overridable.
yamt Oct 24, 2024
fad3b13
ports/unix: Disable MICROPY_PY_WEBSOCKET.
yamt Oct 24, 2024
a984524
ports/unix/build-wasi.sh: Simplify requirements.
yamt Dec 12, 2024
8e3e536
ports/unix/build-wasi.sh: Use "set -e".
yamt Dec 12, 2024
5098523
ports/unix/build-wasi.sh: Print a bit friendly message.
yamt Dec 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ports/unix/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ CC = clang
endif
# Use clang syntax for map file
LDFLAGS_ARCH = -Wl,-map,$@.map -Wl,-dead_strip
else
else ifeq ($(UNAME_S),Linux)
# Use gcc syntax for map file
LDFLAGS_ARCH = -Wl,-Map=$@.map,--cref -Wl,--gc-sections
endif
Expand Down
55 changes: 55 additions & 0 deletions ports/unix/build-wasi.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#! /bin/sh

# prerequisites
#
# WASI_SDK: wasi-sdk 25.0 or later
# WASM_OPT: binaryen wasm-opt version_117 or later

# Note:
# we specify the target "--target=wasm32-wasi" explicitly below for the case
# where $CLANG is built with a configuration different from wasi-sdk.
# ditto for "-B ${WASI_SDK}/bin/".

set -e

WASI_SDK=${WASI_SDK:-/opt/wasi-sdk-25.0}
WASI_SYSROOT=${WASI_SYSROOT:-${WASI_SDK}/share/wasi-sysroot}
WASM_OPT=${WASM_OPT:-wasm-opt}
RESOURCE_DIR=$(${WASI_SDK}/bin/clang --print-resource-dir)
LLVM_DIR=${LLVM_DIR:-${WASI_SDK}}
CLANG=${CLANG:-${LLVM_DIR}/bin/clang}
CC="${CLANG} --sysroot ${WASI_SYSROOT} -resource-dir ${RESOURCE_DIR}"

CFLAGS="--target=wasm32-wasi -D_WASI_EMULATED_PROCESS_CLOCKS -D_WASI_EMULATED_SIGNAL -D_WASI_EMULATED_MMAN -mllvm -wasm-enable-sjlj" \
LDFLAGS="--target=wasm32-wasi -lwasi-emulated-process-clocks -lwasi-emulated-signal -lwasi-emulated-mman -lsetjmp -B ${WASI_SDK}/bin/" \
make \
CC="${CC}" \
STRIP="${WASI_SDK}/bin/strip" \
SIZE="${WASI_SDK}/bin/size" \
UNAME_S=wasi \
VARIANT=wasi \
"$@"

PROG=build-wasi/micropython

# Unlike emscripten, WASI doesn't provide a way to scan GC roots
# like WASM locals. Hopefully --spill-pointers can workaround it.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you try this with e.g. long-running scripts?

${WASM_OPT} \
--spill-pointers \
-o ${PROG}.spilled ${PROG}

# LLVM still uses the older version of EH proposal. ("phase 3")
# Convert to the latest version of EH proposal with exnref.
${WASM_OPT} \
--translate-to-exnref --enable-exception-handling \
-o ${PROG}.spilled.exnref ${PROG}.spilled

cat <<EOF
Built successfully.

Now you can run it with EH-enabled runtimes.
eg. (using the latest EH)
toywasm --wasi build-wasi/micropython.spilled.exnref
eg. (using the old EH)
iwasm build-wasi/micropython.spilled
EOF
2 changes: 2 additions & 0 deletions ports/unix/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,9 @@ typedef long mp_off_t;
#define MICROPY_PY_SYS_PATH_ARGV_DEFAULTS (0)

// Enable sys.executable.
#ifndef MICROPY_PY_SYS_EXECUTABLE
#define MICROPY_PY_SYS_EXECUTABLE (1)
#endif

#define MICROPY_PY_SOCKET_LISTEN_BACKLOG_DEFAULT (SOMAXCONN < 128 ? SOMAXCONN : 128)

Expand Down
12 changes: 9 additions & 3 deletions ports/unix/unix_mphal.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,13 @@
#endif
#endif

#ifndef _WIN32
#if defined(_WIN32) || defined(__wasi__)
#define HAS_SIGNAL 0
#else
#define HAS_SIGNAL 1
#endif

#if HAS_SIGNAL != 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just #if HAS_SIGNAL is good enough?

#include <signal.h>

static void sighandler(int signum) {
Expand Down Expand Up @@ -75,7 +81,7 @@ static void sighandler(int signum) {
void mp_hal_set_interrupt_char(char c) {
// configure terminal settings to (not) let ctrl-C through
if (c == CHAR_CTRL_C) {
#ifndef _WIN32
#if HAS_SIGNAL != 0
// enable signal handler
struct sigaction sa;
sa.sa_flags = 0;
Expand All @@ -84,7 +90,7 @@ void mp_hal_set_interrupt_char(char c) {
sigaction(SIGINT, &sa, NULL);
#endif
} else {
#ifndef _WIN32
#if HAS_SIGNAL != 0
// disable signal handler
struct sigaction sa;
sa.sa_flags = 0;
Expand Down
6 changes: 6 additions & 0 deletions ports/unix/variants/mpconfigvariant_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@
#define MICROPY_PY_OS_INCLUDEFILE "ports/unix/modos.c"
#define MICROPY_PY_OS_ERRNO (1)
#define MICROPY_PY_OS_GETENV_PUTENV_UNSETENV (1)
#ifndef MICROPY_PY_OS_SYSTEM
#define MICROPY_PY_OS_SYSTEM (1)
#endif
#define MICROPY_PY_OS_URANDOM (1)

// Enable the unix-specific "time" module.
Expand All @@ -111,11 +113,15 @@
#endif

// The "select" module is enabled by default, but disable select.select().
#ifndef MICROPY_PY_SELECT_POSIX_OPTIMISATIONS
#define MICROPY_PY_SELECT_POSIX_OPTIMISATIONS (1)
#endif
#define MICROPY_PY_SELECT_SELECT (0)

// Enable the "websocket" module.
#ifndef MICROPY_PY_WEBSOCKET
#define MICROPY_PY_WEBSOCKET (1)
#endif

// Enable the "machine" module, mostly for machine.mem*.
#define MICROPY_PY_MACHINE (1)
Expand Down
3 changes: 3 additions & 0 deletions ports/unix/variants/wasi/manifest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# include("$(PORT_DIR)/variants/manifest.py")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this file only has comments can it just be omitted?


# include("$(MPY_DIR)/extmod/asyncio")
40 changes: 40 additions & 0 deletions ports/unix/variants/wasi/mpconfigvariant.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2019 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

// Set base feature level.
#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES)

// WASI has different values for POLL constants.
#define MICROPY_PY_SELECT_POSIX_OPTIMISATIONS (0)

// WASI doesn't have executable or process.
#define MICROPY_PY_OS_SYSTEM (0)
#define MICROPY_PY_SYS_EXECUTABLE (0)

#define MICROPY_PY_WEBSOCKET (0)

// Enable extra Unix features.
#include "../mpconfigvariant_common.h"
28 changes: 28 additions & 0 deletions ports/unix/variants/wasi/mpconfigvariant.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Build for WASI
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Imo not needed to state the obvious.,


FROZEN_MANIFEST ?= $(VARIANT_DIR)/manifest.py

# WASI doesn't have FFI
MICROPY_PY_FFI=0
Copy link
Contributor

@stinos stinos Apr 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should have whitespace around the =, likewise in rest of file


# When threading is enabled, micropython GC uses signals, which is
# not available on WASI.
MICROPY_PY_THREAD=0

# Disable for now because network support is limited in WASI.
MICROPY_PY_SOCKET=0
MICROPY_PY_SSL=0

# ../../lib/berkeley-db-1.xx/PORT/include/db.h:40:10:
# fatal error: 'sys/cdefs.h' file not found
MICROPY_PY_BTREE=0

# WASI doesn't have termios
MICROPY_PY_TERMIOS=0
MICROPY_USE_READLINE=0

# The following things might just work as they are.
# Disabled for now because I'm not interested in them.
MICROPY_VFS_FAT=0
MICROPY_VFS_LFS1=0
MICROPY_VFS_LFS2=0
Loading