summaryrefslogtreecommitdiff
path: root/README
blob: 57a42907a0cf6b177ecbffebd8d7fa9b4cabc29a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
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

# mkdir $(dirname $(clang -print-runtime-dir))/wasi && 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.