summaryrefslogblamecommitdiff
path: root/README
blob: 0c208f9b331e85348763af1873f9ccf98c5385b0 (plain) (tree)
1
2
3
4
5
6
7
8
9


                 




                                                                          
                                                                             




                                                         


















































































































                                                                                                                                                                

                                                                                

























                                                                                                                                         
                                           









































                                                                                                                                            































                                                                        
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.