ruby - 如何制作同时针对 MRI 和 JRuby 的 gem?

标签 ruby gem jruby

我想制作一个 gem,当其他人尝试将它与 MRI 一起使用时,它将使用 C 代码,而当他们从 JRuby 中使用它时,它将使用 Java 代码。

nokogiri 和 puma gems 就是这样做的,我看过他们的代码,但没有看到他们是如何实现的。

最佳答案

这是通过使用 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

但您可能需要针对不同的平台执行特定任务。

使用 MRI,然后使用 rake native gem 进行编译;使用 JRuby,rake java gem – 这是像 rvm 这样的工具派上用场的地方。您最终会为您的 gem 获得不同的 gem 文件,每个平台一个,然后您可以将其作为您的 gem 发布。

参见 rake-compiler documentation有关更多详细信息,或查看其他执行相同操作的项目,例如 redclothpg_array_parser (我发现他们是比 nokogiri 更好的例子)。

关于ruby - 如何制作同时针对 MRI 和 JRuby 的 gem?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13536119/

相关文章:

ruby - Net::SSH似乎未连接到远程主机

ruby-on-rails-3 - Neo4j ActiveRecord 支持使用 Ruby 作为解释器

ruby-on-rails - 在Rails应用程序中记录内部线程

java - Jruby 统计库

ruby - 让 Ruby 与 Node.js 交互

ruby-on-rails - 进一步改进 Active Record/Postgresql 查询

ruby - YAML 每个缩进有多少个空格?

ruby-on-rails - 本地 Gem Assets 未更新

ruby - 在 Ubuntu 12.10 上安装 Nokogiri (1.5.2) 时出现问题

ruby-on-rails - gem 列表在更新 gem 后立即显示两个版本的 Ruby gem