ruby-on-railsrubyrubygemsbundlernative

Why won't bundle install my local gem w/ extension?


I have a gem I'm developing locally with the following structure:

foo
  ext
   foo
    extconf.rb
    foo.cpp
    foo.h
    etc.cpp
    etc.h
  lib
 foo.gemspec

--- foo.gemspec --

Gem::Specification.new do |s|
  s.name    = "foo"
  s.version = "0.0.2"
  s.author  = "Aemon Cannon"
  s.files = Dir["ext/foo/*.{h,cpp}"] + Dir["lib/**/*"] + Dir['ext/**/extconf.rb']
  s.platform = Gem::Platform::RUBY
  s.require_paths = [ 'lib', 'ext' ]
  s.extensions = Dir['ext/**/extconf.rb']
end

--- ext/foo/extconf.rb ----

require 'mkmf'
$CPPFLAGS += "-std=c++11 -Wno-unused-value "
abort "missing libz" unless  have_library("z")
abort "missing c++ standard library" unless have_library("stdc++")
create_makefile "foo"

I use gem build foo to build a gem, which seems to build successfully, then add the gem to my rails app under vendor/gems. I mention it in my Gemfile thusly:

gem 'foo', '0.0.2', :path => 'vendor/gems'

When I 'bundle install' it says:

Using foo (0.0.2) from source at vendor/gems

BUT it does not appear to build the extension, and now the gem has been deleted from vendor/gems and does not appear in vendor/cache.

gem install foo-0.0.1.gem installs the gem properly, building the native extension successfully.

Rails version 3.2.x
Bundler 1.5.x


Solution

  • The Bundler docs for using :path say:

    Unlike :git, bundler does not compile C extensions for gems specified as paths.

    My understanding is that :path is mainly intended for using with gems that you are actively developing, and Bundler expects “ready to go” code at that location. If you want to use :path, you should compile the extension manually first (perhaps using rake-compiler).