module FFI::Library

def ffi_lib(*names)

Raises:
  • (LoadError) - if a library cannot be opened

Returns:
  • (Array) -

Parameters:
  • names (Array) -- names of libraries to load
def ffi_lib(*names)
  raise LoadError.new("library names list must not be empty") if names.empty?
  lib_flags = defined?(@ffi_lib_flags) ? @ffi_lib_flags : FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_LOCAL
  ffi_libs = names.map do |name|
    if name == FFI::CURRENT_PROCESS
      FFI::DynamicLibrary.open(nil, FFI::DynamicLibrary::RTLD_LAZY | FFI::DynamicLibrary::RTLD_LOCAL)
    else
      libnames = (name.is_a?(::Array) ? name : [ name ]).map { |n| [ n, FFI.map_library_name(n) ].uniq }.flatten.compact
      lib = nil
      errors = {}
      libnames.each do |libname|
        begin
          orig = libname
          lib = FFI::DynamicLibrary.open(libname, lib_flags)
          break if lib
        rescue Exception => ex
          ldscript = false
          if ex.message =~ /(([^ \t()])+\.so([^ \t:()])*):([ \t])*(invalid ELF header|file too short|invalid file format)/
            if File.read($1) =~ /(?:GROUP|INPUT) *\( *([^ \)]+)/
              libname = $1
              ldscript = true
            end
          end
          # TODO better library lookup logic
          unless libname.to_s.start_with?("/")
            path = ['/usr/lib/','/usr/local/lib/'].find do |pth|
              File.exist?(pth + libname)
            end
            if path
              libname = path + libname
              retry
            end
          end
          if ldscript
            retry
          else
            libr = (orig == libname ? orig : "#{orig} #{libname}")
            errors[libr] = ex
          end
        end
      end
      if lib.nil?
        raise LoadError.new(errors.values.join(".\n"))
      end
      # return the found lib
      lib
    end
  end
  @ffi_libs = ffi_libs
end