ホーム   »  Ruby
Tag | Ruby

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Windows で Rails3 の動作環境構築を諦める3つの理由

Windows 7 に Ruby 1.9.2 + Rails 3.1.1 動作環境を構築しようと迷い込んだ壮絶な修羅の道について、後人が同じ轍を踏まないように要点を記しておきます。

理由1. ネイティブライブラリ

兎に角ネイティブライブラリ周りは鬼門。

gem でインストールするライブラリには導入時にネイティブライブラリ (Windows で言う DLL のようなもの) をコンパイルするものがありますが、このビルド方法が Windows 未対応であることが多い。自前でやるにもコンパイラの種類、バージョンの違いに厳しかったり、欠落したライブラリが何であるかソースを読まなければ分からなかったり、リンク先の DLL を MinGW 用にエクスポートしなければいけなかったり、そもそも C のソースが Unix 環境前提で修正箇所が大量にあるなど、とにかく一度トラブルと調査にかなりの時間を浪費するし最終的に解決しない事も多い。

私の場合は mysql2 アダプタのコンパイルに三連休の丸 2 日を費やして諦めました (残り一日はこのエントリで消えました)。代替で mysql, ruby-mysql アダプタで回避しようとしても MySQL2 で定義されている定数などをオンコードで参照していたため無理でしたし、この問題が解決しても後にまだ therubyracer のコンパイルが控えています。

理由2. 32bit

メモリをふんだんに載せた開発マシンでも 32bit 版一択という状況。Ruby ランタイムは 64bit 対応しているが、追加ライブラリが 64bit 未対応などの状況に遭遇することも少なくない。Ruby ランタイムも 64bit 自体が枯れていないようで原因不明のエラーに何度か遭遇した (当方の環境の問題かもしれないが)。

理由3. 環境との相性の悪さ

バッチファイル (*.bat) やファイルセパレータ (\) などの環境の違い、空白入りディレクトリ名などの慣習が MSYS や make と相性が悪く地味に問題の原因になる。

対策

今は VMWare に CentOS を入れて歪ながらも平穏な生活を送っています。

対策1. Windows を使わない

Rails プラットフォームは Unix 系 OS を前提として開発されている (Windows は放置気味な) ことが 3.1 になってさらに強くなったように感じます。可能であれば開発端末には Linux か Mac OS X を使ったほうが無駄な事に時間を費やさずに済むでしょう :-P

対策2. 仮想環境で Linux を立てる

問題なのは Rails の実行環境のため開発環境は Windows のままでかまわないでしょう。Windows 上に VMWare や VirtualBox で Linux 環境を作り、プロジェクトのディレクトリごとを共有して環境を分離するという方法も取れます。会社から Windows マシンしか与えられていないのであればこれが一番現実的ですね。

対策3. JRuby を使用する

Unix 系はどうも… と言うのであれば JRuby on Rails で構築するのも一つの手かと思います。リンク先の記事の通り、こちらは特に問題もなく動作環境が構築できます。ただサーバの起動が遅かったりライブラリ構成やコードの挙動が違うなどの弊害があるかもしれません。

開発用の動作環境ではなくリリース環境が Windows に縛られているという場合には JRuby しか選択肢はないですね。

"Could not find a JavaScript runtime" と Rails 3.1 起動に失敗する件

表題のままなのですが、結論から言いますと SELinux DEATH! そうです、またこいつなんです。

Rails 3.1 から内部で CaffeeScript を使うようになったそうで実行時に JavaScript ランタイムが必要になりました。Gemfile に execjs と therubyracer を追加して bundle install を実行すれば必要なライブラリが入ります。入るはずですなんです。

torao@cumin$ vi Gemfile
# ...
gem 'execjs'
gem 'therubyracer'  # 追加

torao@cumin$ bundle install

しかしそれでも「JavaScript ランタイムが見つからない」と Rails を起動できないことがあります。というかできませんでした。

