Module: PdfOxide::FFI::Library

Defined in:
lib/pdf_oxide/ffi/library.rb

Overview

Loads the native PDF Oxide library with cross-platform support

Class Method Summary collapse

Class Method Details

.find_libraryArray<String>

Finds library for current platform

Returns:

  • (Array<String>)

    Library names to try loading



12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/pdf_oxide/ffi/library.rb', line 12

def self.find_library
  case RbConfig::CONFIG['host_os']
  when /darwin/
    %w[libpdf_oxide.dylib libpdf_oxide.0.dylib]
  when /linux/
    %w[libpdf_oxide.so libpdf_oxide.so.0]
  when /mswin|mingw/
    %w[pdf_oxide.dll libpdf_oxide.dll]
  else
    raise UnsupportedPlatformError, "Unsupported OS: #{RbConfig::CONFIG['host_os']}"
  end
end

.find_library_pathObject



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/pdf_oxide/ffi/library.rb', line 30

def self.find_library_path
  # Try to find in standard locations
  find_library.each do |lib_name|
    # Native-gem layout: cdylib staged inside the gem at
    # ext/pdf_oxide/ during platform-specific gem packaging.  This is
    # the path bundled into platform-tagged gems and is the first
    # thing the loader should try when installed from a native gem.
    gem_native = File.expand_path("../../../ext/pdf_oxide/#{lib_name}", __dir__)
    return gem_native if File.exist?(gem_native)

    # Try system paths
    result = system_find_library(lib_name)
    return result if result

    # Try relative to gem (dev-checkout layouts)
    relative_paths = [
      File.expand_path("../../target/release/#{lib_name}", __dir__),
      File.expand_path("../../target/debug/#{lib_name}", __dir__),
      File.expand_path("../../../target/release/#{lib_name}", __dir__),
      File.expand_path("../../../target/debug/#{lib_name}", __dir__),
      lib_name
    ]

    relative_paths.each do |path|
      return path if File.exist?(path)
    end
  end

  # Fallback to library name (system will search)
  find_library.first
end

.homebrew_find(lib_name) ⇒ Object



82
83
84
85
86
87
88
89
90
# File 'lib/pdf_oxide/ffi/library.rb', line 82

def self.homebrew_find(lib_name)
  output = `brew --prefix 2>/dev/null`.strip
  return nil if output.empty?

  path = File.join(output, 'lib', lib_name)
  File.exist?(path) ? path : nil
rescue StandardError
  nil
end

.ldconfig_search(lib_name) ⇒ Object



73
74
75
76
77
78
79
80
# File 'lib/pdf_oxide/ffi/library.rb', line 73

def self.ldconfig_search(lib_name)
  output = `ldconfig -p 2>/dev/null | grep #{lib_name}`.strip
  return nil if output.empty?

  output.split("\n").first&.split('=>')&.last&.strip
rescue StandardError
  nil
end

.library_pathString

Returns Path to native library.

Returns:

  • (String)

    Path to native library



26
27
28
# File 'lib/pdf_oxide/ffi/library.rb', line 26

def self.library_path
  @library_path ||= find_library_path
end

.system_find_library(lib_name) ⇒ Object



62
63
64
65
66
67
68
69
70
71
# File 'lib/pdf_oxide/ffi/library.rb', line 62

def self.system_find_library(lib_name)
  case RbConfig::CONFIG['host_os']
  when /darwin/
    ldconfig_search(lib_name) || homebrew_find(lib_name)
  when /linux/
    ldconfig_search(lib_name)
  when /mswin|mingw/
    windows_find(lib_name)
  end
end

.windows_find(_lib_name) ⇒ Object



92
93
94
95
# File 'lib/pdf_oxide/ffi/library.rb', line 92

def self.windows_find(_lib_name)
  # Windows DLL search path is handled by system
  nil
end