WebAssembly / wabt

The WebAssembly Binary Toolkit
Apache License 2.0
6.86k stars 699 forks source link

More docs for building/using libwabt? #1267

Open dubiousjim opened 4 years ago

dubiousjim commented 4 years ago

I wasn't able to find much documentation about libwabt.js, but I was able to piece this together from various sources. Corrections/elaborations are invited.

Usage

Call either parseWat(filename:string, watSource:string, features: object) or readWasm(buffer: Uint8Array, {readDebugNames:true}).

The features object can contain any of the following boolean keys: mutable_globals, exceptions, multi_value, sign_extension, sat_float_to_int, simd, threads, tail_call, bulk_memory, reference_types.

The calls to parseWat and readWasm will return an object wasm that supports the following methods:

Updating/Building

The file demo/libwabt.js in the wabt git repository is periodically updated. It's not clear how to do this manually oneself, to incorporate recent changes to the repo. Issue #536 says that this can be done by running make emscripten-release, which uses a target from the repo's top-level Makefile.

However, I just now tried going into my emsdk folder, updating it following the instructions here (including the source ./emsdk_env.sh command), then cd-ing into my wabt repo and trying make emscripten-release. This fails with:

mkdir -p out/emscripten/Release/
cd out/emscripten/Release/ && cmake -G "Unix Makefiles" /Users/jim/Documents/CLOUD/dev/wasm/wabt/ -DCMAKE_TOOLCHAIN_FILE=/Users/jim/Documents/CLOUD/dev/wasm/emsdk/upstream/emscripten//cmake/Modules/Platform/Emscripten.cmake -DCMAKE_BUILD_TYPE=Release 
CMake Error at /Users/jim/_dev/wasm/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake:100 (message):
  Failed to fetch compiler version information with command
  "'/Users/jim/_dev/wasm/emsdk/upstream/emscripten/emcc' -v"! Process
  returned with error code 1.
Call Stack (most recent call first):
  /opt/local/share/cmake-3.16/Modules/CMakeDetermineSystem.cmake:93 (include)
  CMakeLists.txt:18 (project)

CMake Error: CMake was unable to find a build program corresponding to "Unix Makefiles".  CMAKE_MAKE_PROGRAM is not set.  You probably need to select a different build tool.
-- Configuring incomplete, errors occurred!
make: *** [out/emscripten/Release/Makefile] Error 1
dubiousjim commented 4 years ago

Digging further, I can see that I need to do more work to get my emscripten install working properly. I invite more feedback about the proper usage of libwabt.js or official instructions about how to re-compile it locally based on the most recently pulled sources for wabt.

dubiousjim commented 4 years ago

Should I just use https://github.com/AssemblyScript/wabt.js, rather than trying to compile fresh versions of libwabt.js locally?

dubiousjim commented 4 years ago

