Project Blackbird ================= Whatever this was before, it's currently really about creating WebAssembly Components in C using the wasi-http interface. See the stuff under: c/wasi-http/0.2.0/ They can be run under NGINX Unit with the wasm-wasi-component language module or under wasmtime (v24 works), e.g. $ wasmtime serve -Scli -Sinherit-env ./component.wasm Getting Started =============== First you'll need some tools. Firstly clang/llvm Fedora ------ # dnf install make clang llvm compiler-rt lld wasi-libc-devel wasi-libc-static Debian ------ # apt install make clang llvm lld You will also need to grab the wasi-sysroot, this is essentially a C library targeting WebAssembly (it is based partly on cloudlibc and musl libc) and is required for building server side WebAssembly modules. It's up to you where you put this. $ wget -O- https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-24/wasi-sysroot-24.0.tar.gz | tar -xzf - Note: Debian does provide a wasi-libc package, but the way it's packaged makes it unusable in this instance as --sysroot expects the include and lib directories to both be there (whereas in the Debian package they are in different locations). libclang_rt.builtins-wasm32.a ----------------------------- For either of the above you will also need the libclang wasm32-wasi runtime library, this can be done with # wget -O- https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-24/libclang_rt.builtins-wasm32-wasi-24.0.tar.gz | tar --strip-components=1 -xvzf - -C $(dirname $(clang -print-runtime-dir)) That will install the following, path may vary slightly /usr/lib/clang/18/lib/wasi/libclang_rt.builtins-wasm32.a **NOTE:** If you get a major clang version update, you may need to repeat that last task. wit-bindgen & wasm-tools ------------------------ Finally you need a couple of rust based tools. You can grab the latest versions for your platform here https://github.com/bytecodealliance/wit-bindgen/releases https://github.com/bytecodealliance/wasm-tools/releases Again, where you put these is up to you. You will need to tell make where to find these tools, you can either set the WIT_BINDGEN & WASM_TOOLS environment variables in your shell or pass these directly to make, e.g. $ make WIT_BINDGEN=/path/to/wit-bindgen WASM_TOOLS=/path/to/wasm-tools Now you are ready to try building some components! (from the project_blackbird repository root) $ cd c/wasi-http/0.2.0/echo-request $ make # or the above make command depending on how you set the above vars or for Debian you will need to specify the WASI_SYSROOT $ make WASI_SYSROOT=/path/to/wasi-sysroot If it works you should be left with (amongst others) a component.wasm file, you can test that out by using the wasmtime-serve command You can grab wasmtime from https://github.com/bytecodealliance/wasmtime/releases/download/v24.0.0/wasmtime-v24.0.0-x86_64-linux.tar.xz or pick a different version for your platform, don't take the c-api package by mistake. Untar that someplace then you can do $ /path/to/wasmtime serve ./component.wasm Then try $ curl localhost:8080 *** Welcome to WebAssembly with wasi-http / C *** [Request Info] REQUEST_PATH = / METHOD = GET QUERY = [Request Headers] accept = */* user-agent = curl/8.6.0 For the other components using the reactor adaptor you will want to use $ /path/to/wasmtime serve -Scli ./component.wasm For env-var you will want $ /path/to/wasmtime serve -Scli -Sinherit-env ./component.wasm You can of course use that last command for them all. ================================================================================ Make Fermyon Spin WebAssembly Modules run on NGINX Unit. The repository will contain some exploratory tools. Quickstart ========== Clone the spin repository $ git clone https://github.com/fermyon/spin.git Build the wasm module. $ cd spin/examples/wasi-http-rust $ cargo build --target wasm32-wasi Grab the Wasmtime C API $ wget -O- https://github.com/bytecodealliance/wasmtime/releases/download/v13.0.0/wasmtime-v13.0.0-x86_64-linux-c-api.tar.xz | tar -xvf - Clone this repository $ git clone git://git.digital-domain.net/project_blackbird.git Build it $ cd project_blackbird/c/wasmtime-wasi-http $ make WASMTIME_C_API=/path/to/wasmtime-c-api WASM_MODULE=/path/to/spin/examples/wasi-http-rust/target/wasm32-wasi/debug/wasi_http_rust.wasm Run it $ ./wasmtime-wasi-http Initializing... Loading binary... Compiling module... Setting function imports... [poll2::poll-oneoff] [streams2::read] [streams2::blocking-read] [streams2::subscribe-to-input-stream] [streams2::write] [streams2::blocking-write] [streams2::subscribe-to-output-stream] [default-outgoing-HTTP2::handle] [types2::new-fields] [types2::fields-entries] [types2::finish-incoming-stream] [types2::finish-outgoing-stream] [types2::incoming-request-method] [types2::incoming-request-path-with-query] [types2::incoming-request-headers] [types2::incoming-request-consume] [types2::new-outgoing-request] [types2::outgoing-request-write] [types2::set-response-outparam] [types2::incoming-response-status] [types2::incoming-response-headers] [types2::incoming-response-consume] [types2::new-outgoing-response] [types2::outgoing-response-write] [types2::future-incoming-response-get] [types2::listen-to-future-incoming-response] Initialising WASI... Instantiating module... Getting function exports... [HTTP#handle] [cabi_realloc] Shutting down... Done. Component Model =============== You can play with the component model under rust/hello_world This requires some new tools - https://github.com/bytecodealliance/wit-bindgen - https://github.com/bytecodealliance/wasm-tools You can use the pre-built packages, once downloaded and untar'd, edit rust/hello_world/component/Makefile and adjust the paths for the above tools. To build the component with make you may need to specify where the WASI sysroot is $ make WASI_SYSROOT=/path/to/wasi-sysroot You can then build the Rust runtime under rust/hello_world with $ cargo build after a while (sheesh) it should finish... then you can run it with $ target/debug/hello_world it won't actually print anything, but also shouldn't give an error.