class FFI::DynamicLibrary

Constants

SEARCH_PATH
SEARCH_PATH_MESSAGE

Private Class Methods

load_library(name, flags) click to toggle source
# File lib/ffi/dynamic_library.rb, line 69
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
try_load(libname, flags, errors) click to toggle source
# File lib/ffi/dynamic_library.rb, line 99
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