This is done by cross-compiling the gem for the different platforms you are targeting, using rvm (or other similar tools to switch between rubies) and rake-compiler.
The gemspec
file must specify the files needed for each platform; this is done by checking the platform the gem is being compiled with:
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
In the Rakefile
, after installing rake-compiler
, the pattern is usually the following:
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
But you may need to do specific tasks for the different platforms.
With MRI, you then compile with rake native gem
; with JRuby, rake java gem
– this is where a tool like rvm gets handy. You finally end up with different gem files for your gem, one per platform, that you can then release as your gem.
See rake-compiler documentation for more details, or check out other projects that do the same, such as redcloth or pg_array_parser (I find they are better examples than nokogiri for this).