[Rubygems-developers] Platform Specification and Auto-selecting the Platform

Jim Weirich jim at weirichhouse.org
Mon Apr 23 22:14:56 EDT 2007

Warning: Long Message Follows ...

The recent thread on specifying equivalent gems brought out the
fact that RubyGems does not provide a good interface for
selecting from multiple platform gems. Chad and I had a
discussion earlier this year about handling that situation
better. One of the things we need to understand is exactly what
kind of platforms we need to deal with and that lead to the
Tattle project
(http://www.chadfowler.com/2007/1/8/tattle-the-ruby-census). I
haven't seen the results of tattle yet (perhaps Chad would like
to share the gathered data), but I have been thinking about a
framework for platforms. Let me lay that out now and get
feedback, and we can work the details of exactly what platforms
we need into the framework when we have the tattle data.

The current situation is that we have essentially two types of
platforms, Ruby and Win32 right now (is there anything else?).
Soon we will be getting gems with a Java / JRuby platform. I'm
thinking its time to organize that.

My proposal is to have 3 types of platforms:

(1) Pure Ruby Platform. Gems in this category can be run using
just a Ruby runtime (either MRI, Yarv, or JRuby). A good number
of gems will fall into this category. Pure ruby gems will be
designated with "ruby" (no designation defaults to a pure ruby

(2) Source Gems. Source gems are gems that come with source code
that needs to be built (compiled, links, etc) in order to be
installed. Source code gems will be designated either "C" or
"Java" depending on the language of the source code. Other
languages could be supported in the future, but this will do for

(3) Binary Gems. Binary gems have the compiled object code
packaged in the gem. During installation, all you have to do copy
the libraries (or Jars) to the right location. No compile toolset
is needed.

Binary gems will be designed hierarchically as follows:

(a) Hardwore architecture (e.g. x86, ppc, sparc, jvm).
(b) OS (e.g. mswin, linux, macos, bsd, aix)
(c) Optional OS variant (xp, vista, redhat, ubuntu)
(d) Optional OS revision.

So, the binary platform designation for the computer I'm writing
this on might be: x86-macos-10.4.9. The hardware platform for my
mail server would be x86-linux-debian-2.4.24. My parallels
virtual machine might be x86-mswin-xp (I have no idea what
version of XP I'm running there, but you get the idea). If I were
running JRuby, the binary platform would be simply "jvm-1.4.2".

I'm skipping the question of how we can access all this
information uniformly across all the platforms. Put that down as
your homework assignment.

Now, the platform designation for a gem indicates what
hareware/os it can run on. So mygem-1.0_jvm-1.4 will run on any
Java platform with version 1.4 or better. mygem-1.0_x86-macos-10
will run on any version of MacOS X running on Intel hardware.
Since you can produce universal binaries on a mac that run on
either Intel or PowerPC, I would suggest that
mygem-1.0_uni-macos-10 would be a gem with universal binaries.

(Note that proposed naming scheme for gem file names. Will this
be a backwards compatibility issue? I don't think so. The gem
file name is just so we don't have file names for different
platforms that collide. I suspect that RubyGems will get the real
platform info from the gemspec itself).

So, that's how we designate platforms. How will gems choose a
platform (more or less) automatically.

Here's the selection process. Gems will know what platform its
running on (note to self: do we have to handle cross platform
installations?). It just needs to find compatible gems. Here's
the process:

(1) Determine the latest version of a gem that satisfies the
version constraint (exactly as it is handled now).

(2) Find all the platforms available for the chosen version.

(3) If there is a binary gems that matches the target platform,
select the gem that has the longest match (e.g. x86-mswin-xp is a
better match than x86-mswin). When matching OS versions, the gem
version must be less than or equal to the target version.

(4) If there are no matching binary gems, then if the target
machine has a compile toolkit available, then select the source
gem (either C or Java) that is appropriate.

(5) If there are no source gems available, or if the target
machine doesn't have a compile environment (i.e. most windows
machines), then install the pure ruby platform.

The algorithm prefers gems that are more specialized for a
particular platform, but falls back with reasonable results.

We will probably need a way to override the default platform
selection. I would recommend making the override available for
only explicitly installed gems (not for gems that are installed
automatically because they are dependencies).

Does this make sense?  What do you think?

-- Jim Weirich      jim at weirichhouse.org     http://onestepback.org
-- In theory, practice and theory are the same.
-- In practice, they are different.

More information about the Rubygems-developers mailing list