Engineering in Focus

the Fandor engineering blog

Installing gherkin from a git repository with bundler

leave a comment »

I just installed our Rails application on new hardware running Ubuntu 11.10. Everything went smoothly except for one gem: gherkin 1.0.30. (We’re on Rails 2 for now, so we’re using cucumber 0.8.0, which uses gherkin 1.) bundle install resulted in this error:

/usr/lib/ruby/vendor_ruby/1.8/rubygems/installer.rb:533:in `build_extensions': ERROR: Failed to build gem native extension. (Gem::Installer::ExtensionBuildError)
/usr/bin/ruby1.8 extconf.rb
gcc -I. -I. -I/usr/lib/ruby/1.8/x86_64-linux -I. -fPIC -fno-strict-aliasing -g -g -O2 -fPIC -O0 -Wall -Werror -c gherkin_lexer_ar.c
/Users/aslakhellesoy/scm/gherkin/tasks/../ragel/i18n/ar.c.rl: In function ‘CLexer_scan’:
/Users/aslakhellesoy/scm/gherkin/tasks/../ragel/i18n/ar.c.rl:198:29: error: the comparison will always evaluate as ‘true’ for the address of ‘raise_lexer_error’ will never be NULL [-Werror=address]
cc1: all warnings being treated as errors

There wasn’t a serious problem with the native code, but the gcc I was using (4.6.1) had found a warning that earlier versions presumably had not — or 1.0.30 wouldn’t have compiled with -Werror.

The fix was easy; just remove -Werror from the compilation. (It’s in a rake task that compiles C code generated by the Ragel state machine compiler.) The trick was setting up the modified gem so bundler could use it.

The only way to install a modified version of a gem with native extensions that you don’t own is to use Gemfile’s :git option. (There’s also a :path option which installs a gem from a path on your filesystem, but it doesn’t compile native extensions.) So, in the including application’s Gemfile, we have

gem 'gherkin', '1.0.30', :git => '', :branch => 'v1.0.30-no-Werror'

pointing at the modified fork of gherkin.

What exactly needed to be modified? Although bundler can fake up a .gemspec if none is present, that .gemspec won’t compile native extensions. For native extensions to be compiled, a gem installed with :git must have its own gemspec which refers to the extensions. The native code itself must also be present in the gem, which (being generated) it is not in the original gherkin repo.

So I installed Ragel (with MacPorts) and the jeweler and rake-compiler gems, ran rake gems:posix to generate the native code and the .gemspec, removed the .gitignore entries that ignored what I’d just generated, and added the generated code to my fork. Now bundle install gets the native code from git and compiles it as it would if it came from a packaged gem.

You can look at the fork to see the details. I’m not promising that it’ll be there forever, so if you need to solve this problem too, make your own fork.

This is probably the most trouble I ever had making a seven-character fix in a single file. Anything to keep the films rolling!

About these ads

Occasionally, some of your visitors may see an advertisement here.

Tell me more | Dismiss this message

Written by fandave Edit

September 12, 2011 at 20:12

Posted in Rails, Ruby

Leave a Reply

Skip to toolbar Log Out