MotleyCoderDev / wasm2brs

Bringing the power of WebAssembly to the Roku and supporting languages like C/C++/Rust.
https://motley-coder.com/2020/12/20/webassembly-on-roku/
Other
50 stars 5 forks source link

Building wasm2brs

All the dependencies for wasm2brs are installed within a Docker image that can be run with ./run.sh.

To build our repo:

git submodule update --init --recursive
./run.sh make

To run make without the Docker image (not recommended) be sure to install the same dependencies as listed in the Dockerfile.

Running the samples

./run.sh make doom

This will place all the output files in project/. To run, either side load the project manually or use vscode with the BrightScript Language extension. When opening our repository in vscode, running the debugger will run project/.

The samples we have are:

Starting your own project

The easiest way to get started is to look in our samples directory. Specifically the cmake sample is setup to be used as a template.

If you wish to use libc/libc++, then you should use install wasienv, which comes with wasi-libc as well as helpful scripts that run clang/make/cmake/etc with the correct compiler flags and directories.

The mandelbrot sample shows how to use clang directly without wasienv and no standard libraries. Note that wasm-ld is required.

In general the process looks like:

Rust projects

Rust is considerably easier to setup and involves changing the target of the project to wasm32-wasi and compiling with optimization level z:

opt-level = "z"
rustup target add wasm32-wasi
cargo build --target wasm32-wasi

Or

rustc -C opt-level=z --target wasm32-wasi yourfile.rs

As mentioned above, you'll want to run wasm-opt on the output wasm file and finally wasm2brs to convert into a .brs file.

Note: Some Rust libraries depend upon crates that do not have a target built for wasm32-wasi, such as the unix crate. The easiest path is to fork those libraries and remove their dependence upon those crates.

WASM / BrightScript limitations

WASI limitations

API

Function external_append_stdin(bytesOrString as Dynamic) as Void

Hooks

m.external_print_line = custom_print_line:

m.external_output = custom_output:

m.external_wait_for_stdin = custom_wait_for_stdin:

Run tests

Run all the tests, this will auto discover your device with a default password of rokudev.

./run.sh make run_test

To run a specific test you can specify the .wast file as an absolute path, otherwise it assumes it's in the third_part/testsuite/ directory, for example i32.wast:

./run.sh make run_test ARGS="wast i32.wast"

To use a non-default password:

./run.sh make run_test ARGS="password ..."

To deploy to a specific device (e.g. 1.2.3.4):

./run.sh make run_test ARGS="deploy 1.2.3.4"

To provide multiple arguments:

./run.sh make run_test ARGS="password ... deploy 1.2.3.4 wast i32.wast"