如何在Ruby Gem中包装Ruby C扩展? [英] How do I wrap up a Ruby C extension in a Ruby Gem?

查看:110
本文介绍了如何在Ruby Gem中包装Ruby C扩展?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我找不到很多文件。如何打包gem,以便在安装gem时编译C扩展名?



特别我想这样做:




  • 我想在gem install上编译C扩展名


  • on Windows我想简单地安装一个预编译的.so




对此有任何帮助,特别是源代码,非常有用:)

解决方案

Luis Lavena 创建了 rake-compiler 仅用于此目的。





然而,你确定你需要C扩展吗?关于C扩展的一点是,每个Ruby实现都有自己的C扩展API(和基于非C的类似,比如XRuby,JRuby,Ruby.NET,IronRuby,HotRuby,MagLev,Red Sun根本就没有)意味着你的C扩展只能在 1 实现中工作。而且,由于MRI only 实现了Ruby 1.8和YARV ,所以实现了Ruby 1.9,而我们目前处于1.8和1.9之间的转换阶段,很多人可能会至少使用两种不同的实现。 (我个人使用5:MRI,YARV,JRuby,IronRuby和Rubinius。)



也许你最好使用 Ruby-FFI 。 Ruby-FFI是Ruby的一个FFI(外部函数接口)( duh ),它允许您以可在Ruby实现中移植的方式绑定并映射纯Ruby中的C库。 FFI API首先由 Evan Phoenix 开发,作为本地扩展API Rubinius ,然后通过 Charles Oliver Nutter (并通过 Wayne Meissner )实现 JRuby 韦恩之后还写了 Ruby-FFI gem ,其中包含用于MRI和YARV的C扩展。 Laurent Sansonetti MacRuby Marc-AndréCournoyer tinyrb 支持FFI (再次由 Wayne Meissner 撰写)和 MagLev 开发人员也在努力。这意味着如果你可以让你的库使用FFI而不是C扩展,你将自动支持6个Ruby实现,而不仅仅是一个。



唯一的原因是如果你真的想做一些实现特定的行为,那么使用C扩展而不是FFI扩展。其中一个例子就是 ParseTree 宝石,它深入到MRI的肠道内, - 分析树的内存表示。



最后但并非最不重要的一点,请看 John Croisant 项目,尼斯FFI 项目旨在使 Ruby-FFI 更好。


I can't find many docs on this. How do I package a gem such that the C extension is compiled when the gem is installed?

In particular I want to do this:

  • on Linux and MacOSX i would like compile the C extension on gem install

  • on Windows I would like to simply install a precompiled .so

any help on this, in particular example source, would be very useful :)

解决方案

Luis Lavena has created rake-compiler just for this purpose.

However, are you sure that you need a C extension? The thing about C extensions is that every Ruby implementation has their own C extension API (and non-C based ones like XRuby, JRuby, Ruby.NET, IronRuby, HotRuby, MagLev, Red Sun don't have one at all), which means that your C extension will only work on one implementation. And, since MRI only implements Ruby 1.8 and YARV only implements Ruby 1.9, and we are currently in a transition phase between 1.8 and 1.9, chances are that a lot of people will use at least two different implementations. (I personally use 5: MRI, YARV, JRuby, IronRuby and Rubinius.)

Maybe you are better off using Ruby-FFI. Ruby-FFI is an FFI (Foreign Function Interface) for Ruby (duh), which allows you to bind to and map C libraries in pure Ruby in a manner that is portable across Ruby implementations. The FFI API was first developed by Evan Phoenix as the native extension API for Rubinius, it was then adopted by Charles Oliver Nutter (and implemented by Wayne Meissner) for JRuby. Wayne then also wrote the Ruby-FFI gem, which contains C extensions for MRI and YARV. Laurent Sansonetti implemented Ruby-FFI for MacRuby, Marc-André Cournoyer's tinyrb also supports FFI (again written by Wayne Meissner) and the MagLev developers are also working on it. Which means that if you can make your library work with FFI as opposed to a C extension, you will automatically support 6 Ruby implementations instead of just one.

The only reason to use a C extension as opposed to an FFI extension would be, if you really do want some implementation specific behavior. One example of this would be the ParseTree gem, which reaches deep into the intestines of MRI and rips out the in-memory representation of the parse tree.

Last but not least, take a look at the Nice-FFI project by John Croisant, which aims to make using Ruby-FFI even nicer.

这篇关于如何在Ruby Gem中包装Ruby C扩展?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