如何在Ruby Gem中包装Ruby C扩展?

时间:2022-10-30 08:14:01

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?

我在这方面找不到很多文档。如何打包gem以便在安装gem时编译C扩展?

In particular I want to do this:

特别是我想这样做:

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

    在Linux和MacOSX上我想在gem install上编译C扩展

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

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

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

任何有关这方面的帮助,特别是示例源代码,将非常有用:)

2 个解决方案

#1


14  

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

Luis Lavena为此目的创建了rake-compiler。

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.)

但是,您确定需要C扩展吗?关于C扩展的事情是每个Ruby实现都有自己的C扩展API(而非基于X的扩展,如XRuby,JRuby,Ruby.NET,IronRuby,HotRuby,MagLev,Red Sun根本没有),表示您的C扩展仅适用于一个实现。而且,由于MRI只实现了Ruby 1.8而YARV只实现了Ruby 1.9,而且我们目前处于1.8到1.9之间的过渡阶段,很可能很多人会使用至少两种不同的实现。 (我个人使用5:MRI,YARV,JRuby,IronRuby和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.

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

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.

如果您确实需要某些特定于实现的行为,那么使用C扩展而不是FFI扩展的唯一原因是。其中一个例子就是ParseTree宝石,它深入到MRI的肠道并撕掉了解析树的内存中表示。

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

最后但并非最不重要的是,看看John Croisant的Nice-FFI项目,该项目旨在使Ruby-FFI更加出色。

#2


0  

I have a github repo that I maintain just for my own reference and these things have helped me.

我有一个github回购,我维护只是为了我自己的参考,这些东西帮助了我。

Ruby_C_extensions

Ruby_C_extensions

It may help to look around on github to find some good examples of gems already written just for your study but go ahead and clone them and see if you can build them on your system. If they were put together right they should build just fine.

它可能有助于在github上查找已经为您的研究编写的宝石的一些好例子,但继续克隆它们,看看您是否可以在您的系统上构建它们。如果将它们组合在一起它们应该构建得很好。

Please note that you do need some build tools in any platform you're using. Here is a video that I just watched that tells you what you need for Linux.

请注意,您在任何正在使用的平台中都需要一些构建工具。这是我刚看过的一段视频,它告诉你Linux需要什么。

Python Programming Environment Setup

Python编程环境设置

Now I know that that it says Python, he does show you how to install the build tools packages.

现在我知道它说Python,他确实向您展示了如何安装构建工具包。

I use DevKit for Windows and it works for me. With anything the installation of the tools is the most important.

我使用DevKit for Windows,它适用于我。对于任何事情,安装工具是最重要的。

I also have used rake-compiler and hoe to set up the folder structure. So it looks like we have to lean some gardening by getting a rake and a hoe. :-D

我也使用rake-compiler和hoe来设置文件夹结构。因此看起来我们必须通过耙子和锄头来减少一些园艺。 :-D

#1


14  

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

Luis Lavena为此目的创建了rake-compiler。

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.)

但是,您确定需要C扩展吗?关于C扩展的事情是每个Ruby实现都有自己的C扩展API(而非基于X的扩展,如XRuby,JRuby,Ruby.NET,IronRuby,HotRuby,MagLev,Red Sun根本没有),表示您的C扩展仅适用于一个实现。而且,由于MRI只实现了Ruby 1.8而YARV只实现了Ruby 1.9,而且我们目前处于1.8到1.9之间的过渡阶段,很可能很多人会使用至少两种不同的实现。 (我个人使用5:MRI,YARV,JRuby,IronRuby和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.

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

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.

如果您确实需要某些特定于实现的行为,那么使用C扩展而不是FFI扩展的唯一原因是。其中一个例子就是ParseTree宝石,它深入到MRI的肠道并撕掉了解析树的内存中表示。

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

最后但并非最不重要的是,看看John Croisant的Nice-FFI项目,该项目旨在使Ruby-FFI更加出色。

#2


0  

I have a github repo that I maintain just for my own reference and these things have helped me.

我有一个github回购,我维护只是为了我自己的参考,这些东西帮助了我。

Ruby_C_extensions

Ruby_C_extensions

It may help to look around on github to find some good examples of gems already written just for your study but go ahead and clone them and see if you can build them on your system. If they were put together right they should build just fine.

它可能有助于在github上查找已经为您的研究编写的宝石的一些好例子,但继续克隆它们,看看您是否可以在您的系统上构建它们。如果将它们组合在一起它们应该构建得很好。

Please note that you do need some build tools in any platform you're using. Here is a video that I just watched that tells you what you need for Linux.

请注意,您在任何正在使用的平台中都需要一些构建工具。这是我刚看过的一段视频,它告诉你Linux需要什么。

Python Programming Environment Setup

Python编程环境设置

Now I know that that it says Python, he does show you how to install the build tools packages.

现在我知道它说Python,他确实向您展示了如何安装构建工具包。

I use DevKit for Windows and it works for me. With anything the installation of the tools is the most important.

我使用DevKit for Windows,它适用于我。对于任何事情,安装工具是最重要的。

I also have used rake-compiler and hoe to set up the folder structure. So it looks like we have to lean some gardening by getting a rake and a hoe. :-D

我也使用rake-compiler和hoe来设置文件夹结构。因此看起来我们必须通过耙子和锄头来减少一些园艺。 :-D