cygiwnでrvmを使ってruby-1.9.2をビルド&インストールする
herokuのデフォルトのrubyが1.9.2になるとのことで、cygwinにもruby-1.9.2を入れておくことにしました。
直接ソースをビルドしてシステムに入れるのではなく、rvmを使ってHOME下にインストールしました。
以下は、その手順です。
事前準備1: cygwinパッケージのインストール
cygwin上に以下のパッケージが入ってなければ入れます。当然cygwin自体も最新版にしておきます。(上からssl certの更新で使うもの、さらにrvmで必要なもの、さらにrubyのビルドで必要なもの、です)
- curl
- openssl
- ruby
- git
- patch
- gcc4
- mingw-win32api
- make
- openssl-devel
- libgdbm-devel
- zlib-devel
- tcltk
- bison
- autoconf
- m4
- libffi4
- libreadline7
- libopenssl098
- procps
- quilt
(いらないものや足りないものがあるかも)
事前準備2: cygwinのSSLルート証明書のアップデート
cygwin付属のルートSSL証明書は古いようで、gitやcurlやwgetでrvmのサイトなどへhttps接続しようとすると失敗してしまいます。
そこでまず、cygwin上のcertを更新する必要があります。
git - SSL certificate rejected trying to access GitHub over HTTPS behind firewall - Stack Overflow の回答にあるやり方そのままでOKでした。
具体的には以下の3行を実行します:
cd /usr/ssl/certs curl http://curl.haxx.se/ca/cacert.pem | awk 'split_after==1{n++;split_after=0} /-----END CERTIFICATE-----/ {split_after=1} {print > "cert" n ".pem"}' c_rehash
rvmのインストールとruby-1.9.2-headのビルド
事前に古いrvmデータは削除しておきます。
rm -rf ~/.rvm ~/.rvmrc
https://rvm.beginrescueend.com/に書いてある方法でrvmを入れます。
bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
certが古いままならばここで何も表示されずに終わってしまいます。certが更新されていればgit経由でrvmをダウンロードしていきます。
次にrvmを使ってruby-1.9.2を入れます:
source $HOME/.rvm/scripts/rvm rvm install 1.9.2-head -C "--enable-shared optflags='-O2 -march=native'"
certが古かったり、cygwinパッケージが足りなかったりするとダウンロードやビルドに失敗し赤い文字が画面上に出ます(失敗しなければ緑か白の文字だけ出ます)。
ruby-1.9.2のビルドの仕方はcygwinでrvm - akcnvの個人的備忘録 @ ウィキ - アットウィキのものを参考にしています。今の1.9.2-headではLIBRARY_PATHの設定は不要のようです。(ちなみに1.8.7-headのほうは、上記記事にある対策を取る必要がありました。)
rvmのruby-1.9.2がきちんと入ったことを確認する
ビルド後、そのままコマンド
rvm use 1.9.2-head
を実行するとrubyコマンドやgemコマンドが、rvm上のruby-1.9.2のものを使うようになります。
以下のような結果になっていれば入っていることになります:
$ ruby -v ruby 1.9.2p274 (2011-06-06 revision 31932) [i386-cygwin]
システムのrubyコマンドに戻す場合は、
rvm use system
です。
起動時にrvmコマンドを使えるようにする
以下の行を~/.bashrcや~/.bash_profile等に追加すれば、ターミナルを立ち上げた時点でrvmコマンドが使えるようになります。以下の行はrvmのインストーラーが自動で追加するようです。
[[ -s $HOME/.rvm/scripts/rvm ]] && source $HOME/.rvm/scripts/rvm
デフォルトのrubyをrvmのrubyにする
上記の.bash_profileに加え、以下を実行しておけば、次のターミナル起動からは最初からrubyコマンドやgemコマンドが、rvmのruby-1.9.2のものを使うようになります。
rvm use 1.9.2-head --default
rvm gemsetでgem環境を切り分けよう
rvmはrubyランタイムだけでなく、gemパッケージの環境を切り替えることができます。たとえば、webアプリプロジェクトごとに必要なgemパッケージだけを持った環境を作っておくことで、プロジェクトごとにgem環境を切り替えて使うことができます。
gem環境の管理はrvm useした状態に入ってる時にrvm gemsetコマンドを使って行います。
gem環境作成、たとえばminiblogプロジェクトのための"miniblog"環境を作る場合は
rvm use 1.9.2-head rvm gemset create miniblog
を実行します。
次に作ったgem環境に切り替えます。
rvm gemset use miniblog
この状態であとはgemコマンドでgem installしていけば良いです。
rvm useコマンドで一緒にgem環境も切り替えることも可能です。
rvm use 1.9.2-head@miniblog
ちなみにデフォルトのgem環境は"global"です。
おまけ: cygwinでrvm install 1.8.7-headする方法
インストール方法
curl -O http://dl.dropbox.com/u/14499563/ruby-1.8.7-p348-cygwin/current-cygwin-has-own-setjmph.patch rvm install 1.8.7-head -C "--enable-shared optflags='-O2 -march=native'" --patch ./current-cygwin-has-own-setjmph.patch
解説
普通にビルドして失敗するのは、cygwinがすでにsetjmp.hを持っているのに、ソースeval.cとgc.c中でifdef __CYGWIN__内でsetjmp/longjmpのプロトタイプ宣言をしているからです(しかも型が違う)。
そのためmakeを失敗させないためには、単純にこの宣言部分を削除するpatchをつくればいいことになります。
patchの作り方(ruby-1.8.7-p348の場合)
cd ~/.rvm/src/ruby-1.8.7-head/ ed eval.c <<EDIT 210,212d wq EDIT ed gc.c <<EDIT 42,44d wq EDIT git diff > ~/current-cygwin-has-own-setjmph.patch
このpatchはdropbox上においておきます。
https://rvm.beginrescueend.com/rubies/patching/によると、 ".rvm/patches/ruby/1.8.7/"にあるpatchは自動適用されているようで、そこに置くようにgithubでpull requestするのが良いようです。