Rustの出力したwasmを動かす
2020/4/18
Rust WASM
Rust WASM
概要
Rustの出力したwasmを動かす。
準備
Rustのインストール (インストール済みであれば不要)
curl https://sh.rustup.rs -sSf | sh
rustup update
手順1
# WebAssemblyへのコンパイル機能を有効化
rustup target add wasm32-unknown-unknown
mkdir rust_wasm
cd rust_wasm
# 新しいプロジェクト wasam-test を作成する
cargo new --lib wasm-test
nano Cargo.toml
# Cargo.tomlを編集して以下を追加する:
[lib]
crate-type = ["cdylib"]
続き
nano src/lib.rs
# src/lib.rs を編集して以下の内容にする:
src/lib.rs
#[no_mangle]
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
続き:
# 以下を実行してビルドする
cargo build --target=wasm32-unknown-unknown --release
# 以下を実行して wasm ができていることを確認する
ls target/wasm32-unknown-unknown/release/*.wasm
target/wasm32-unknown-unknown/release/wasm_test.wasm
# 注意:「wasm-test」が「wasm_test」になるので注意すること
nano index.html
# 以下の内容のindex.htmlを作成する:
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Hello, WebAssembly!</title>
<script>
const wasm = './target/wasm32-unknown-unknown/release/wasm_test.wasm'
fetch(wasm)
.then(response => response.arrayBuffer())
.then(bytes => WebAssembly.instantiate(bytes, {}))
.then(results => {
console.log('wasm output:')
console.log(results.instance.exports.add(34, 56))
})
</script>
</head>
</html>
続き:
# http-serverを起動する
python3 -m http.server 8080
# web-browserで「localhost:8080」にアクセスする。
# consoleに以下が表示されていればOK:
# wasm output:
# 90
consoleに以下のようなエラーが出た場合、MIME-typeにwasmが登録されていないことになる。
TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'.
そのときは、/etc/mime.typesにwasmのMIMEtypeを登録する。
sudo leafpad /etc/mime.types
以下を末尾に追加する:
application/wasm wasm
登録後、http-serverを再起動する。
手順2
上の手順1の方法では文字列などをJavascript側に渡すことができない。 文字列を渡したい場合は、変換ツール(wasm-bindgen-cli)によってwasmをjsのモジュールに変換し そのモジュールを使うことにより文字列を引き渡すことができる。
以下、そのやり方について記する;
# 変換ツールのインストール
cargo install wasm-bindgen-cli
# 新しいプロジェクト wasam-test2 を作成する
cargo new --lib wasm-test
nano Cargo.toml
# Cargo.tomlを編集して以下を追加する:
[dependencies]
wasm-bindgen = "0.2"
[lib]
crate-type = ["cdylib"]
続き:
nano src/lib.rs
# src/lib.rs を編集して以下の内容にする:
src/lib.rs
extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn hello() -> String {
//"Hello WASM world!".to_string() ←こちらでも良い
String::from("Hello WASM world!")
}
#[wasm_bindgen]
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
続き:
# 以下を実行してビルドする
cargo build --target=wasm32-unknown-unknown --release
# 以下を実行して、wasmをjsに変換する
wasm-bindgen target/wasm32-unknown-unknown/release/wasm_test2.wasm --out-dir ./pkg --target web
# jsが生成されていることの確認
ls pkg/*.js
pkg/wasm_test2.js
nano index.html
# 以下の内容のindex.htmlを作成する:
index.html
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
</head>
<body>
<script type="module" src='./index.js'></script>
Rust -> Wasm -> Js test
</body>
</html>
注意:「<script type="module" 」であることに注意のこと
nano index.js
# 以下の内容を作成する:
index.js
// in script[type=module]
import init, {add, hello } from './pkg/wasm_test2.js';
(async () => {
await init();
// call Rust func
console.log(hello());
console.log('wasm->js output:')
console.log(add(34,56));
})();
続き:
# http-serverを起動する
python3 -m http.server 8080
# web-browserで「localhost:8080」にアクセスする。
# consoleに以下が表示されていればOK:
# Hello WASM world!
# wasm->js output:
# 90
サイズ情報
$ ls -l target/wasm32-unknown-unknown/release/wasm_test2.wasm
-rwxrwxr-x 2 xxxx 1794765 4月 18 10:49 target/wasm32-unknown-unknown/release/wasm_test2.wasm
$ ls -l pkg
合計 32
-rw-rw-r-- 1 xxxx 881 4月 18 10:49 wasm_test2.d.ts
-rw-rw-r-- 1 xxxx 2831 4月 18 10:49 wasm_test2.js
-rw-rw-r-- 1 xxxx 235 4月 18 10:49 wasm_test2_bg.d.ts
-rw-rw-r-- 1 xxxx 16946 4月 18 10:49 wasm_test2_bg.wasm
wasm_test2.wasmと(変換後の)wasm_test2.jsのサイズを比較すると、ずいぶん小さくなっている印象があるが、該当モジュールのなかで、wasm_test2_bg.wasmを呼び出しているようだ。
参考情報
WebAssembly入門
バンドラを使わずにRustをWASMにする
爆速でjsでWebAssemblyを動かす
Incorrect response MIME type. Expected 'application/wasm'エラーの対応
以上
| 固定リンク
「linux」カテゴリの記事
- platfomioを使ってnaitive(linux/windows)のプログラムをビルドする方法(2021.03.10)
- micro:bit Yotta開発ツール(linux版)(2021.01.09)
- PlatformIOをRaspberryPi4で動かしてみる(実験)(2020.10.20)
- headless RaspberryPiインストール方法(v2)(2020.10.20)
- wio-terminalのファームウェア・アップデートについて(linux版)(2020.10.15)
「Rust」カテゴリの記事
- プログラミング言語RustをXIAOで動かす(v2)(2020.10.05)
- プログラミング言語RustをXIAOで動かす(2020.06.09)
- プログラミング言語RustをFeather-M4-Expressで動かす(2020.05.28)
- プログラミング言語RustをCircuit-Playground-Expressで動かす(2020.05.28)
- プログラミング言語RustをNucleo-F103RBボードで動かす(STM32F1xx)(2020.05.11)
「wasm」カテゴリの記事
- Rustの出力したwasmを動かす(2020.04.18)
- GO/TinyGOの出力したwasmを動かす(2020.04.17)
コメント