torao@cumin$ rails server -e development
/home/torao/.rvm/gems/ruby-1.9.2-p290/gems/execjs-1.2.9/lib/execjs/runtimes.rb:47:in `autodetect': Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)
        from /home/torao/.rvm/gems/ruby-1.9.2-p290/gems/execjs-1.2.9/lib/execjs.rb:5:in `'
        from /home/torao/.rvm/gems/ruby-1.9.2-p290/gems/execjs-1.2.9/lib/execjs.rb:4:in `'
…

gem list を実行しても必要な JavaScript ランタイムが導入されているように見えます。

torao@cumin$  gem list

*** LOCAL GEMS ***

actionmailer (3.1.1)
…
execjs (1.2.9)
…
therubyracer (0.9.8)
…

Rails から見えていないというより Ruby 実行環境から見えていないのかも? コマンドラインから直接 require で参照してみましたが同じエラーが出るため Ruby からライブラリが見えていないようです。

torao@cumin$ ruby -e "require 'execjs'"
/home/torao/.rvm/gems/ruby-1.9.2-p290/gems/execjs-1.2.9/lib/execjs/runtimes.rb:47:in `autodetect': Could not find a JavaScript runtime. See https://github.com/sstephenson/execjs for a list of available runtimes. (ExecJS::RuntimeUnavailable)
        from /home/torao/.rvm/gems/ruby-1.9.2-p290/gems/execjs-1.2.9/lib/execjs.rb:5:in `'
        from /home/torao/.rvm/gems/ruby-1.9.2-p290/gems/execjs-1.2.9/lib/execjs.rb:4:in `'
        from :33:in `require'
        from :33:in `rescue in require'
        from :29:in `require'
        from -e:1:in `
'

例外の発生箇所 execjs/runtimes.rb(47) を見てみます。環境変数 EXECJS_RUNTIME に設定されているランタイムか、または実行環境で使利用可能な JavaScript ランタイムを選択しているようです。

def self.autodetect
  from_environment || best_available ||
    raise(RuntimeUnavailable, "Could not find a JavaScript runtime. " +
      "See https://github.com/sstephenson/execjs for a list of available runtimes.")
    # ↑ここで例外!
end

def self.best_available
  runtimes.find(&:available?)
end

def self.from_environment
  if name = ENV["EXECJS_RUNTIME"]
    if runtime = const_get(name)
      if runtime.available?
        runtime if runtime.available?
      else
        raise RuntimeUnavailable, "#{runtime.name} runtime is not available on this system"
      end
    elsif !name.empty?
      raise RuntimeUnavailable, "#{name} runtime is not defined"
    end
  end
end
…
def self.runtimes
  @runtimes ||= [
    RubyRacer,
    RubyRhino,
    Johnson,
    Mustang,
    Node,
    JavaScriptCore,
    SpiderMonkey,
…

RubyRacer がインストールされているはずなのに best_available が false を返している部分が想定と違う動きです。RubyRacerRuntime クラスの available? を追ってみます。

def available?
  require "v8"
  true
rescue LoadError
  false
end

どうも V8 エンジンのロードに失敗しているようです。コマンドラインから試してみると確かにネイティブライブラリのロードに失敗していました (「インストールされていない」ならともかく「インストールされているのにロードに失敗した」ならエラーログくらい出してもらいたいところです)。

torao@cumin$ ruby -e "require 'v8'"
/home/torao/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require': /home/torao/.rvm/gems/ruby-1.9.2-p290/gems/therubyracer-0.9.8/ext/v8/v8.so: cannot restore segment prot after reloc: Permission denied - /home/torao/.rvm/gems/ruby-1.9.2-p290/gems/therubyracer-0.9.8/ext/v8/v8.so (LoadError)
        from /home/torao/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
        from /home/torao/.rvm/gems/ruby-1.9.2-p290/gems/therubyracer-0.9.8/lib/v8.rb:6:in `'
…

で、cannot restore segment prot after reloc: Permission denied の原因は何かと調べてみたら、変な場所からライブラリをロードできないよう SELinux がブロックしていることが原因でした。開発用サーバのため rvm 流儀で $HOME/.rvm 以下に gem リポジトリが置かれたのがアダとなったようです。

とりあえず今回は開発用の動作環境ですので root で /etc/sysconfig/selinux を編集し SELINUX=disabled にして再起動しましたところこの問題は解消しました。本番環境などで SELinux を無効化したくない場合はこちらなどを参考に Ruby が参照している v8.so をロードする許可を与えてください。

三連休最後の一日がこれで潰れましたよ。とほほ…

Ruby 1.9.2 ソースビルド

Rubyサイトからソースをダウンロードし、回答、ビルド、インストールを行う。例として今回は 2011年9月12日最新安定板の 1.9.2-p290 を使用。

torao@clove$ wget "ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-p290.tar.gz"
--2011-09-12 18:23:10--  ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-p290.tar.gz
           => `ruby-1.9.2-p290.tar.gz'
ftp.ruby-lang.org をDNSに問いあわせています... 221.186.184.68
ftp.ruby-lang.org|221.186.184.68|:21 に接続しています... 接続しました。
anonymous としてログインしています... ログインしました!
==> SYST ... 完了しました。    ==> PWD ... 完了しました。
==> TYPE I ... 完了しました。  ==> CWD /pub/ruby/1.9 ... 完了しました。
==> SIZE ruby-1.9.2-p290.tar.gz ... 11182217
==> PASV ... 完了しました。    ==> RETR ruby-1.9.2-p290.tar.gz ... 完了しました。
長さ: 11182217 (11M)

100%[==========================================================>] 11,182,217  1.20M/s 時間 8.8s

2011-09-12 18:23:19 (1.22 MB/s) - `ruby-1.9.2-p290.tar.gz' へ保存終了 [11182217]

torao@clove$ tar zxvf ruby-1.9.2-p290.tar.gz
ruby-1.9.2-p290/
ruby-1.9.2-p290/.cvsignore
ruby-1.9.2-p290/.document
…
torao@clove$ cd ruby-1.9.2-p290
torao@clove$ ./configure --prefix=/usr/local/ruby-1.9.2-p290
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking target system type... x86_64-unknown-linux-gnu
…
torao@clove$ make
gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -Wpointer-arith -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -I. -I.ext/include/x86_64-linux -I./include -I. -DRUBY_EXPORT   -o main.o -c main.c
gcc -O3 -ggdb -Wextra -Wno-unused-parameter -Wno-parentheses -W
…
torao@clove$ sudo make install
[sudo] password for torao:
./miniruby -I./lib -I.ext/common -I./- -r./ext/purelib.rb  ./tool/generic_erb.rb -c -o encdb.h ./template/encdb.h.tmpl ./enc enc
encdb.h unchanged
make -f enc.mk RUBY="./miniruby -I./lib -I.ext/common -I./- -r./ext/purelib.rb " MINIRUBY="./miniruby -I./lib -I.ext/common -I./- -r./ext/purelib.rb "  srcs
…
torao@clove$ cd /usr/local
torao@clove$ sudo ln -s ruby-1.9.2-p290 ruby

あとは /usr/local/ruby/bin にパスを通して終わり。

Aptana 3 で JRuby on Rails 開発環境構築

Eclipse 3.7 で Aptana Studio 3 を導入して Ruby on Rails 3 開発環境を構築するまでの手順です。JRuby で行っておりますが普通の Ruby でも作業は同じですので参考にしてください。Aptana Studio 3 Getting Started も参照。

EclipseEclipse 3.7 (Indigo)
AptanaAptana Studio 3.0.4
JavaOracle JDK 1.6.0u26
RubyJRuby 1.6.4 (ruby-1.9.2-p136)
RailsRails 3.0.10
続きを読む

Rails 3.0.10 インストール

JRuby 1.6.4 をインストールした後に gem から Rails 3.0.10 をインストールしてみた。

OSWindows XP
RubyJRuby 1.6.4 (ruby-1.9.2-p136)
JavaOracle JDK 1.6.0u26
RailsRails 3.0.10
続きを読む
Profile
Takami Torao
Takami Torao
C/C++ 使いだった 1996年、運命の Java と出会い現在に至る。のらアーキテクト。
Yah, this is image so I don't wanna eat spam, sorry!
Search

Google
MOYO Laboratory
Web

カテゴリー
最近の記事
最近のコメント
最近のトラックバック
月別アーカイブ
ブロとも申請フォーム
RSSフィード
リンク
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。