Rustでwasmをビルド (windows) _ Apacheで実行


今回はRustを使ったWebAssembly(wasm)の方法について書いていきます。
本来なら、Rustの環境構築から行うところですが、環境構築に関しては既に他の方が書かれている記事がいくつかありますので、今回は省きます。
コマンドで「cargo --version」が通るぐらいの環境を前提として環境構築します。
(あと、windowsで作成するにあたり、C++のビルドツールは必要になるかもしれないです。今回は.exeを作成するわけではないので、実際に必要なのかはわかりませんが)

開発環境

windows10
cargo 1.47.0 (Rustのことです)
xampp(wasmを Apacheで読み込ませる上で使用します。)
Microsoft Edge(IE以外のブラウザーなら基本動きます。詳細は下記参照)
https://developer.mozilla.org/ja/docs/WebAssembly

環境構築

まず、Rustの「wasm-pack」をインストールします。
「wasm-pack」はRustのソースコードを「.wasm」にビルドする上で必要になります。
コマンドラインで下記を実行することでインストールできます。

$ cargo install wasm-pack

今回はApacheでwasmを読み込ませようと思うので、xamppをダウンロードします。
下記リンクのサイトからダウンロードしてください。
https://www.apachefriends.org/jp/index.html
基本的にはインストーラーを起動して、適当に「OK」を押下しておけば大丈夫です。
インストールの時点で気にすることは特にありません。
インストール後に ApacheのMIMEタイプを設定します。
ApacheのMIMEタイプを設定する場合は、「httpd.conf」に書き込みを追加します。
xamppを使用している場合は、下記画像の様に「config」ボタンを押下すると「httpd.conf」を開くことができます。

書き込む内容は、

 AddType application/wasm .wasm

と書き込みます。
書き込みを行う位置は「httpd.conf」内で「AddType」を検索すると、今回書き込む内容と似たような記述がされている場所があるので、その辺りに書き込むのが無難でしょう。
これにより、Apacheで「.wasm」を処理できる様になります。

コーディング・ビルド

wasm用のプロジェクトを作成します。
wasm用と言っても、基本的には Rustの libプロジェクトです。
コマンドラインで"C:\xampp\htdocs"に移動したあと、下記コマンドを実行します。
(xamppで実行する場合、"C:\xampp\htdocs"フォルダ下にファイル類を入れておく必要があるので、プロジェクトもそこに作成しておきます。)

$ cargo new --lib sample_wasm_rust

今回作成するプロジェクト名は「sample_wasm_rust」としておきます。
コマンドに「--lib」を設定していますが、「--lib」で作成しなくとも「cargo.toml」を修正すればlibプロジェクトにすることができます。
コマンドラインを実行すると自身の環境下にプロジェクトが作成されるかと思います。
Rustでwasmを作成する上で必要なクレートを追加します。
「cargo.toml」ファイルの [dependencies]に下記の書き込みを追加します。

cargo.toml
[dependencies]
wasm-bindgen="0.2"

次に「lib.rs」に下記のコードを書き込みます。

lib.rs
use wasm_bindgen::prelude::wasm_bindgen;

#[wasm_bindgen]
pub fn res()->String{
    format!("Rust側の返答")
}

処理の内容は res()関数を呼び出すと"Rust側の返答"を戻り値として返す処理になっています。
Rustのコード内の関数に#[wasm_bindgen]を付けることで javascript側から関数を呼び出せるようになります。
Rustのコードが書けたら wasmにビルドします。コマンドラインで下記を実行して下さい。

wasm-pack build --target web

ビルド時のコマンドについての詳細は下記を参考にしてください。
https://rustwasm.github.io/docs/wasm-pack/commands/build.html
ビルド実行すると「pkg」フォルダが作成され、「pkg」フォルダ下に「.wasm」ファイルが作成されます。
これで wasm自体は完成です。

次は呼び出す側の.htmlを作成します。コードの中身は下記の通りです。
格納先は、今回作成したプロジェクトの「sample_wasm_rust」フォルダ下に入れておきます。

index.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
  </head>
  <body>
    <h1>wasm_sample</h1>
    <script type="module">
      import init, * as wasm from './pkg/sample_wasm_rust.js';
      async function run() {
        await init();
        var result = wasm.res();
        alert(result);
      }
      run();
    </script>
  </body>
</html>

処理自体は wasmから「res()」関数を呼び出して、結果をアラートで出力するという単純なものです。
大した内容は書いていないですが、念のため、下記のリンクにソースを挙げておきます。
https://github.com/NagaJun1/wasm_sample

実行

コードが書きあがったら、xamppでApacheを起動して実行します。
xamppを起動し、Apacheの「start」ボタンを押下するとデフォルトの設定の場合、ポート80と443が起動するかと思います。
起動したら、下記URLにアクセスします。
http://localhost:80/sample_wasm_rust/

成功したら上記の画像の様に、ブラウザのアラート内にRustで設定した文字列が表示されるかと思います。

まとめ

Rustでwasmを作成する方法と、xampp(Apache)でwasmを処理する方法について書かせていただきました。
他の方が書かれた内容を見ると、httpサーバーを立てて実行しているとかいうのがあったんですが、自分はRustのコードしかわからないので、xampp(apache)経由の方が楽でしたね(笑)
今回はJavsScriptからRustを呼び出すという一方通行なことしかしませんでしたが、RustでJavaScriptを呼び出すこともできるので、気が向いたらその方法についても記事にしようかと思います。
あと、RustからのDOM操作についても気が向いたら書こうかと思います。
まあ、DOM操作に関しては他の方が書かれてた記事があったので、記事ができるまで待っていられないという方はそちらを参考にしてください(笑)

参考

mozillaのRust、wasmの公式サイト
https://developer.mozilla.org/ja/docs/WebAssembly/Rust_to_wasm