Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions lib/ffi-compiler/loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand Down