WSLを使ってC++をEmscriptenでWebAssemblyにコンパイルしたい

# 目標
WSLを使ってC++をEmscriptenでWebAssemblyにコンパイル

# 環境
Windows 10 Home

# 方法
## 1. WSLを有効，Ubuntuのインストール
### 1.1 WSLを有効にする

```コントロールパネル > プログラム > Windowsの機能の有効化または無効化```
```Windows Subsystem for LINUX```にチェックを入れる

### 1.2 Ubuntuのインストール

```Microsoft Store```を開いて```Ubuntu```と検索
3つくらい似た名前のソフトがヒットしましたが，僕は無印のUbuntuをインストールしました

### 1.3 ホームディレクトリを変更する
Windows側からWSL側のディレクトリにアクセスするのが非常に面倒だったのでC:直下に```ubuntu_home```ディレクトリを作ってそちらにホームディレクトリを変更しました
やりかたは[【WSL】Ubuntuのホームディレクトリを変更する _ IT土方の奮闘記](https://it-blue-collar-dairy.com/change_home_directory_for_ubuntu/)を参考にしました
めっちゃわかりやすい

## 2. Emscriptenのインストール
### 2.1 インストール
基本的に[公式チュートリアル](https://emscripten.org/docs/getting_started/downloads.html#sdk-download-and-install)通りにやったので使ったコマンドだけ書いておきます

```console:Shell
$ git clone https://github.com/emscripten-core/emsdk.git
$ cd emsdk
$ ./emsdk install latest
$ ./emsdk activate latest
```

### 2.2 PATHを通す
いつでもどこでもemccコマンドを呼びたいのでパスを通します

試しに

```console:Shell
$ source ./emsdk_env.sh
```
と入力するとこんな感じで追加するPATHや環境変数が返ってきます

```console:Shell
Adding directories to PATH:
PATH += /{user}/c/ubuntu_home/Projects/emsdk
PATH += /{user}/c/ubuntu_home/Projects/emsdk/upstream/emscripten
PATH += /{user}/c/ubuntu_home/Projects/emsdk/node/12.9.1_64bit/bin

Setting environment variables:
EMSDK = /{user}/c/ubuntu_home/Projects/emsdk
EM_CONFIG = /{user}/c/ubuntu_home/.emscripten
EM_CACHE = /{user}/c/ubuntu_home/Projects/emsdk/upstream/emscripten/cache
EMSDK_NODE = /{user}/c/ubuntu_home/Projects/emsdk/node/12.9.1_64bit/bin/node
```

まず```/{user}/c/ubuntu_home```内の```.profile```をVisual Codeなどのエディタで開いて一番下あたりにこれらを追記していく

```bash:.profile
# For Emscripten
# Adding directories to PATH:
PATH="/{user}/c/ubuntu_home/Projects/emsdk:$PATH"
PATH="/{user}/c/ubuntu_home/Projects/emsdk/upstream/emscripten:$PATH"
PATH="/{user}/c/ubuntu_home/Projects/emsdk/node/12.9.1_64bit/bin:$PATH"
# Setting environment variables:
EMSDK="/{user}/c/ubuntu_home/Projects/emsdk"
EM_CONFIG="/{user}/c/ubuntu_home/.emscripten"
EM_CACHE="/{user}/c/ubuntu_home/Projects/emsdk/upstream/emscripten/cache"
EMSDK_NODE="/{user}/c/ubuntu_home/Projects/emsdk/node/12.9.1_64bit/bin/node"
```

最初そのままコピペしたんだけどうまくいかなくて

- =前後のスペースを消す
- 中身を""で囲う
- PATHは最後に```:$PATH```をダブルクォーテーションの前に付け足す

てことをやったらうまくいきました．
シェルを再起動して

```console:Shell
$ emcc -v
```
が通ればOK！

## 3. EmscriptenでCをコンパイル
### コンパイル
公式チュートリアルにもあるようにまずはシンプルなCファイルのコンパイルからやってみた

以下のファイルを作成
作業用フォルダとして適当に```test_emsdk```を作ってそこに保存していく

```c:test_emsdk/hello.c
#include <stdio.h>
int main(int argc, char *argv[]){
  printf("Hello, world!\n");
  return 0;
}
```

以下のコマンドでコンパイル

```console:Shell
$ emcc hello.c -s WASM=1 -o hello.html
```

```-s WASM=1```で出力をWASMに指定して
```-o hello.html```でコードを実行するためのHTMLを指定している

うまくいけば```hello.c```と同じ階層に以下のファイルが生成される

- hello.html
- hello.js
- hello.wasm

さっそく```hello.html```をブラウザで開いてみる
今回はChromeを使った

### エラー
開けなかった
<img width="562" alt="error_emscripten.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616261/6202164d-810d-fce3-75b1-1b3affb9984b.png">

公式チュートリアルにこんなことが書いてあった
<img width="526" alt="error_emscripten2.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616261/5becc9b8-13e9-e380-d4c4-f0864bf454ca.png">
要するにXHRリクエストに対応してないからローカルのwebサーバーを立ち上げてそこで開く必要があるらしい

というわけでNode.jsを使ってローカルサーバーを起動します

## 4. WSLにNode.jsをインストール
apt-getを使うと古いバージョンがインストールされるとかっていう噂を見かけたので別のやり方でやりました
[WSL install Node](https://gist.github.com/micahgodbolt/8b9a338c8bab7bc147975646ea20826c)
ここにまさにやりたいことがドンピシャで書いてあったので丸々参考にした

まず，
[nvm-sh_nvm_ Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions](https://github.com/nvm-sh/nvm#installing-and-updating)
ここのページの```Install & Update Script```の項目に書かれている

```console:Shell
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
```
をホームディレクトリにて実行．（バージョンが変わってるかもしれないので実際に上のページに行ってコピペすることを推奨します）

次に以下のコマンドを実行してインストール

```console:Shell
$ source ~/.bashrc      // バッシュの再読み込み
$ nvm install node      // nodeのインストール
```

確認

```console:Shell
$ node --version
v14.2.0
```
OK！

## 5. 簡易的にローカルサーバー起動
http-serverというものを使えばお手軽にサーバー起動できるみたいなので採用してみた

**インストール**

```console:Shell
$ npm install -g http-server
```

**起動**
作業用の```test_emsdk```ディレクトリ上で以下のコマンドを実行

```console:Shell
$ http-server -o
```
この```-o```オプションをつけると起動後自動的にブラウザを開いてくれる

## 6. あらためてhello.htmlを開く
今しがた```http-server```で起動したサーバーから```hello.html```にアクセス
<img width="598" alt="ok_emscripten.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616261/96799f14-1816-5ac0-3ded-e674dee0c29e.png">

今度はうまくいった！！

# 次の目標
本来の目標である複数cppファイルのコンパイルとかやりたい


# 参考
- [【WSL】Ubuntuのホームディレクトリを変更する _ IT土方の奮闘記](https://it-blue-collar-dairy.com/change_home_directory_for_ubuntu/)
- [C_C++からWebAssemblyにコンパイルする - WebAssembly _ MDN](https://developer.mozilla.org/ja/docs/WebAssembly/C_to_wasm)
- [WSL install Node](https://gist.github.com/micahgodbolt/8b9a338c8bab7bc147975646ea20826c)
- [http-serverを使用してNode.js上で簡単にローカルサーバーを立ち上げる - Qiita](https://qiita.com/h-koeda/items/6ab3603c77c562ed8cca)