class FFI::DynamicLibrary
def self.load_library(name, flags)
def self.load_library(name, flags) if name == FFI::CURRENT_PROCESS FFI::DynamicLibrary.open(nil, RTLD_LAZY | RTLD_LOCAL) else flags ||= RTLD_LAZY | RTLD_LOCAL libnames = (name.is_a?(::Array) ? name : [name]) libnames = libnames.map(&:to_s).map { |n| [n, FFI.map_library_name(n)].uniq }.flatten.compact errors = [] libnames.each do |libname| lib = try_load(libname, flags, errors) return lib if lib unless libname.start_with?("/") SEARCH_PATH.each do |prefix| path = "#{prefix}/#{libname}" if File.exist?(path) lib = try_load(path, flags, errors) return lib if lib end end end end raise LoadError, [*errors, SEARCH_PATH_MESSAGE].join(".\n") end end
def self.try_load(libname, flags, errors)
def self.try_load(libname, flags, errors) begin lib = FFI::DynamicLibrary.open(libname, flags) return lib if lib # LoadError for C ext & JRuby, RuntimeError for TruffleRuby rescue LoadError, RuntimeError => ex if ex.message =~ /(([^ \t()])+\.so([^ \t:()])*):([ \t])*(invalid ELF header|file too short|invalid file format)/ if File.binread($1) =~ /(?:GROUP|INPUT) *\( *([^ \)]+)/ return try_load($1, flags, errors) end end errors << ex nil end end