I was able to get emscripten working by rolling back to a previous version. (I'm using an older OS X, namely 10.10; emscripten 1.38.33 did work here. Possibly a newer version does as well.)

Doing make emscripten-release now fails at a later point, with:

...
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/jim/_dev/wasm/wabt/out/emscripten/Release
/Applications/Xcode.app/Contents/Developer/usr/bin/make --no-print-directory -C out/emscripten/Release/ all
Scanning dependencies of target wabt
[  2%] Building CXX object CMakeFiles/wabt.dir/src/apply-names.cc.o
In file included from /Users/jim/_dev/wasm/wabt/src/apply-names.cc:17:
In file included from /Users/jim/_dev/wasm/wabt/src/apply-names.h:20:
In file included from /Users/jim/_dev/wasm/wabt/src/common.h:33:
/Users/jim/_dev/wasm/wabt/out/emscripten/Release/config.h:272:2: error: no snprintf
#error no snprintf
 ^
/Users/jim/_dev/wasm/wabt/out/emscripten/Release/config.h:290:2: error: no strcasecmp
#error no strcasecmp
 ^
2 errors generated.
shared:ERROR: '/Users/jim/Documents/CLOUD/dev/wasm/emsdk/fastcomp/fastcomp/bin/clang++ -target asmjs-unknown-emscripten -D__EMSCRIPTEN_major__=1 -D__EMSCRIPTEN_minor__=39 -D__EMSCRIPTEN_tiny__=4 -D_LIBCPP_ABI_VERSION=2 -Werror=implicit-function-declaration -Xclang -nostdsysteminc -Xclang -isystem/Users/jim/Documents/CLOUD/dev/wasm/emsdk/upstream/emscripten/system/include/libcxx -Xclang -isystem/Users/jim/Documents/CLOUD/dev/wasm/emsdk/upstream/emscripten/system/lib/libcxxabi/include -Xclang -isystem/Users/jim/Documents/CLOUD/dev/wasm/emsdk/upstream/emscripten/system/include/compat -Xclang -isystem/Users/jim/Documents/CLOUD/dev/wasm/emsdk/upstream/emscripten/system/include -Xclang -isystem/Users/jim/Documents/CLOUD/dev/wasm/emsdk/upstream/emscripten/system/include/libc -Xclang -isystem/Users/jim/Documents/CLOUD/dev/wasm/emsdk/upstream/emscripten/system/lib/libc/musl/arch/emscripten -Xclang -isystem/Users/jim/Documents/CLOUD/dev/wasm/emsdk/upstream/emscripten/system/local/include -D__STDC_FORMAT_MACROS=1 -D__STDC_LIMIT_MACROS=1 -I/Users/jim/_dev/wasm/wabt -I/Users/jim/_dev/wasm/wabt/out/emscripten/Release -std=c++11 -Wold-style-cast -fno-exceptions -DNDEBUG -O2 -Wall -Wextra -Wno-unused-parameter -Wpointer-arith -gline-tables-only -Wuninitialized -c -DEMSCRIPTEN -mllvm -disable-llvm-optzns /Users/jim/_dev/wasm/wabt/src/apply-names.cc -Xclang -disable-O0-optnone -Xclang -isystem/Users/jim/Documents/CLOUD/dev/wasm/emsdk/upstream/emscripten/system/include/SDL -c -o CMakeFiles/wabt.dir/src/apply-names.cc.o -emit-llvm' failed (1)
make[3]: *** [CMakeFiles/wabt.dir/src/apply-names.cc.o] Error 1
make[2]: *** [CMakeFiles/wabt.dir/all] Error 2
make[1]: *** [all] Error 2
make: *** [emscripten-release] Error 2

I am able to build (the same checkout of) wabt fine using cmake; but that uses my MacPorts version of llvm, rather than the one that emscripten bundles.

Am providing this info in case it's useful; but it looks like the AssemblyScript/wabt.js repo is building libwabt.js nightly automatically, and if that's synched with the latest changes to this repo, I can just use that.

mollthecoder commented 8 months ago

Thanks for documenting the module usage! That just saved me a lot of time.

(Edit: Just realized my previous information was incorrect/obsolete.)

mollthecoder commented 8 months ago

I modified the module to have an export default WasmModule; at the end so it works with ESM. I wrote these TypeScript declarations.

interface wasm {
    destroy(): void;
    resolveNames(): void;
    validate(features: object): void;
    toBinary(
        opts: {log: boolean, write_debug_names: boolean}
    ): {log: string, buffer: Uint8Array};
    generateNames(): void;
    applyNames(): void;
    toText({foldExprs: boolean, inlineExport: boolean}): string;
}
interface Wabt {
    parseWat(filename: string, watSource: string, features: object): wasm;
    readWasm(buffer: Uint8Array, opts: {readDebugNames: true}): wasm;
}
export default function(): Promise<Wabt>;

It's not perfect, but it works for my usage. I was using libwabt.js in a Vanilla TypeScript web app bundled with Vite.