SML# v3.3.0をWSLにインストールする

Bash on Ubuntu on WindowsもといWindows Subsystem for Linux（WSL）でSML#をソースコードからインストールする方法。

# 先にまとめ

- 実質Ubuntuなので、SML#は問題なくインストール可能で動作もする。
- SML# v3.3.0は起動後にCPUパワーをひじょうに食うため、v3.2.0のREPLと併用するのがよい。

# 前提条件

- OS：Windows10
- SML#バージョン：v3.3.0

# 対象者

- Windows10でSML#を利用したい人
- ソースビルドする暇がある人
    - 公式パッケージのほうが簡単に入るはず

# 関連ライブラリのインストール

## libyajl-devとか

SML#ソースに含まれるINSTALL書いてないけど、libz、libeditも必要だった。
Ubuntuの初期状態では入っていなかった。

```bash
aptitude install libyajl-dev libz-dev libedit-dev
```

## LLVM(3.7.1)

SML#はLLVM v3.7.1の`llvm-config`と`llvm-as`を要求する。[^1]
Ubuntu xenialでのllvmパッケージはv3.8.0のため、llvm-3.7パッケージを利用する。
~~ただし、llvm-3.7パッケージが提供するコマンド名は`llvm-config-3.7`などと、
バージョン番号が後ろについている。
そこでupdate-alternativeを使い、`llvm-config`コマンドとして管理する。~~

[^1]: `configure --help`を見たところ、LLVMのディレクトリ指定はできるが、コマンド名指定は見つからなかった。

```bash
aptitude install llvm-3.7
# 以下はあまりよくなかった
# update-alternative --install /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-3.7 100
# update-alternative --install /usr/bin/llvm-as llvm-as /usr/bin/llvm-as-3.7 100
```

SML#公式のパッケージ内容を見てみると違う方法が見つかった。
Ubuntuのllvm-3.7パッケージは`/usr/lib/llvm-3.7/bin`にllvm-configやllvm-asのコマンドを持っている。
`/usr/lib/llvm-***`に各バージョンのLLVMバイナリやライブラリが格納されている。
ここをSML#のビルドconfigureで指定すればいい。

## Massive Threads

下記リンク先の手順に従う

- https://github.com/massivethreads/massivethreads

### インストール

`/usr/local/`に配置される。

```bash
git clone git@github.com:massivethreads/massivethreads.git
cd massivethreads
./configure CFLAGS="-Wall -Wextra -O3"
make
make install
cd tests
make build
make check
```

### ライブラリリストを更新

これをやらないと、SML#のビルドで`libmyth.so.0`が見つからない。

```bash
ldconfig
```

# SML#のインストール

v3.2.0と共存方法は後述。
ここのインストールを飛ばし、次の説へ進む。

## 普通にインストールする方法

`/usr/local/`に配置される。

```bash
# ./configure
./configure --with-llvm=/usr/lib/llvm-3.7
make
make install
```

## 複数バージョンを共存させる

ここからは、個人的に使いやすい設定をメモする。

現状のSML# 3.3.0は起動するだけでCPUを大幅に食う。
私のCore i7-7600UでもCPUの70%がsmlsharpプロセスに割かれる。
SML#の起動とともに、CPUファンが一気に鳴り出す。
なので、複数バージョンを利用する。

### SML#のアンインストール

用意されてないので手動で行う。

```bash
rm -rf /usr/local/lib/smlsharp
rm /usr/local/bin/smlformat
rm /usr/local/bin/smllex
rm /usr/local/bin/smlsharp
rm /usr/local/bin/smlyacc
```

他にsmlなんたらがなければ、`rm /usr/local/bin/sml*`で消せるはず

### v3.3.0のインストール

インストール先を変更する。

```bash
mkdir /opt/smlsharp/v3.3.0
# ./configure --prefix=/opt/smlsharp/v3.3.0
./configure --prefix=/opt/smlsharp/v3.3.0 --with-llvm=/usr/lib/llvm-3.7
make
make install
```

### v3.2.0のインストール

インストール先を変更する。

```bash
mkdir /opt/smlsharp/v3.2.0
# ./configure --prefix=/opt/smlsharp/v3.2.0
./configure --prefix=/opt/smlsharp/v3.2.0 --with-llvm=/usr/lib/llvm-3.7
make
make install
```

### smlsharpの選択管理

REPLは`smlsharp`という名前でv3.2.0を使い、
コンパイルは`smlsharpc`という名前でv3.3.0を使うことにする。

```bash
update-alternative --install /usr/bin/smlsharp smlsharp /opt/smlsharp/v3.2.0/bin/smlsharp 100
update-alternative --install /usr/bin/smlsharpc smlsharpc /opt/smlsharp/v3.2.0/bin/smlsharp 80
update-alternative --install /usr/bin/smlsharp smlsharp /opt/smlsharp/v3.3.0/bin/smlsharp 80
update-alternative --install /usr/bin/smlsharpc smlsharpc /opt/smlsharp/v3.3.0/bin/smlsharp 100
```

# 蛇足

- SML/NJは32bit前提のため、64bit前提のWSLではまだ動かないらしい。今後に期待。
    - https://github.com/Microsoft/BashOnWindows/issues/228
    - 実際にパッケージ・ソースの両方を試したがだめだった。
- MLtonは、パッケージインストールだけで問題なく動いた。