Posts Tagged ‘gems’

Custom Ruby and RadRails on Mac OS X

Tuesday, January 20th, 2009

Let’s break this down, shall we …

Building Ruby and RubyGems

Many thanks to Dan Benjamin for his excellent posting on doing a custom build of Ruby & RubyGems on OS X. I was just getting started with using a Mac at the time, and it was a very straight-forward and helpful guide. For most software, I’ll use MacPorts or standard Apple packages, but for Ruby I’ll make an exception.

For starters, I just want to expand a bit on his excellent tutorial. I won’t re-iterate his whole piece, but the outline is:

  • start with OS X Leopard, and XCode (from your Optional Installs DVD)
  • get /usr/local and its derivatives into your path
  • set aside a good long-term home for your custom build code
  • pull down the source for Ruby
  • run ./configure, then build and install with make
  • pull down the source for RubyGems, run its setup.rb

After that you can install all of the gems that your heart desires. I initially pulled down source for the Ruby 1.9 candidate release, but there are significant enough language changes that it destabilized a lot of tried-and-true gems. Instead, I went with the latest generation of 1.8.7.

I did however run into a little issue when installing the native mysql gem. Dan’s instructions weren’t valid for my case. Fortunately, the README.html in the gem suggested building it manually as such:

$ sudo gem install mysql -- --with-mysql-config
  or
$ ruby extconf.rb --with-mysql-config

That worked well, since I’d already installed MySQL and my /etc/mysql.cnf was in its standard location. Hooray!

Configuring RadRails to use the Custom-Built Componentry

Since I switch back and forth between Ruby and Java, I chose to stick with the Eclipse IDE. Aptana has created a nice development suite called RadRails which is highly componentized, and it works rather well for script development as well. Yes, if I don’t use TextMate I’m a heretic, but at some point I’ll hunker down and pony out the bucks for it :)

The install of Eclipse 3.4 Ganymede that I started out with contained several plugins / features from rubypeople.org. As well intended as they were, I ran into several areas of conflict between them and RadRails. I thus chose to remove these plugins from Eclipse, and stability ensued.

However, even after removed, I still have two Eclipse sections for ‘Ruby’. The one for RadRails is the one with fewer sub-sections (also known as ‘the one that looks less like the Java language configuration section’).

Since you’ve custom built your install of Ruby, you’ll want to make the following configuration changes to Eclipse / RadRails:

  • Under Ruby | Interpreters, add a new Generic Ruby interpreter. Its executable should be /usr/bin/local/ruby, and the rest will take care of itself (I didn’t specify any arguments).
  • Under Rails, set up the ‘rails’ and ‘mongrel_rails’ paths to reference the respective binaries in /usr/local/bin, since that’s where all of your installed gems will have been exposed.
  • Under Java | Build Path | Classpath Variables, you’ll want to add GEM_LIB, which should reference /usr/local/lib/ruby/gems/1.8/gems. It seems out of place under ‘Java’, but the IDE was crying out for it loudly.

That should address the majority of the IDE configuration. If anything doesn’t quite work correctly, you may want to examine the steps that I describe below as being ‘optional’, particularly the one where I created a mock Ruby.framework setup.

Optional (?) Configuration

I question whether they’re mandatory or not because this configuration has been stable on my machine for a little while now, and I have a tendency to get very detail-oriented, not all of which turns out to actually be necessary. In the spirit of completeness — yep, there’s detail-oriented for you right there! — I’ll lay out what I have put into play.

I’ve injected ‘/usr/local/bin’ and ‘/usr/local/sbin’ into /etc/paths; that works like a charm.

I consistently install gems as root, or else I end up with account-specific discrepancies driven by each ~/.gems folder. I merely point that out to illustrate that such user-specific directories exists :)

I’ve added the following unnecessary env var:

export GEM_LIB=/usr/local/lib/ruby/gems/1.8/gems

It matches the Classpath Variable you set in Eclipse (above). If nothing else, it’s an easy ‘$’ substitution when I need to go spelunking into gem source code.

There’s been at least once where I have also needed the following env var. It should be configured to point at the expanded source code of your custom Ruby build.

export RUBY_SOURCE_DIR=...

I’ve created the following directory structure:

$ mkdir -p /System/Library/Frameworks/Ruby.framework/Versions/1.8-Current

Therein I have created a ‘usr’ directory structure that matches the one you’ll find in /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr . It’s all just symlinks into the appropriate /usr/local hierarchy. I then co-opted the Current symlink:

$ cd /System/Library/Frameworks/Ruby.framework/Versions
$ ls -l
1.8
1.8-Current
Current -> 1.8
$ rm Current
$ ln -s 1.8-Current Current

Consider that you may need to mimic certain aspects of the default Ruby framework configuration, which is the inverse of the mock framework setup that I just described. Specifically, /usr/local/lib/ruby takes after /System/Library/Frameworks/Ruby.framework/Versions/Current/usr/lib/ruby.

This is why I ended up with both a ‘/usr/local/lib/ruby/site_ruby’ and ‘/usr/local/lib/ruby/vendor_ruby’ subdir on my machine.

The standard location for the ruby executable is often used in a she-bang line for bash scripts. The standard location is:

#!/usr/bin/ruby

Which of course was still pointing at the default OS X Ruby framework. I renamed the existing symlink and replaced it with one to /usr/local/bin/ruby. I did not do this for gem, irb, rdoc (etc.) since I don’t have she-bang needs for them.

In Summary

I hope some of this information is useful to you. I was sitting at Cafe International and setting up RadRails when the HD on my two-week-old MacBook Pro 2008 went into beachball-of-death mode. I had to pick back up from there 2+ weeks later on a fresh laptop, which at least allowed me to keep these copious notes.