SML#をレガシー環境にインストール

わけあって [SML# 3.2.0](www.pllab.riec.tohoku.ac.jp/smlsharp/) を [Vine Linux 6.3](https://vinelinux.org/aboutvine63.html) にインストールした時のメモ。 

SML# のインストールは、[マニュアル](http://www.pllab.riec.tohoku.ac.jp/smlsharp/docs/3.0/ja/manual.xhtml)の [インストール手順](http://www.pllab.riec.tohoku.ac.jp/smlsharp/docs/3.0/ja/Ch6.S3.xhtml) に従えば、 macOS や Ubuntu ならパッケージマネージャ経由で行えるため、全く苦労はない。  それ以外のディストリビューションでも、 LLVM 3.7.1 をパッケージマネージャからインストールできれば、あとは標準的な ./configure && make && make install で行えるので、あまり苦労はないはずだ。 

しかし Vine Linux 6系のようなレガシー環境ではまず確実に LLVM 3.7.1 をソースからビルドする羽目になる。 さらに Vine Linux 6 が出たのは 2011年のことで、そこから構成を大きく変えていない 6.3 (2015年2月) は gcc や諸々のライブラリが **非常に** 古いため、 gcc を含め多くのソフトウェアをソースからビルドしなければならずとても手間がかかる。  (それでも gmp-devel や yajl-devel は既存のものを使えるのは救いだ)

そんなわけで、GCC 4.9.4, LLVM 3.7.1, SML# 3.2.0 をソースからインストールした時のメモ。インタプリタとコンパイラはざっと動作確認してある。 

Vine Linux 6.3 x64 を「デスクトップ」オプションでインストールした直後からの手順を書いている。

以下の手順では、 gccをソースからビルドして　/usr/local にインストールしている。 このままだと SML# が /usr/lib64/libstdc++.so.6 を優先して使ってしまうためうまく動かない。 export LD_LIBRARY_PATH=/usr/local/lib64 などとしてから smlsharp を実行する必要がある。

```sh
# Python 2.7
sudo apt-get install zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel
wget https://www.python.org/ftp/python/2.7.12/Python-2.7.12.tgz
tar zxf Python-2.7.12.tgz
cd Python-2.7.12
./configure && make -j4 && sudo make install

# CMake 3.6
wget https://cmake.org/files/v3.6/cmake-3.6.2.tar.gz
tar zxf cmake-3.6.2.tar.gz
cd cmake-3.6.2
./bootstrap && make -j4 && sudo make install

# gcc 4.9.4 インストール
wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-4.9.4/gcc-4.9.4.tar.bz2
tar jxf gcc-4.9.4.tar.bz2
cd gcc-4.9.4
./contrib/download_prerequisites
cd ..
mkdir gcc-4.9.4-build && cd gcc-4.9.4-build
$PWD/../gcc-4.9.4/configure --enable-languages=c,c++ --disable-multilib
make -j4
sudo make install

# gcc アンインストール
sudo apt-get remove gcc libstdc++-devel

# llvmインストール
wget http://llvm.org/releases/3.7.1/llvm-3.7.1.src.tar.xz
tar xf llvm-3.7.1.src.tar.xz
mkdir llvm-3.7.1-build && cd llvm-3.7.1-build
export LD_LIBRARY_PATH=/usr/local/lib64
cmake -G”Unix Makefiles” $PWD/../llvm-3.7.1.src
make -j4
sudo make install

# SML#
apt-get install gmp-devel yajl-devel
export LD_LIBRARY_PATH=/usr/local/lib64
wget http://www.pllab.riec.tohoku.ac.jp/smlsharp/download/smlsharp-3.2.0.tar.gz
tar zxf smlsharp-3.2.0.tar.gz
cd smlsharp-3.2.0
./configure --with-llvm=/usr/local
make -j4
make install
```

# 解説

* LLVMのビルドに Python 2.7 と CMake が必要なので入れる。 CMake の必要バージョンはメモしそこねたけど Vine Linux のパッケージはだめだった。
* **gcc を入れ直す。** パッケージの gcc 4.4.5 の g++ では -std=c++11 を受け付けないため。
* 幸い パッケージの gmp-devel は使えているようだ

# /usr/local/lib64 を使うようにする

そのまま SML# を起動すると

```
smlsharp: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.18' not found (required by smlsharp)
smlsharp: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.17' not found (required by smlsharp)
smlsharp: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.14' not found (required by smlsharp)
smlsharp: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.15' not found (required by smlsharp)
smlsharp: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by smlsharp)
```

などと、 標準の /usr/lib64 を見に行ってしまうため失敗する。 これはそもそも素の gcc がそうなっているためだ。何か変だと思う (/usr/local に入れた gcc でビルドしたのだから libstdc++ も /usr/local のものを見に行くべき) が、[GCC の FAQ](https://gcc.gnu.org/faq.html#rpath) 曰くそういうもののようだし、仕方がない。 

/usr/local/bin/smlsharp, smlyacc, smllex, smlformat をそれぞれ smlsharp.orig などとサフィックスをつけた名前にリネームし、

```sh
#!/bin/sh
export LD_LIBRARY_PATH=/usr/local/lib64:$LD_LIBRARY_PATH
exec $0.orig "$@"
```

という内容の同名のラッパーを /usr/local/bin に置いておくと良い（注：後述）。

(あるいは LLVM や SML# のコンパイル時 (と、SML#が gcc を呼び出す時) に  -Wl,-rpath=/usr/local/lib64 などとリンカオプションを渡せればよかったのだが、上の手順ではそうなっていない。)

## どうすればよかったか

[続編へ](http://qiita.com/keigoi/items/e88d3f90b6f4dfb22a3f)