如何制作针对MRI和JRuby的宝石?

我想创建一个gem,当其他人试图将它与MRI一起使用时,它将使用C代码,当他们从J Ruby使用它时,它将使用Java代码.

nokogiri和puma gems这样做,我已经看了他们的代码,但没看到他们是如何实现它的.

解决方法

这是通过使用rvm(或其他类似工具在ruby之间切换)和 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这样的工具变得方便的地方.你终于得到了宝石的不同宝石文件,每个平台一个,然后你可以作为你的宝石发布.

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

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...