macOSにmozjs-45.0.2をインストール

# 概要

[React](https://facebook.github.io/react/)や[Node.js](https://nodejs.org/ja/)などJavaScriptベースの技術が華やかなりしであります。
私の本業的にReactやNode.jsの学習はあまり切迫してはいないのですが、それはさておきES2016は知りたいと思い、JavaScriptエンジンであるmozjsをインストールしようと思いました。

最初はMacPortsでインストールをしようと思ったのですが、執筆時時点(2016年12月)ではES2016非対応のバージョンでメンテナンスが止まっていたため、tarball(xxx.tarやxxx.tar.zzなどファイルのこと)を持ってきて自分でビルドしてみるかということに。

GoogleのV8ではなくMozillaのmozjsを選択した強い動機は特になく、強いて言えばtarballを持ってきて展開してconfigure && makeでイケそうだなという程度でした。

# tarballのダウンロード

Mozillaのサイトから、mozjs-45.0.2.tar.bz2をダウンロードします。macOSであれば、bz2ファイルはダブルクリックでもtarでも展開可能です。執筆時時点では安定板のmozjs-45.0.2が最新でした。

- [https://people.mozilla.org/~sfink/mozjs-45.0.2.tar.bz2](https://people.mozilla.org/~sfink/mozjs-45.0.2.tar.bz2)

# インストール

手順としては、いたって簡単です。
適当なディレクトリ(ダウンロードディレクトリでも構いません。インストール時に/usr/local配下などにコピーされます)に、ダウンロードしてきたmozjsのtarballをtarで展開します。かくいう私も、ブラウザからダウンロードしたので、直接Downloadsフォルダで展開してしまいました。

展開されたディレクトリにあるINSTALLファイルをエディタなりmoreなりcatなりで読んでみます。まさに、ここに書いてある手順にしたがって作業をすればいいだけなのです。

# と、思ったら…

いや、厳密には、ほぼ手順通りではありました。
たぶん他のUNIX系OSであっても、私がmacOS上で作業したように、おそらくはスムーズにコトは運ぶはずなのです。

以下のように、まったくINSTALLファイルに書かれているとおりに、実行したのです。

```shell-session:INSTALLファイルの記述どおりに作業	
> cd js/src
> mkdir obj
> cd obj
> ../configure && make
```

JavaScriptエンジンともなると結構なボリュームのソースコードですから、configure && makeが終わるまでの時間は、それ相応にかかります。
コンパイル時間そのものはマシンスペックや、同時に走っているプロセス数に依存するので何時間何分とも言えませんが、私のMacBook Pro(Retina,13-inch,Early 2015)では、およそ30分ぐらいで終わりました。

ビルドが終わったら、make installでインストールします。
当然、/usr/local配下にインストールされるので、root権限でmake insallを実行する必要があります。
ちなみに「zura」は私のMBPでのユーザ名なので、その辺は適当に自分のユーザ名で調整してください。

```shell-session:バイナリのインストール	
> sudo su - root
# cd ~zura/Downloads/mozjs-45.0.2/js/src/obj
# make install 
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C js/src install
make[1]: Circular js.pc <- js.pc dependency dropped.
../../config/nsinstall -t js.pc /usr/local/lib/pkgconfig
../../config/nsinstall -t js-config.h /usr/local/include/mozjs-45
/Users/zura/Downloads/mozjs-45.0.2/js/src/obj/_virtualenv/bin/python -m mozbuild.action.process_install_manifest --no-remove /usr/local/include/mozjs-45 ../../_build_manifests/install/dist_include
From /usr/local/include/mozjs-45: Kept 0 existing; Added/updated 141; Removed 0 files and 0 directories.
../../config/nsinstall -t js-config /usr/local/bin
../../config/nsinstall -t libjs_static.a /usr/local/lib
mv -f /usr/local/lib/libjs_static.a /usr/local/lib/libjs_static.ajs
../../config/nsinstall -t libmozjs-45.dylib /usr/local/lib
../../config/nsinstall -t libmozjs-45.dylib /usr/local/lib
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C shell install
../../../config/nsinstall -t js /usr/local/bin
　　　　　:
　　　　　:
　　　　　:
```

うん、よいよい。と、しばらく画面を眺めていたのですが…。
rootから一般ユーザ(zura)に戻ってjsコマンドを叩くと…しょんぼりな結果に。

```shell-session:インストールしたjsコマンドを実行したら…
zura> js
dyld: Library not loaded: @executable_path/libmozglue.dylib
  Referenced from: /usr/local/bin/js
  Reason: image not found
Abort
```

libmozglue.dylibという動的ライブラリがないといわれてしまいました。おーい、なぜにライブラリをインストールしてくれへんのかいな…。

# 調査

そこで、findコマンドを使って、/usr/local配下に本当に動的ライブラリがインストールされていないかどうか確認しました。

```shell-session:動的ライブラリのfind	
> find /usr/local -name libmozglue.dylib
```

なんも表示されん…どうやらビルドされなかったのか、インストールされなかったかの、いずれかです。
それじゃあ、インストール元(mozjs-45.0.2/js/src/obj)配下にはあるのでしょうか。こちらもfindコマンドで調べます。

```shell-session:mozjs展開ディレクトリ中をfind
> find . -name libmozglue.dylib
./dist/bin/libmozglue.dylib
./dist/sdk/lib/libmozglue.dylib
./mozglue/build/libmozglue.dylib
```
なんだ、ビルドもされていて、ライブラリ自体もあるじゃあないですか。

make installで使われていたインストールコマンドはnsinstallでしたので、このコマンドがどこにあるのかを確認します。

```shell-session:nsinstallコマンドのfind	
> find . -name nsinstall
./config/nsinstall
./dist/bin/nsinstall
```

dist/bin/nsinstallがありました。ちょうど、dist/bin/libmozglue.dylibと同じディレクトリ内にいますね。
ということは、configureでこのインストールが抜けていたということなんでしょうか。

# 改めて、インストール

configureを改修するのは気が引けたので(コミュニティに貢献してやれよ…とは自分でも思ったけど他用がありまして…)、そのままnsinstallコマンドを使って、同じディレクトリ内のlibmozglue.dylibをインストールしました。
当然ここでも、rootにsuしてからの作業になるので注意してください(sudoだけで実行してもよいでしょう)。

```shell-session:nsinstallでlibmozglue.dyliboをインストール
# cd dist/bin
# ./nsinstall -t libmozglue.dylib
```

特に何のメッセージ出力もなく終わりました。本当にインストールされたのかをfindコマンドで確認します。

```shell-session:/usr/local配下のlibmozglue.dylibをfind
# find /usr/local -name libmozglue.dylib
/usr/local/lib/libmozglue.dylib
```

ありました。無事にインストールできているようです。

# 実行

改めて、jsコマンドを実行してみます。jsコマンドはJavaScriptの対話式インタプリタです。

```shell-session:jsコマンドの実行
> js
js> let a = 10
js> a == 10
true
js> class Test {
  constructor () {
    let x = 10;
  }
}
js> let y = new Test();
```

ES2016は詳しく理解していないので(だって勉強するために入れたんだもん)、上のコード例は結構適当なのですが、letもclassも使えるのでES2016のコードが解かるjsがインストールされているということは確認できました。