linkage_checker: resolve some variable install names on macOS

This commit is contained in:
Gabriel Gerlero 2023-06-20 16:42:13 -03:00
parent 4cfe70ce50
commit 15a0c7fd7d
3 changed files with 35 additions and 7 deletions

View File

@ -103,7 +103,7 @@ class Keg
def each_linkage_for(file, linkage_type, &block)
links = file.method(linkage_type)
.call
.call(resolve_variable_references: false)
.grep_v(/^@(loader_|executable_|r)path/)
links.each(&block)
end

View File

@ -31,6 +31,7 @@ class LinkageChecker
@unwanted_system_dylibs = []
@version_conflict_deps = []
@files_missing_rpaths = []
@executable_path_dylibs = []
check_dylibs(rebuild_cache: rebuild_cache)
end
@ -39,13 +40,14 @@ class LinkageChecker
display_items "System libraries", @system_dylibs
display_items "Homebrew libraries", @brewed_dylibs
display_items "Indirect dependencies with linkage", @indirect_deps
display_items "Variable-referenced libraries", @variable_dylibs
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
alias generic_display_normal_output display_normal_output
private :generic_display_normal_output
@ -74,6 +76,7 @@ class LinkageChecker
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
alias generic_display_test_output display_test_output
private :generic_display_test_output
@ -85,7 +88,7 @@ class LinkageChecker
issues = [@broken_deps, unexpected_broken_dylibs]
if test
issues += [@unwanted_system_dylibs, @version_conflict_deps, unexpected_present_dylibs]
issues += [@undeclared_deps, @files_missing_rpaths] if strict
issues += [@undeclared_deps, @files_missing_rpaths, @executable_path_dylibs] if strict
end
issues.any?(&:present?)
end
@ -182,9 +185,12 @@ class LinkageChecker
checked_dylibs << dylib
if dylib.start_with? "@"
if dylib.start_with? "@rpath"
@variable_dylibs << dylib
next
elsif dylib.start_with?("@executable_path") && !Pathname(file).binary_executable?
@executable_path_dylibs << dylib
next
end
begin

View File

@ -9,7 +9,7 @@ require "macho"
module MachOShim
extend Forwardable
delegate [:dylib_id, :rpaths] => :macho
delegate [:dylib_id] => :macho
def macho
@macho ||= MachO.open(to_s)
@ -79,10 +79,32 @@ module MachOShim
macho.write!
end
def dynamically_linked_libraries(except: :none)
def dynamically_linked_libraries(except: :none, resolve_variable_references: true)
lcs = macho.dylib_load_commands.reject { |lc| lc.type == except }
lcs.map(&:name).map(&:to_s).uniq
names = lcs.map(&:name).map(&:to_s).uniq
names.map! { |name| resolve_variable_name(name) } if resolve_variable_references
names
end
def rpaths(resolve_variable_references: true)
names = macho.rpaths.uniq
names.map! { |name| resolve_variable_name(name) } if resolve_variable_references
names
end
def resolve_variable_name(name)
if name.start_with? "@loader_path"
Pathname(name.sub("@loader_path", dirname)).cleanpath.to_s
elsif name.start_with?("@executable_path") && binary_executable?
Pathname(name.sub("@executable_path", dirname)).cleanpath.to_s
else
name
end
end
def archs