IntelliJとWSLでOCaml

# 前提

+ OCamlのことはあんまりよく分かってません
+ JetBrainsによる公式サポートではない部分を含みます

# 登場人物

+ IntelliJ IDEA Ultimate
    + Community Editionでも大丈夫そう 
+ [reasonml-idea-plugin](https://github.com/reasonml-editor/reasonml-idea-plugin)
    + Reason MLのプラグインがOCamlもサポートしてるようです
+ Ubuntu on WSL（とbash）
+ OCamlのツール各種
  
# 概要 

Windows側にある
　IntelliJとプラグインが
Windows側にある
　プロジェクトに対して
WSL側にある
　bashとOCamlのツール各種を使って色々やります[^1][^2]

[^1]: （JetBrainsのC/C++向けIDEである）CLionでのCMakeサポートがだいたいこのような構成になっていて、さらにもう少しIDEとの連携ができます。

[^2]: VSCodeにはWSL側のファイルを開く機能が存在しており、Ubuntu上でVSCodeを開いている状態に限りなく近い状況で操作できます。構成がシンプルになって混乱も少ないので、IntelliJに愛が無ければVSCodeを使ったほうが良いと思います。

# WSLのbashをIntelliJのターミナルとして開く設定

`File | Settings | Tools | Terminal`で
Shell Path に `C:\Windows\System32\wsl.exe` を設定します。
プロジェクト単位で設定しておけるので大変便利です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202327/6105be7c-fb7f-1977-6f34-509f361c82d3.png)
中略
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202327/243a9742-48cd-7915-ff90-1fd3f0e823f5.png)
WSLのbashからWindowsのファイルは基本的には問題無く使えます。
（どういうエッジケースがあるかなどは把握していませんが、
　改行コードおよびgitで悲しい感じになる場合があります）

以下、コマンド実行はすべてWSLのbashで行います。

# OPAM

OCamlのパッケージマネージャであるOPAMを
WSLのUbuntuにインストールします
https://opam.ocaml.org/doc/Install.html#Ubuntu

```
add-apt-repository ppa:avsm/ppa
apt update
apt install opam
```

# OCamlコンパイラ

OPAMでOCamlコンパイラをインストールします
https://ocaml.org/docs/install.html#OPAM

```
# environment setup
opam init
eval `opam env`
# install given version of the compiler
opam switch create 4.10.0
eval `opam env`
# check you got what you want
which ocaml
ocaml -version
```

# エラー

>opam switch create 4.10.0

あたりでエラーに気づきます。

```
### output ###
# bwrap: Creating new namespace failed, likely because the kernel does not support user namespaces.  bwrap must be installed setuid on such systems.
```

# bwrap & sandbox

https://github.com/ocaml/opam/issues/3747#issuecomment-462339452
https://github.com/ocaml/opam-repository/issues/12050#issuecomment-393478072

+ サンドボックス機能のために`bwrap`というものが必要で、WSLではそれがサポートされていないようなので、サンドボックスを無効化します。
    + 一度も初期化してない状態であれば、`opam init --disable-sandboxing`でできそうですが、未確認
+ 一度以上（？）初期化済みであれば`~/.opam/config`にある`wrap-*-command`な設定を削除します
    + https://opam.ocaml.org/doc/Manual.html#configfield-wrap-build-commands

    + 空でも良いらしいのですが、サンドボックス用の設定らしきものしか無かったので項目ごと削除しました
    + 空にする際はたぶん`[]`を残します。`wrap-build-commands: []`みたいに。たぶん。

    ```
    wrap-build-commands:
    [ [ <term> { <filter> } ... ] { <filter> } ... ]
    wrap-install-commands:
    [ [ <term> { <filter> } ... ] { <filter> } ... ]
    wrap-remove-commands:
    [ [ <term> { <filter> } ... ] { <filter> } ... ]
    ```

その後、`opam init`からやり直します。

# SDKの設定

https://github.com/reasonml-editor/reasonml-idea-plugin/wiki/Configure-an-ocaml-project

+ プラグイン公式の通りSDKを設定しますが、WSL側にあるディレクトリを選びます。
    + `\\wsl$\Ubuntu\home\ユーザ\.opam\4.10.0`のような感じ
+ OCamlのソースはWSL側に`git clone`しましたが、どっちでも良さそう？

# 補完が効いて嬉しい！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202327/2bd11a5e-088b-c716-3091-df044820050a.png)

ただし、私はOCamlのことをあんまり分かってないので、何ができてどれだけ嬉しいかよく分かってません。

# `ocamlbuild`でHello World

ついに、Hello Worldです
https://ocaml.org/learn/tutorials/basics.html

>To compile an OCaml program named my_prog.ml to a native executable, use ocamlbuild my_prog.native:

ネイティブのバイナリを出力するためには`ocamlbuild`というのが必要なようですが、まだ入っていません。
`opam search ocamlbuild`で探すとやっぱり存在してたので
`opam install ocamlbuild`します。

あとは上記のチュートリアル通りにビルドして実行してください。