宝石を作りたいのですが、誰かがMRIで使用しようとすると、Cコードを使用し、JRubyから使用する場合はJavaコードを使用します。
のこぎりとプーマの宝石がこれを行い、私は彼らのコードをちらっと見ましたが、彼らがそれをどのように実現しているかはわかりませんでした。
これは、rvm(またはrubiesを切り替えるための他の同様のツール)とrake-compilerを使用して、ターゲットとするさまざまなプラットフォーム用にgemをクロスコンパイルすることによって行われます。
ファイルには、gemspec
各プラットフォームに必要なファイルを指定する必要があります。これは、gemがコンパイルされているプラットフォームをチェックすることによって行われます。
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
でRakefile
、インストール後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
ただし、プラットフォームごとに特定のタスクを実行する必要がある場合があります。
rake native gem
MRIを使用すると、;でコンパイルします。JRubyを使用すると、rake java gem
–これはrvmのようなツールが便利になる場所です。最終的に、プラットフォームごとに1つずつ、gem用に異なるgemファイルが作成され、gemとしてリリースできます。
詳細については、 rake-compilerのドキュメントを参照するか、 redclothやpg_array_parserなど、同じことを行う他のプロジェクトを確認してください(これについては、nokogiriよりも優れた例だと思います)。