Class: LinkageChecker Private

Inherits:
Object show all
Defined in:
extend/os/mac/linkage_checker.rb,
extend/os/linux/linkage_checker.rb,
linkage_checker.rb

Overview

This class is part of a private API. This class may only be used in the Homebrew/brew repository. Third parties should avoid using this class if possible, as it may be removed or changed without warning.

Check for broken/missing linkage in a formula’s keg.

Constant Summary collapse

SYSTEM_LIBRARY_ALLOWLIST =

Libraries provided by glibc and gcc.

%w[
  ld-linux-x86-64.so.2
  ld-linux-aarch64.so.1
  libanl.so.1
  libatomic.so.1
  libc.so.6
  libdl.so.2
  libm.so.6
  libmvec.so.1
  libnss_files.so.2
  libpthread.so.0
  libresolv.so.2
  librt.so.1
  libthread_db.so.1
  libutil.so.1
  libgcc_s.so.1
  libgomp.so.1
  libstdc++.so.6
  libquadmath.so.0
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(keg, formula = nil, cache_db:, rebuild_cache: false) ⇒ LinkageChecker

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Returns a new instance of LinkageChecker.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'linkage_checker.rb', line 15

def initialize(keg, formula = nil, cache_db:, rebuild_cache: false)
  @keg = keg
  @formula = formula || resolve_formula(keg)
  @store = LinkageCacheStore.new(keg.to_s, cache_db)

  @system_dylibs    = Set.new
  @broken_dylibs    = Set.new
  @unexpected_broken_dylibs = nil
  @unexpected_present_dylibs = nil
  @variable_dylibs  = Set.new
  @brewed_dylibs    = Hash.new { |h, k| h[k] = Set.new }
  @reverse_links    = Hash.new { |h, k| h[k] = Set.new }
  @broken_deps      = Hash.new { |h, k| h[k] = [] }
  @indirect_deps    = []
  @undeclared_deps  = []
  @unnecessary_deps = []
  @unwanted_system_dylibs = []
  @version_conflict_deps = []
  @files_missing_rpaths = []
  @executable_path_dylibs = []

  check_dylibs(rebuild_cache: rebuild_cache)
end

Instance Attribute Details

#formulaObject (readonly)

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



13
14
15
# File 'linkage_checker.rb', line 13

def formula
  @formula
end

#kegObject (readonly)

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



13
14
15
# File 'linkage_checker.rb', line 13

def keg
  @keg
end

#storeObject (readonly)

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



13
14
15
# File 'linkage_checker.rb', line 13

def store
  @store
end

#undeclared_depsObject (readonly)

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



13
14
15
# File 'linkage_checker.rb', line 13

def undeclared_deps
  @undeclared_deps
end

Instance Method Details

#broken_dylibs_with_expectationsObject

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



120
121
122
123
124
125
126
127
128
129
130
# File 'linkage_checker.rb', line 120

def broken_dylibs_with_expectations
  output = {}
  @broken_dylibs.each do |broken_lib|
    output[broken_lib] = if unexpected_broken_dylibs.include? broken_lib
      ["unexpected"]
    else
      ["expected"]
    end
  end
  output
end

#broken_library_linkage?(test: false, strict: false) ⇒ Boolean

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.

Parameters:

  • test (Boolean) (defaults to: false)
  • strict (Boolean) (defaults to: false)

Returns:

  • (Boolean)

Raises:

  • (ArgumentError)


81
82
83
84
85
86
87
88
89
90
# File 'linkage_checker.rb', line 81

def broken_library_linkage?(test: false, strict: false)
  raise ArgumentError, "Strict linkage checking requires test mode to be enabled." if strict && !test

  issues = [@broken_deps, unexpected_broken_dylibs]
  if test
    issues += [@unwanted_system_dylibs, @version_conflict_deps, unexpected_present_dylibs]
    issues += [@undeclared_deps, @files_missing_rpaths, @executable_path_dylibs] if strict
  end
  issues.any?(&:present?)
end

#display_normal_outputObject

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'linkage_checker.rb', line 39

def display_normal_output
  display_items "System libraries", @system_dylibs
  display_items "Homebrew libraries", @brewed_dylibs
  display_items "Indirect dependencies with linkage", @indirect_deps
  display_items "@rpath-referenced libraries", @variable_dylibs
  display_items "Missing libraries", @broken_dylibs
  display_items "Broken dependencies", @broken_deps
  display_items "Undeclared dependencies with linkage", @undeclared_deps
  display_items "Dependencies with no linkage", @unnecessary_deps
  display_items "Unwanted system libraries", @unwanted_system_dylibs
  display_items "Files with missing rpath", @files_missing_rpaths
  display_items "@executable_path references in libraries", @executable_path_dylibs
end

#display_reverse_outputObject

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'linkage_checker.rb', line 53

def display_reverse_output
  return if @reverse_links.empty?

  sorted = @reverse_links.sort
  sorted.each do |dylib, files|
    puts dylib
    files.each do |f|
      unprefixed = f.to_s.delete_prefix "#{keg}/"
      puts "  #{unprefixed}"
    end
    puts if dylib != sorted.last.first
  end
end

#display_test_output(puts_output: true, strict: false) ⇒ Object

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



67
68
69
70
71
72
73
74
75
76
77
78
# File 'linkage_checker.rb', line 67

def display_test_output(puts_output: true, strict: false)
  display_items "Missing libraries", broken_dylibs_with_expectations, puts_output: puts_output
  display_items "Unused missing linkage information", unexpected_present_dylibs, puts_output: puts_output
  display_items "Broken dependencies", @broken_deps, puts_output: puts_output
  display_items "Unwanted system libraries", @unwanted_system_dylibs, puts_output: puts_output
  display_items "Conflicting libraries", @version_conflict_deps, puts_output: puts_output
  return unless strict

  display_items "Undeclared dependencies with linkage", @undeclared_deps, puts_output: puts_output
  display_items "Files with missing rpath", @files_missing_rpaths, puts_output: puts_output
  display_items "@executable_path references in libraries", @executable_path_dylibs, puts_output: puts_output
end

#unexpected_broken_dylibsObject

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'linkage_checker.rb', line 92

def unexpected_broken_dylibs
  return @unexpected_broken_dylibs if @unexpected_broken_dylibs

  @unexpected_broken_dylibs = @broken_dylibs.reject do |broken_lib|
    @formula.class.allowed_missing_libraries.any? do |allowed_missing_lib|
      case allowed_missing_lib
      when Regexp
        allowed_missing_lib.match? broken_lib
      when String
        broken_lib.include? allowed_missing_lib
      end
    end
  end
end

#unexpected_present_dylibsObject

This method is part of a private API. This method may only be used in the Homebrew/brew repository. Third parties should avoid using this method if possible, as it may be removed or changed without warning.



107
108
109
110
111
112
113
114
115
116
117
118
# File 'linkage_checker.rb', line 107

def unexpected_present_dylibs
  @unexpected_present_dylibs ||= @formula.class.allowed_missing_libraries.reject do |allowed_missing_lib|
    @broken_dylibs.any? do |broken_lib|
      case allowed_missing_lib
      when Regexp
        allowed_missing_lib.match? broken_lib
      when String
        broken_lib.include? allowed_missing_lib
      end
    end
  end
end