[Rubygems-developers] pure-ruby vs. compile-on-intsall

Florian Frank flori at nixe.ping.de
Wed Nov 7 07:37:30 EST 2007

Trans wrote:
>>>> I'm a bit confused. If I have a pure-ruby version of my lib, but also
>>>> have some extensions that can speed things up, should the pure-ruby
>>>> gem be named plainly? Eg. 'foo-1.0.0.gem'.  But then what platform is
>>>> the compile-on-install gem? Am I going about this wrong? I'm starting
>>>> to think it would be easier to create two packages, one for the
>>>> pure-ruby gem and another for the optional extensions.
> I need to provide these:
>   * pure ruby version
>   * compile-on-install version
>   * win32 pre-built version
> I would like to make the first two a single gem, rather then two
> separate gems. To do that I need RubyGems not to abort if make fails.
> I am going to try to figure out a way to do that. But if someone
> already has an idea how, please let me know.
If you figure this out, please post the solution to the list. I had/have
exactly the same problem with my json gem, which offers a pure ruby
implementation variant and a faster c extension variant.

I have used another name (json_pure) for the pure ruby variant, which
solves one problem: You now can pick the json variant, if your platform
supports compilation, and you can pick json_pure if you have to use the
pure version. Ironically my json gem would automatically fallback to the
pure variant anyway, if the shared objects couldn't be loaded. So the
json_pure variant contains almost the same files as the json variant
does, and the json variant includes the pure ruby version, which can be
used by requiring 'json/pure' instead of requiring 'json'.

Another problem isn't solved by this workaround, though. If some other
developer adds json as a dependency, it will resolve to the compile
variant, but the resolution will fail altogether on a platform like
jruby, which doesn't support compilation.

I have learned that merb ran into this problem, they now use json_pure
as a dependency. This is far from optimal. I have made made a RubyGems
feature request for a pure ruby platform
a while ago, in order to address this problem, but it was closed without
a real solution.

It's unfortunate, that RubyGems conflates gems, that are pure ruby with
those that will trigger a compilation process, but I guess it's too late
to change this now. In the case of json, it would be indeed be enough,
if RubyGems would soldier on and just install the pure ruby stuff
anyway, if compilation fails. But this isn't guaranteed to work for
other gems, that don't have a pure ruby fallback.

The gem command could do a better job to resolve dependencies as well:

It could first figure out, if the platform under which is running,
supports compilation. If the json dependency is being resolved on
platform like jruby, that doesn't support compilation like jruby, it
should first look for a binary platform specific gem, e. g. jruby
platform. If none is found, it should look for a pure platform variant
and try to install that one. If there is no pure platform found, it
should assume, that the ruby platform gem is actually a pure ruby
implementation and try to install that one. This could still fail, but
this would be the same behaviour, that is happening now.

If this algorithm would be implemented, merb could use the json
dependency and automatically get the fastest possible variant on the
given platform.

I hope, that there will be a better solution for the pure ruby issue,
but I don't know, how I could solve this by building the gems any

Florian Frank

More information about the Rubygems-developers mailing list