2012-11-23 12 views
6

私は宝石を作りたいと思っています。誰かがMRIでそれを使用しようとすると、Cコードが使用され、JRubyからJavaコードを使用すると、Javaコードが使用されます。MRIとJRubyの両方をターゲットとする宝石を作るにはどうすればいいですか?

ノコギリとプーマの宝石がこれを行い、私は彼らのコードを見てきましたが、どうしたのか分かりませんでした。

+0

も参照してください。http://stackoverflow.com/questions/3642085/make-bundler-use-different-gems-for-different-platforms – knut

+0

これは私が言っていることではありません。私は宝石を作りたいと思っています。誰かがMRIでそれを使用しようとすると、Cコードが使用され、JRubyからJavaコードを使用すると、Javaコードが使用されます。 nokogiriとpumaの宝石はこれを行いますが、私はコードを見ていましたが、どうしたのか分かりませんでした。 – jshen

+0

最も簡単な方法は、ルビーの宝石を書くことです。これは 'jRuby' 、「MRI」または任意の実施形態を含む。それはうまく動作します。あなたはあなたの宝石の外部依存関係が何であるかを指定していません。 – nikhil

答えて

6

これは、rvm(またはルビーを切り替えるための他の同様のツール)とrake-compilerを使用して、ターゲットとするさまざまなプラットフォームのgemをクロスコンパイルすることによって行われます。

gemspecファイルには、各プラットフォームに必要なファイルを指定する必要があります。 、Rakefile

Gem::Specification.new do |gem| 
# . . . 

    if RUBY_PLATFORM =~ /java/ 
    # package jars 
    gem.files += ['lib/*.jar'] 
    # . . . 
    else 
    # package C stuff 
    gem.files += Dir['ext/**/*.c'] 
    # . . . 
    gem.extensions = Dir['ext/**/extconf.rb'] 
    end 
end 

rake-compilerをインストールした後、パターンは通常、以下の通りです:

spec = Gem::Specification.load('hello_world.gemspec') 

if RUBY_PLATFORM =~ /java/ 
    require 'rake/javaextensiontask' 
    Rake::JavaExtensionTask.new('hello_world', spec) 
else 
    require 'rake/extensiontask' 
    Rake::ExtensionTask.new('hello_world', spec) 
end 

しかし、あなたが特定の操作を行う必要があり、これは宝石がしてコンパイルされているプラ​​ットフォームを確認することで行われますさまざまなプラットフォームのためのタスク。

MRIでは、rake native gemでコンパイルします。 JRubyでrake java gem - これはrvmのようなツールが便利な場所です。あなたは最終的に、あなたの宝石のための異なった宝石のファイルで終わることができます。

詳しくはredclothpg_array_parserなどの他のプロジェクトをチェックしてください(これはノコギリよりも良い例です)。

関連する問題