diff --git a/lib/ffi-compiler/loader.rb b/lib/ffi-compiler/loader.rb index 08c5fe8..984c3c5 100644 --- a/lib/ffi-compiler/loader.rb +++ b/lib/ffi-compiler/loader.rb @@ -5,24 +5,39 @@ module FFI module Compiler module Loader + # Finds the native extension for the given library name. + # Tries RubyGems extension_dir using the library name as the gem name (best effort), + # then always falls back to the legacy recursive search for compatibility. def self.find(name, start_path = nil) library = Platform.system.map_library_name(name) + + # Try RubyGems extension_dir using name as gem name (best effort) + if defined?(Gem::Specification) + begin + spec = Gem::Specification.find_by_name(name) + if spec && spec.respond_to?(:extension_dir) + ext_dir = spec.extension_dir + ext_path = File.join(ext_dir, library) + return ext_path if File.exist?(ext_path) + end + rescue Gem::MissingSpecError + # Ignore and fall back to legacy search + end + end + + # Legacy search root = false Pathname.new(start_path || caller_path(caller[0])).ascend do |path| Dir.glob("#{path}/**/#{FFI::Platform::ARCH}-#{FFI::Platform::OS}/#{library}") do |f| return f end - Dir.glob("#{path}/**/#{library}") do |f| return f end - break if root - - # Next iteration will be the root of the gem if this is the lib/ dir - stop after that root = File.basename(path) == 'lib' end - raise LoadError.new("cannot find '#{name}' library") + raise LoadError, "cannot find '#{name}' library" end def self.caller_path(line = caller[0])