きりかノート 3冊め

おあそびプログラミング

ruby_selectを実装してみた

id:kimuraw:20090412:p2のつづき。

とりあえず1.8.7と1.8.6では利用できるようになったと思うので、macports-devにメール出す前に日本語で整理しておく。

ディレクトリ構成

ruby本体そのものはディレクトリをわけて共存できるようにして、ライブラリ類のディレクトリは共有するというようにした。具体的には以下のようになる。

dir,file 1.8.6(ruby186) 1.8.7(ruby18)
bin/ruby bin/ruby186 bin/ruby18
bin/irb bin/irb186 bin/irb18
libdir lib/ruby/1.8.6/ lib/ruby/1.8.7/
sitedir lib/ruby/site_ruby/1.8/ (share)
vendordir lib/ruby/vendor_ruby/1.8/ (share)
libruby.so libruby186.dylib libruby18.dylib
ri sysdir share/ri/1.8/system1.8.6/ share/ri/1.8/system1.8.7/
ri sitedir share/ri/1.8/site/ (share)


また、同一ファイルになってしまう、macportsの独自拡張のvendor-specific.rbとsite-specific.rbは両方ともlibdirに移動した。

ruby_select

使い方はこんな感じ。

% ruby_select ruby18
Selecting version "ruby18" for ruby
% ls -l =ruby
lrwxr-xr-x  1 root  admin  21 Apr 18 21:03 /opt/local/bin/ruby@ -> /opt/local/bin/ruby18
% sudo ruby_select ruby186
Selecting version "ruby186" for ruby
% ls -l =ruby
lrwxr-xr-x  1 root  admin  22 Apr 18 21:06 /opt/local/bin/ruby@ -> /opt/local/bin/ruby186
%

(macportsの)port:gcc_selectやport:python_selectが使っている共通のツールがあるので、それにのっける形で(というかパクリ)用意した。

${prefix}/etc/select/${name}以下にリンクを張る対象の一覧を記述したテキストファイルを作成する。

baseが作成されるシンボリックリンクで、その他のファイルがruby_selectの引き数となるバージョンになる。シンボリックリンクを作成するのは以下のファイルについて。

  • bin/ ruby, erb, irb, rdoc, ri, testrb
  • lib/ libruby.dylib, libruby-static.a

この実装の課題

今日だけでざくざくっと実装したものということもあって、やっぱり穴がある。今の時点で認識しているものについて。

libruby.dylibへのリンク

拡張モジュールのリンク対象は、それぞれ以下のようになるようにしている(ruby18の場合)。

  • 標準添付ライブラリ: libruby18.dylib
  • site_dir(macportsを使わないライブラリ): libruby18.dylib
  • vendor_dir(macports利用): libruby.dylib (ruby_selectによる)

1番目は閉じた世界だから問題ない。あと、3番目についてもよいだろう。どうせdepends_lib port:rubyしてあるはずだし。うーむ、suffixなしのlibruby.dylibの存在を保証するために、ruby_selectをrubyのメタportにするのがよいような気がしてきた。

で、問題は2番目だ。メタportまたはruby_selectなしで使いたい場合には、拡張ライブラリはsuffixありのほうにリンクしないと機能しない。このケースを考えない、てことにすれば、これもsuffixなしにリンクするということでいけるけど、どうだろう。macportsを通さない、素のgem使うときはsuffixなしのほうにリンクしたいし。

現在のport:rubyからのマイグレーション

port:rubyをメタportとして構成したあと、アップグレードをどうするか。
今はいってるrubyがあればdeactivate、依存関係になるruby[18|186|19]をインストール、とする必要があるけれどどうしたものだろう。できれば自動にしたいよなあ。

(2009-04-19 追記)冷静に考えてみたら、ruby186とruby18で共通の場所はぜんぶ棲み分けするようにしたから、現無印のruby(将来のruby18)とぶつかるファイルパスがないんだな。この件はそのままsudo port upgradeすりゃ済む話だね。解決っ。