简体   繁体   中英

How do I wrap up a Ruby C extension in a Ruby Gem?

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.

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

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.

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.

Python Programming Environment Setup

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM