4

I'm building a native C extension Ruby gem for generating unique identifiers (found here). I'd like the library to use libuuid if possible (through C extensions) and fall back to a simple Ruby implementation. I currently have both the C and Ruby code for generating the UUID, however I can't figure out how to configure a successful fallback. Any ideas?

Matheus Moreira
  • 17,106
  • 3
  • 68
  • 107
Kevin Sylvestre
  • 37,288
  • 33
  • 152
  • 232

1 Answers1

3

The have_library method has a return value:

Returns whether or not the given entry point func can be found within lib.

So you should be able to do this:

$defs.push('-DUSE_RUBY_UUID') if !have_library('uuid')
create_makefile("identifier")

And then set up your C to use libuuid if USE_RUBY_UUID is not defined and call into the Ruby UUID library if it is defined.

Oddly enough, the have_header and have_func methods in mkmf.rb add macros for you:

# File mkmf.rb, line 840
def have_header(header, preheaders = nil, &b)
  checking_for header do
    if try_header(cpp_include(preheaders)+cpp_include(header), &b)
      $defs.push(format("-DHAVE_%s", header.tr_cpp))
      true
    else
      false
    end
  end
end

but have_library makes you do it yourself.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
  • I would define all the methods in ruby first. Then require the C extension. If the library is found, override some ruby methods. If not found, do nothing. – David Grayson Feb 24 '12 at 16:11
  • @David: That depends on how his existing C is set up. Bypassing Ruby completely and going straight to the C library would be a lot faster and probably a lot more convenient than taking a detour through Ruby's method resolution and marshalling/unmarshalling system. – mu is too short Feb 24 '12 at 17:35