Merge pull request #3940 from maxim-belkin/fix-undeclared
linkage_checker: fix detection of broken dependencies and missing libraries
This commit is contained in:
commit
de82d3a945
@ -3,7 +3,7 @@ require "formula"
|
|||||||
|
|
||||||
class LinkageChecker
|
class LinkageChecker
|
||||||
attr_reader :keg, :formula
|
attr_reader :keg, :formula
|
||||||
attr_reader :brewed_dylibs, :system_dylibs, :broken_dylibs, :variable_dylibs
|
attr_reader :brewed_dylibs, :system_dylibs, :broken_dylibs, :broken_deps, :variable_dylibs
|
||||||
attr_reader :undeclared_deps, :unnecessary_deps, :reverse_links
|
attr_reader :undeclared_deps, :unnecessary_deps, :reverse_links
|
||||||
|
|
||||||
def initialize(keg, formula = nil)
|
def initialize(keg, formula = nil)
|
||||||
@ -11,7 +11,8 @@ class LinkageChecker
|
|||||||
@formula = formula || resolve_formula(keg)
|
@formula = formula || resolve_formula(keg)
|
||||||
@brewed_dylibs = Hash.new { |h, k| h[k] = Set.new }
|
@brewed_dylibs = Hash.new { |h, k| h[k] = Set.new }
|
||||||
@system_dylibs = Set.new
|
@system_dylibs = Set.new
|
||||||
@broken_dylibs = Set.new
|
@broken_dylibs = []
|
||||||
|
@broken_deps = Hash.new { |h, k| h[k] = [] }
|
||||||
@variable_dylibs = Set.new
|
@variable_dylibs = Set.new
|
||||||
@indirect_deps = []
|
@indirect_deps = []
|
||||||
@undeclared_deps = []
|
@undeclared_deps = []
|
||||||
@ -20,7 +21,13 @@ class LinkageChecker
|
|||||||
check_dylibs
|
check_dylibs
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def dylib_to_dep(dylib)
|
||||||
|
dylib =~ %r{#{Regexp.escape(HOMEBREW_PREFIX)}/(opt|Cellar)/([\w+-.@]+)/}
|
||||||
|
Regexp.last_match(2)
|
||||||
|
end
|
||||||
|
|
||||||
def check_dylibs
|
def check_dylibs
|
||||||
|
checked_dylibs = Set.new
|
||||||
@keg.find do |file|
|
@keg.find do |file|
|
||||||
next if file.symlink? || file.directory?
|
next if file.symlink? || file.directory?
|
||||||
next unless file.dylib? || file.binary_executable? || file.mach_o_bundle?
|
next unless file.dylib? || file.binary_executable? || file.mach_o_bundle?
|
||||||
@ -29,6 +36,7 @@ class LinkageChecker
|
|||||||
# when checking for broken linkage
|
# when checking for broken linkage
|
||||||
file.dynamically_linked_libraries(except: :LC_LOAD_WEAK_DYLIB).each do |dylib|
|
file.dynamically_linked_libraries(except: :LC_LOAD_WEAK_DYLIB).each do |dylib|
|
||||||
@reverse_links[dylib] << file
|
@reverse_links[dylib] << file
|
||||||
|
next if checked_dylibs.include? dylib
|
||||||
if dylib.start_with? "@"
|
if dylib.start_with? "@"
|
||||||
@variable_dylibs << dylib
|
@variable_dylibs << dylib
|
||||||
else
|
else
|
||||||
@ -38,7 +46,11 @@ class LinkageChecker
|
|||||||
@system_dylibs << dylib
|
@system_dylibs << dylib
|
||||||
rescue Errno::ENOENT
|
rescue Errno::ENOENT
|
||||||
next if harmless_broken_link?(dylib)
|
next if harmless_broken_link?(dylib)
|
||||||
|
if (dep = dylib_to_dep(dylib))
|
||||||
|
@broken_deps[dep] |= [dylib]
|
||||||
|
else
|
||||||
@broken_dylibs << dylib
|
@broken_dylibs << dylib
|
||||||
|
end
|
||||||
else
|
else
|
||||||
tap = Tab.for_keg(owner).tap
|
tap = Tab.for_keg(owner).tap
|
||||||
f = if tap.nil? || tap.core_tap?
|
f = if tap.nil? || tap.core_tap?
|
||||||
@ -49,6 +61,7 @@ class LinkageChecker
|
|||||||
@brewed_dylibs[f] << dylib
|
@brewed_dylibs[f] << dylib
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
checked_dylibs << dylib
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -83,6 +96,8 @@ class LinkageChecker
|
|||||||
next true if Formula[name].bin.directory?
|
next true if Formula[name].bin.directory?
|
||||||
@brewed_dylibs.keys.map { |x| x.split("/").last }.include?(name)
|
@brewed_dylibs.keys.map { |x| x.split("/").last }.include?(name)
|
||||||
end
|
end
|
||||||
|
missing_deps = @broken_deps.values.flatten.map { |d| dylib_to_dep(d) }
|
||||||
|
unnecessary_deps -= missing_deps
|
||||||
[indirect_deps, undeclared_deps, unnecessary_deps]
|
[indirect_deps, undeclared_deps, unnecessary_deps]
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -104,6 +119,7 @@ class LinkageChecker
|
|||||||
display_items "Indirect dependencies with linkage", @indirect_deps
|
display_items "Indirect dependencies with linkage", @indirect_deps
|
||||||
display_items "Variable-referenced libraries", @variable_dylibs
|
display_items "Variable-referenced libraries", @variable_dylibs
|
||||||
display_items "Missing libraries", @broken_dylibs
|
display_items "Missing libraries", @broken_dylibs
|
||||||
|
display_items "Broken dependencies", @broken_deps
|
||||||
display_items "Undeclared dependencies with linkage", @undeclared_deps
|
display_items "Undeclared dependencies with linkage", @undeclared_deps
|
||||||
display_items "Dependencies with no linkage", @unnecessary_deps
|
display_items "Dependencies with no linkage", @unnecessary_deps
|
||||||
end
|
end
|
||||||
@ -123,7 +139,8 @@ class LinkageChecker
|
|||||||
|
|
||||||
def display_test_output
|
def display_test_output
|
||||||
display_items "Missing libraries", @broken_dylibs
|
display_items "Missing libraries", @broken_dylibs
|
||||||
display_items "Possible unnecessary dependencies", @unnecessary_deps
|
display_items "Broken dependencies", @broken_deps
|
||||||
|
display_items "Dependencies with no linkage", @unnecessary_deps
|
||||||
puts "No broken dylib links" if @broken_dylibs.empty?
|
puts "No broken dylib links" if @broken_dylibs.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -158,8 +175,8 @@ class LinkageChecker
|
|||||||
return if things.empty?
|
return if things.empty?
|
||||||
puts "#{label}:"
|
puts "#{label}:"
|
||||||
if things.is_a? Hash
|
if things.is_a? Hash
|
||||||
things.sort.each do |list_label, list|
|
things.keys.sort.each do |list_label|
|
||||||
list.sort.each do |item|
|
things[list_label].sort.each do |item|
|
||||||
puts " #{item} (#{list_label})"
|
puts " #{item} (#{list_label})"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user