5

I'm writing a gem, that includes a C extension. Usually when I write a gem, I follow a process of TDD, where I'll write a failing spec and then work on the code until it passes, etc etc...

With my C extension in "ext/mygem/mygem.c" and a valid extconf.rb configured in the gemspec's "extensions", how do I run my specs and still have my C extension loaded? When I make changes to the C code, what steps do I need to take to recompile the code?

This is probably a stupid question, but typing 'bundle install' from inside my gem's development source tree does not build any native extensions. When I manually run ruby ext/mygem/extconf.rb I do get a Makefile (in the root of the whole project) and when I then run make, I do get a shared object (again, in the root of the whole project). I must be following the wrong workflow, since I understand that the .so is supposed to be placed under lib/. Unless I'm just supposed to do that by hand during development?

Matheus Moreira
  • 17,106
  • 3
  • 68
  • 107
d11wtq
  • 34,788
  • 19
  • 120
  • 195

2 Answers2

4

The solution I went with in the end was to use rake-compiler, on github:

https://github.com/luislavena/rake-compiler

You just add a rake task to do the compile (documented in the README), then make the 'spec' task(s) depend on that build phase.

d11wtq
  • 34,788
  • 19
  • 120
  • 195
4

Don't know whether it's the 'right' way but the way I've done this in the past is

Add

$: << File.dirname(__FILE__) + '/../ext'

To my spec helper

And then have a rakefile that looks like

require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new('spec')
task :build do
  Dir.chdir('ext') do
    output = `ruby extconf.rb`
    raise output unless $? == 0
    output = `make`
    raise output unless $? == 0
  end
end

task :spec => :build

So rake spec builds the c code for me each time, with the built library existing in ext/. The change to the load path ensures that this copy is loaded. This github repo illustrates this.

Frederick Cheung
  • 83,189
  • 8
  • 152
  • 174
  • 1
    Thanks :) I was just coming back here to post that I've found "rake-compile" on github. You basically add it as a development dependency, then in your Rakefile you can tell it what extensions to build. It will run extconf.rb, make, then copy the lib and cleanup. https://github.com/luislavena/rake-compiler – d11wtq Mar 30 '12 at 14:54