Question

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?

Was it helpful?

Solution 2

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top