Remove support for WASI

Freestanding WebAssembly is enough, and WASI has always been a
pain to support.
This commit is contained in:
Frank Denis
2026-08-26 14:25:41 +02:00
parent e6324db75c
commit ee2972b83e
22 changed files with 230 additions and 232 deletions
+1 -33
View File
@@ -77,7 +77,7 @@ jobs:
zig build -Dtarget=aarch64-macos
zig build -Dtarget=x86_64-freebsd
zig build -Dtarget=aarch64-freebsd
zig build -Dtarget=wasm32-wasi
zig build -Dtarget=wasm32-freestanding
zig build -Doptimize=ReleaseFast
rm -fr zig-cache zig-out
@@ -191,38 +191,6 @@ jobs:
make -j $(nproc)
make clean > /dev/null
wasi:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
persist-credentials: false
- name: Install Zig
uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2
with:
version: master
- name: Install Wasmer
uses: wasmerio/setup-wasmer@24b15c95293d23f89c68bd40dac76338f773e924 # v3.1
- name: Build for wasi-core
run: zig build -Dtarget=wasm32-wasi -Doptimize=ReleaseSafe
- name: Run tests with Wasmer
run: |
cd zig-out/bin
failed=0
for wasm in *.wasm; do
name="${wasm%.wasm}"
echo "[$name]"
if ! wasmer run --volume="$(pwd):/" "$wasm" 2>&1; then
echo "*** [$name] FAILED" >&2
failed=1
fi
done
exit $failed
aarch64-gcc:
runs-on: ubuntu-24.04-arm
steps:
-1
View File
@@ -61,7 +61,6 @@ libsodium-nativeclient
libsodium-nativeclient-*
libsodium-osx
libsodium-uninstalled.pc
libsodium-wasm32-wasi
libsodium-win32
libsodium-win64
libsodium.pc
+23 -22
View File
@@ -10,6 +10,8 @@ const is_zig_16 = @hasDecl(std, "Io") and @hasDecl(std.Io, "Dir");
const Dir = if (is_zig_16) std.Io.Dir else std.fs.Dir;
const Io = if (is_zig_16) std.Io else void;
const wasm_libc_path = "builds/wasm32-freestanding";
fn initLibConfig(b: *std.Build, target: std.Build.ResolvedTarget, lib: *Compile) void {
lib.root_module.link_libc = true;
lib.lto = null;
@@ -91,16 +93,11 @@ fn initLibConfig(b: *std.Build, target: std.Build.ResolvedTarget, lib: *Compile)
lib.root_module.addCMacro("HAVE_SYS_RANDOM_H", "1");
lib.root_module.addCMacro("HAVE_WEAK_SYMBOLS", "1");
},
.wasi => {
lib.root_module.addCMacro("HAVE_ARC4RANDOM", "1");
lib.root_module.addCMacro("HAVE_ARC4RANDOM_BUF", "1");
lib.root_module.addCMacro("HAVE_CLOCK_GETTIME", "1");
lib.root_module.addCMacro("HAVE_GETENTROPY", "1");
lib.root_module.addCMacro("HAVE_NANOSLEEP", "1");
lib.root_module.addCMacro("HAVE_POSIX_MEMALIGN", "1");
lib.root_module.addCMacro("HAVE_SYS_AUXV_H", "1");
lib.root_module.addCMacro("HAVE_SYS_PARAM_H", "1");
lib.root_module.addCMacro("HAVE_SYS_RANDOM_H", "1");
.freestanding => {
if (target.result.cpu.arch.isWasm()) {
lib.root_module.link_libc = false;
lib.root_module.addSystemIncludePath(b.path(wasm_libc_path ++ "/include"));
}
},
.freebsd => {
lib.root_module.addCMacro("ASM_HIDE_SYMBOL", ".hidden");
@@ -159,13 +156,6 @@ fn initLibConfig(b: *std.Build, target: std.Build.ResolvedTarget, lib: *Compile)
},
else => {},
}
switch (target.result.os.tag) {
.wasi => {
lib.root_module.addCMacro("__wasi__", "1");
},
else => {},
}
}
pub fn build(b: *std.Build) !void {
@@ -190,15 +180,22 @@ pub fn build(b: *std.Build) !void {
const enable_benchmarks = b.option(bool, "enable_benchmarks", "Whether tests should be benchmarks.") orelse false;
const benchmarks_iterations = b.option(u32, "iterations", "Number of iterations for benchmarks.") orelse 200;
const wasm_max_memory = b.option(u64, "wasm_max_memory", "Maximum WebAssembly linear memory size in bytes.") orelse null;
var build_static = b.option(bool, "static", "Build libsodium as a static library.") orelse true;
var build_shared = b.option(bool, "shared", "Build libsodium as a shared library.") orelse true;
const build_tests = b.option(bool, "test", "Build the tests (implies -Dstatic=true)") orelse true;
var build_tests = b.option(bool, "test", "Build the tests (implies -Dstatic=true)") orelse true;
const wasm_freestanding =
target.result.cpu.arch.isWasm() and target.result.os.tag == .freestanding;
if (target.result.cpu.arch.isWasm()) {
build_shared = false;
}
// The test programs need a hosted environment: standard input and output,
// and files to read the expected results from.
if (wasm_freestanding) {
build_tests = false;
}
if (build_tests) {
build_static = true;
}
@@ -267,6 +264,13 @@ pub fn build(b: *std.Build) !void {
"-Werror=vla",
};
if (wasm_freestanding) {
lib.root_module.addCSourceFiles(.{
.files = &.{wasm_libc_path ++ "/libc.c"},
.flags = flags,
});
}
const allocator = heap.page_allocator;
var walker = try src_dir.walk(allocator);
@@ -340,9 +344,6 @@ pub fn build(b: *std.Build) !void {
.link_libc = true,
}),
});
if (target.result.cpu.arch.isWasm()) {
exe.max_memory = wasm_max_memory;
}
exe.root_module.linkLibrary(static_lib);
exe.root_module.addIncludePath(b.path("src/libsodium/include"));
exe.root_module.addIncludePath(b.path("test/quirks"));
+12 -1
View File
@@ -85,4 +85,15 @@ EXTRA_DIST = \
msvc/vs2026/libsodium/libsodium.xml \
msvc/vs2026/libsodium.import.props \
msvc/vs2026/libsodium.import.xml \
msvc/vs2026/libsodium.sln
msvc/vs2026/libsodium.sln \
wasm32-freestanding/libc.c \
wasm32-freestanding/include/assert.h \
wasm32-freestanding/include/errno.h \
wasm32-freestanding/include/fcntl.h \
wasm32-freestanding/include/stdlib.h \
wasm32-freestanding/include/string.h \
wasm32-freestanding/include/time.h \
wasm32-freestanding/include/unistd.h \
wasm32-freestanding/include/sys/stat.h \
wasm32-freestanding/include/sys/time.h \
wasm32-freestanding/include/sys/types.h
@@ -0,0 +1,7 @@
#undef assert
#ifdef NDEBUG
#define assert(cond) ((void)0)
#else
#define assert(cond) ((cond) ? (void)0 : __builtin_trap())
#endif
@@ -0,0 +1,17 @@
#ifndef _ERRNO_H
#define _ERRNO_H
extern int errno;
#define EPERM 1
#define EINTR 4
#define EIO 5
#define ENXIO 6
#define EAGAIN 11
#define ENOMEM 12
#define EINVAL 22
#define EFBIG 27
#define ERANGE 34
#define ENOSYS 38
#endif
@@ -0,0 +1,3 @@
#ifndef _FCNTL_H
#define _FCNTL_H
#endif
@@ -0,0 +1,17 @@
#ifndef _STDLIB_H
#define _STDLIB_H
#include <stddef.h>
#include <stdint.h>
/* arc4random_buf, malloc and free come from the embedder. */
_Noreturn void abort(void);
uint32_t arc4random(void);
void arc4random_buf(void *buf, size_t size);
void *calloc(size_t nmemb, size_t size);
void free(void *ptr);
void *malloc(size_t size);
#endif
@@ -0,0 +1,16 @@
#ifndef _STRING_H
#define _STRING_H
#include <stddef.h>
void *memchr(const void *s, int c, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
void *memcpy(void *dest, const void *src, size_t n);
void *memmove(void *dest, const void *src, size_t n);
void *memset(void *s, int c, size_t n);
char *strchr(const char *s, int c);
size_t strlen(const char *s);
int strncmp(const char *s1, const char *s2, size_t n);
char *strrchr(const char *s, int c);
#endif
@@ -0,0 +1,3 @@
#ifndef _SYS_STAT_H
#define _SYS_STAT_H
#endif
@@ -0,0 +1,11 @@
#ifndef _SYS_TIME_H
#define _SYS_TIME_H
struct timeval {
long long tv_sec;
long tv_usec;
};
int gettimeofday(struct timeval *tv, void *tz);
#endif
@@ -0,0 +1,8 @@
#ifndef _SYS_TYPES_H
#define _SYS_TYPES_H
#include <stddef.h>
typedef ptrdiff_t ssize_t;
#endif
@@ -0,0 +1,3 @@
#ifndef _TIME_H
#define _TIME_H
#endif
@@ -0,0 +1,3 @@
#ifndef _UNISTD_H
#define _UNISTD_H
#endif
+94
View File
@@ -0,0 +1,94 @@
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
int errno;
void *calloc(size_t nmemb, size_t size) {
void *ptr;
if (nmemb > (size_t)0U && size > SIZE_MAX / nmemb) {
return NULL;
}
if ((ptr = malloc(nmemb * size)) != NULL) {
memset(ptr, 0, nmemb * size);
}
return ptr;
}
_Noreturn void abort(void) {
__builtin_trap();
}
uint32_t arc4random(void) {
uint32_t r;
arc4random_buf(&r, sizeof r);
return r;
}
void *memchr(const void *s, int c, size_t n) {
const unsigned char *p = (const unsigned char *)s;
while (n-- > (size_t)0U) {
if (*p == (unsigned char) c) {
return (void *) (uintptr_t) p;
}
p++;
}
return NULL;
}
size_t strlen(const char *s) {
const char *p = s;
while (*p != 0) {
p++;
}
return (size_t)(p - s);
}
int strncmp(const char *s1, const char *s2, size_t n) {
while (n-- > (size_t) 0U) {
if (*s1 != *s2) {
return (int) (unsigned char) *s1 - (int) (unsigned char) *s2;
}
if (*s1 == 0) {
break;
}
s1++;
s2++;
}
return 0;
}
char *strchr(const char *s, int c) {
for (;;) {
if (*s == (char) c) {
return (char *) (uintptr_t) s;
}
if (*s == 0) {
return NULL;
}
s++;
}
}
char *strrchr(const char *s, int c) {
const char *found = NULL;
for (;;) {
if (*s == (char) c) {
found = s;
}
if (*s == 0) {
break;
}
s++;
}
return (char *) (uintptr_t) found;
}
+6 -15
View File
@@ -237,8 +237,6 @@ dnl Checks
AC_C_VARARRAYS
AC_CHECK_DEFINE([__wasi__], [WASI="yes"], [])
AS_CASE([$host_os], [linux-gnu], [AX_ADD_FORTIFY_SOURCE], [ ])
AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],
@@ -932,11 +930,9 @@ dnl Checks for functions and headers
AC_FUNC_ALLOCA
AS_IF([test "x$EMSCRIPTEN" = "x"],[
AC_CHECK_FUNCS([arc4random arc4random_buf])
AS_IF([test "x$WASI" = "x"],[
AC_CHECK_FUNCS([mmap mlock madvise mprotect])
AC_CHECK_FUNCS([raise])
AC_CHECK_FUNCS([sysconf])
])
AC_CHECK_FUNCS([mmap mlock madvise mprotect])
AC_CHECK_FUNCS([raise])
AC_CHECK_FUNCS([sysconf])
AC_MSG_CHECKING(for getrandom with a standard API)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
#include <stdlib.h>
@@ -974,16 +970,12 @@ if (&getentropy != NULL) {
])
])
AS_IF([test "x$WASI" = "x"],[
AC_CHECK_FUNCS([getpid])
AC_CHECK_FUNCS([getauxval elf_aux_info])
])
AC_CHECK_FUNCS([getpid])
AC_CHECK_FUNCS([getauxval elf_aux_info])
AC_CHECK_FUNCS([posix_memalign nanosleep clock_gettime])
AS_IF([test "x$WASI" = "x"],[
AC_CHECK_FUNCS([memset_s explicit_bzero memset_explicit explicit_memset])
])
AC_CHECK_FUNCS([memset_s explicit_bzero memset_explicit explicit_memset])
AC_SUBST([LIBTOOL_EXTRA_FLAGS])
@@ -994,7 +986,6 @@ AS_IF([test "x$EMSCRIPTEN" != "x"],[
])
AC_SUBST(TEST_LDFLAGS)
AM_CONDITIONAL([EMSCRIPTEN], [test "x$EMSCRIPTEN" != "x"])
AM_CONDITIONAL([WASI], [test "x$WASI" != "x"])
AC_DEFINE([CONFIGURED], [1], [the build system was properly configured])
+1 -2
View File
@@ -10,5 +10,4 @@ EXTRA_DIST = \
apple-xcframework.sh \
macos.sh \
msys2-win32.sh \
msys2-win64.sh \
wasm32-wasi.sh
msys2-win64.sh
-45
View File
@@ -1,45 +0,0 @@
#! /bin/sh
export PATH="/opt/zig/bin:/opt/zig:/opt/homebrew/bin:$PATH"
export PREFIX="$(pwd)/libsodium-wasm32-wasi"
mkdir -p $PREFIX || exit 1
export CC="zig cc"
export CFLAGS="--target=wasm32-wasi -O3"
export LDFLAGS="-s"
export AR="zig ar"
export RANLIB="zig ranlib"
make distclean >/dev/null
if [ "x$1" = "x--bench" ]; then
export BENCHMARKS=1
export CPPFLAGS="-DBENCHMARKS -DITERATIONS=200"
else
export CPPFLAGS="-DED25519_NONDETERMINISTIC=1"
fi
if [ -n "$LIBSODIUM_MINIMAL_BUILD" ]; then
export LIBSODIUM_ENABLE_MINIMAL_FLAG="--enable-minimal"
else
export LIBSODIUM_ENABLE_MINIMAL_FLAG=""
fi
if ! ./configure ${LIBSODIUM_ENABLE_MINIMAL_FLAG} \
--prefix="$PREFIX" \
--host=wasm32-wasi \
--disable-pie --disable-ssp --disable-shared --without-pthreads; then
cat config.log
exit 1
fi
NPROCESSORS=$(getconf NPROCESSORS_ONLN 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null)
PROCESSORS=${NPROCESSORS:-3}
if [ -z "$BENCHMARKS" ]; then
make -j${PROCESSORS} check && make install && make distclean >/dev/null
else
make -j${PROCESSORS} && make check
fi
@@ -78,7 +78,8 @@ BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
#define INTERNAL_RANDOM_BLOCK_SIZE crypto_core_hchacha20_OUTPUTBYTES
#if defined(__OpenBSD__) || defined(__CloudABI__) || defined(__wasi__)
#if defined(__OpenBSD__) || defined(__CloudABI__) || \
(defined(__wasm__) && !defined(__EMSCRIPTEN__))
# define HAVE_SAFE_ARC4RANDOM 1
#endif
#if defined(__CloudABI__) || defined(__wasm__)
@@ -525,7 +526,7 @@ randombytes_internal_random_close(void)
if (global.getrandom_available != 0) {
ret = 0;
}
# elif !defined(NONEXISTENT_DEV_RANDOM) && defined(HAVE_SAFE_ARC4RANDOM)
# elif defined(HAVE_SAFE_ARC4RANDOM)
ret = 0;
# else
if (global.random_data_source_fd != -1 &&
@@ -77,7 +77,8 @@ BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
# pragma comment(lib, "advapi32.lib")
#endif
#if defined(__OpenBSD__) || defined(__CloudABI__) || defined(__wasi__)
#if defined(__OpenBSD__) || defined(__CloudABI__) || \
(defined(__wasm__) && !defined(__EMSCRIPTEN__))
# define HAVE_SAFE_ARC4RANDOM 1
#endif
-5
View File
@@ -2,7 +2,6 @@
EXTRA_DIST = \
run.sh \
cmptest.h \
wasi-test-wrapper.sh \
wintest.bat \
pre.js.inc \
aead_aegis128l.exp \
@@ -660,10 +659,6 @@ TESTS_TARGETS += \
xchacha20
endif
if WASI
LOG_COMPILER = ./wasi-test-wrapper.sh
endif
verify: check
@VALGRIND_CHECK_RULES@
-105
View File
@@ -1,105 +0,0 @@
#! /bin/sh
unset LDFLAGS
unset CFLAGS
if command -v wasm-opt >/dev/null; then
wasm-opt -O4 --enable-sign-ext --emit-target-features $WASMOPT_FLAGS \
-o "${1}.tmp" "$1" && mv -f "${1}.tmp" "$1"
fi
if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "wasmedge" ]; then
if command -v wasmedgec >/dev/null && command -v wasmedge >/dev/null; then
wasmedgec "$1" "${1}.so" >/dev/null &&
wasmedge --dir=.:. "${1}.so" &&
rm -f "${1}.so" &&
exit 0
fi
fi
if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "wasmer" ]; then
if command -v wasmer >/dev/null; then
wasmer run "--${WASMER_BACKEND:-cranelift}" --volume="$(pwd):/" "$1" && exit 0
fi
fi
if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "wasmtime" ]; then
if command -v wasmtime >/dev/null; then
wasmtime run --dir=. "$1" && exit 0
fi
fi
if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "bun" ]; then
if echo | bun help >/dev/null 2>&1; then
{
echo "import fs from 'fs'; import { init, WASI } from '@wasmer/wasi';"
echo "await init();"
echo "const wasi = new WASI({args: process.argv, env: process.env, preopens: {'.':'/'}});"
echo "await (async function() {"
echo " const wasm = await WebAssembly.compile(fs.readFileSync('${1}'));"
echo " await wasi.instantiate(wasm, {});"
echo " wasi.start();"
echo " console.log(wasi.getStdoutString());"
echo "})().catch(e => { console.error(e); process.exit(1); });"
} >"${1}.mjs"
bun run "${1}.mjs" 2>/tmp/err &&
rm -f "${1}.mjs" && exit 0
fi
fi
if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "node" ]; then
if echo | node --experimental-wasi-unstable-preview1 >/dev/null 2>&1; then
{
echo "import fs from 'fs'; import { WASI } from 'wasi';"
echo "const wasi = new WASI({args: process.argv, env: process.env, preopens: {'.':'.'}});"
echo "const importObject = { wasi_snapshot_preview1: wasi.wasiImport };"
echo "await (async function() {"
echo " const wasm = await WebAssembly.compile(fs.readFileSync('${1}'));"
echo " const instance = await WebAssembly.instantiate(wasm, importObject);"
echo " wasi.start(instance);"
echo "})().catch(e => { console.error(e); process.exit(1); });"
} >"${1}.mjs"
node --experimental-wasi-unstable-preview1 "${1}.mjs" 2>/tmp/err &&
rm -f "${1}.mjs" && exit 0
fi
fi
if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "wasm3" ]; then
if command -v wasm3 >/dev/null; then
wasm3 "$1" && exit 0
fi
fi
if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "iwasm" ]; then
if command -v iwasm >/dev/null; then
if iwasm | grep -qi wasi >/dev/null 2>&1; then
if wamrc --version; then
wamrc -o "${1}.o" "$1" >/dev/null &&
iwasm --dir=. "${1}.o" && exit 0
else
iwasm --dir=. "$1" && exit 0
fi
fi
fi
fi
if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "wazero" ]; then
if command -v wazero >/dev/null; then
wazero run -mount .:/ "$1" && exit 0
fi
fi
if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "zwasm" ]; then
if command -v zwasm >/dev/null; then
zwasm run --dir "$(pwd)::/" --allow-read --allow-write --allow-path "$1" && exit 0
fi
fi
if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "wasmer-js" ]; then
if command -v wasmer-js >/dev/null; then
wasmer-js run "$1" --dir=. && exit 0
fi
fi
echo "WebAssembly runtime failed" >&2
exit 1