2019-04-19 15:38:03 +09:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								# frozen_string_literal: true
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-07 20:41:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								require "keg"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								require "formula"
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-06 12:07:57 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								require "linkage_cache_store"
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-07 20:41:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								class LinkageChecker
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-01 13:26:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  attr_reader :undeclared_deps
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-29 19:57:39 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  def initialize(keg, formula = nil, cache_db:, rebuild_cache: false)
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-07 20:41:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    @keg = keg
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-14 13:14:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    @formula = formula || resolve_formula(keg)
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-29 19:57:39 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    @store = LinkageCacheStore.new(keg.to_s, cache_db)
							 | 
						
					
						
							
								
									
										
										
										
											2018-05-21 16:15:52 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-01 13:26:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    @system_dylibs    = Set.new
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    @broken_dylibs    = Set.new
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    @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 = []
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-05 15:29:42 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    @unwanted_system_dylibs = []
							 | 
						
					
						
							
								
									
										
										
										
											2018-08-27 10:12:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    @version_conflict_deps = []
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-01 13:26:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-06 13:27:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    check_dylibs(rebuild_cache: rebuild_cache)
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-16 17:37:59 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-24 09:52:51 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  def display_normal_output
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-01 13:26:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    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 "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
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-05 15:29:42 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    display_items "Unwanted system libraries", @unwanted_system_dylibs
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-24 09:52:51 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  def display_reverse_output
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-01 13:26:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    return if @reverse_links.empty?
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-02 20:58:34 +05:30
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    sorted = @reverse_links.sort
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    sorted.each do |dylib, files|
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-24 09:52:51 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      puts dylib
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      files.each do |f|
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-15 00:04:01 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        unprefixed = f.to_s.delete_prefix "#{keg}/"
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-24 09:52:51 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        puts "  #{unprefixed}"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      end
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-01 13:26:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      puts if dylib != sorted.last.first
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-24 09:52:51 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  def display_test_output(puts_output: true)
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-01 13:26:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    display_items "Missing libraries", @broken_dylibs, puts_output: puts_output
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    display_items "Broken dependencies", @broken_deps, puts_output: puts_output
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-05 15:29:42 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    display_items "Unwanted system libraries", @unwanted_system_dylibs, puts_output: puts_output
							 | 
						
					
						
							
								
									
										
										
										
											2018-08-27 10:12:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    display_items "Conflicting libraries", @version_conflict_deps, puts_output: puts_output
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-24 09:52:51 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    puts "No broken library linkage" unless broken_library_linkage?
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  def broken_library_linkage?
							 | 
						
					
						
							
								
									
										
										
										
											2018-08-27 10:12:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    !@broken_dylibs.empty? ||
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      !@broken_deps.empty? ||
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-05 15:29:42 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      !@unwanted_system_dylibs.empty? ||
							 | 
						
					
						
							
								
									
										
										
										
											2018-08-27 10:12:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      !@version_conflict_deps.empty?
							 | 
						
					
						
							
								
									
										
										
										
											2018-05-06 15:55:33 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-24 09:52:51 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  private
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-24 16:49:51 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  attr_reader :keg, :formula, :store
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-24 09:52:51 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-18 18:52:12 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  def dylib_to_dep(dylib)
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-20 12:30:14 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    dylib =~ %r{#{Regexp.escape(HOMEBREW_PREFIX)}/(opt|Cellar)/([\w+-.@]+)/}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    Regexp.last_match(2)
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-18 18:52:12 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-06 13:27:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  def check_dylibs(rebuild_cache:)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    keg_files_dylibs = nil
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if rebuild_cache
							 | 
						
					
						
							
								
									
										
										
										
											2018-10-13 08:22:51 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      store&.delete!
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-06 13:27:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    else
							 | 
						
					
						
							
								
									
										
										
										
											2018-10-13 08:22:51 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      keg_files_dylibs = store&.fetch(:keg_files_dylibs)
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-06 13:27:59 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-01 13:26:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    keg_files_dylibs_was_empty = false
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    keg_files_dylibs ||= {}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if keg_files_dylibs.empty?
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      keg_files_dylibs_was_empty = true
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      @keg.find do |file|
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        next if file.symlink? || file.directory?
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        next if !file.dylib? && !file.binary_executable? && !file.mach_o_bundle?
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-01 13:26:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        # weakly loaded dylibs may not actually exist on disk, so skip them
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        # when checking for broken linkage
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        keg_files_dylibs[file] =
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          file.dynamically_linked_libraries(except: :LC_LOAD_WEAK_DYLIB)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    end
							 | 
						
					
						
							
								
									
										
										
										
											2018-01-16 17:37:59 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-17 00:15:51 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    checked_dylibs = Set.new
							 | 
						
					
						
							
								
									
										
										
										
											2016-11-07 19:37:52 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-01 13:26:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    keg_files_dylibs.each do |file, dylibs|
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      dylibs.each do |dylib|
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-07 20:41:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        @reverse_links[dylib] << file
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-01 13:26:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-17 00:15:51 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        next if checked_dylibs.include? dylib
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-01 13:26:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        checked_dylibs << dylib
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-07 20:41:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        if dylib.start_with? "@"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          @variable_dylibs << dylib
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-01 13:26:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								          next
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        begin
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          owner = Keg.for Pathname.new(dylib)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        rescue NotAKegError
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          @system_dylibs << dylib
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        rescue Errno::ENOENT
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          next if harmless_broken_link?(dylib)
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-01 13:26:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								          if (dep = dylib_to_dep(dylib))
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            @broken_deps[dep] |= [dylib]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            @broken_dylibs << dylib
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          end
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-07 20:41:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        else
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-01 13:26:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								          tap = Tab.for_keg(owner).tap
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          f = if tap.nil? || tap.core_tap?
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            owner.name
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-07 20:41:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          else
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-01 13:26:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            "#{tap}/#{owner.name}"
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-07 20:41:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								          end
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-01 13:26:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								          @brewed_dylibs[f] << dylib
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-07 20:41:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-05-22 14:46:14 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    if formula
							 | 
						
					
						
							
								
									
										
										
										
											2018-08-27 10:12:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      @indirect_deps, @undeclared_deps, @unnecessary_deps,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        @version_conflict_deps = check_formula_deps
							 | 
						
					
						
							
								
									
										
										
										
											2018-05-22 14:46:14 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    end
							 | 
						
					
						
							
								
									
										
										
										
											2018-06-01 13:26:45 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return unless keg_files_dylibs_was_empty
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    store&.update!(keg_files_dylibs: keg_files_dylibs)
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-14 13:14:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  end
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-05 15:29:42 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  alias generic_check_dylibs check_dylibs
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-14 13:14:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-08-27 10:12:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  def check_formula_deps
							 | 
						
					
						
							
								
									
										
										
										
											2016-09-11 17:49:27 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    filter_out = proc do |dep|
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      next true if dep.build?
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      next false unless dep.optional? || dep.recommended?
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-09-11 17:49:27 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      formula.build.without?(dep)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    end
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-25 10:26:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-28 17:24:43 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    declared_deps_full_names = formula.deps
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                      .reject { |dep| filter_out.call(dep) }
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                                      .map(&:name)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    declared_deps_names = declared_deps_full_names.map do |dep|
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      dep.split("/").last
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    end
							 | 
						
					
						
							
								
									
										
										
										
											2018-07-16 16:46:39 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    recursive_deps = formula.runtime_formula_dependencies(undeclared: false)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								                            .map(&:name)
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-25 10:26:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-10 08:34:23 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    indirect_deps = []
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    undeclared_deps = []
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    @brewed_dylibs.each_key do |full_name|
							 | 
						
					
						
							
								
									
										
										
										
											2016-09-11 17:49:27 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      name = full_name.split("/").last
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-10 08:34:23 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      next if name == formula.name
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-10 08:34:23 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      if recursive_deps.include?(name)
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-28 17:24:43 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        indirect_deps << full_name unless declared_deps_names.include?(name)
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-10 08:34:23 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        undeclared_deps << full_name
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    end
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-25 10:26:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-10 08:34:23 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    sort_by_formula_full_name!(indirect_deps)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    sort_by_formula_full_name!(undeclared_deps)
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-25 10:26:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-28 17:24:43 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    unnecessary_deps = declared_deps_full_names.reject do |full_name|
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      next true if Formula[full_name].bin.directory?
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-10 08:34:23 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      name = full_name.split("/").last
							 | 
						
					
						
							
								
									
										
										
										
											2018-08-27 10:12:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      @brewed_dylibs.keys.map { |l| l.split("/").last }.include?(name)
							 | 
						
					
						
							
								
									
										
										
										
											2016-09-11 17:49:27 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    end
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-25 10:26:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-07 15:35:27 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    missing_deps = @broken_deps.values.flatten.map { |d| dylib_to_dep(d) }
							 | 
						
					
						
							
								
									
										
										
										
											2018-03-21 13:10:23 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    unnecessary_deps -= missing_deps
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-25 11:44:29 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-08-27 10:12:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    version_hash = {}
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    version_conflict_deps = Set.new
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    @brewed_dylibs.keys.each do |l|
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      name = l.split("/").last
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      unversioned_name, = name.split("@")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      version_hash[unversioned_name] ||= Set.new
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      version_hash[unversioned_name] << name
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      next if version_hash[unversioned_name].length < 2
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-08-27 10:12:02 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      version_conflict_deps += version_hash[unversioned_name]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    [indirect_deps, undeclared_deps,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								     unnecessary_deps, version_conflict_deps.to_a]
							 | 
						
					
						
							
								
									
										
										
										
											2018-02-10 08:34:23 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  def sort_by_formula_full_name!(arr)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    arr.sort! do |a, b|
							 | 
						
					
						
							
								
									
										
										
										
											2016-09-11 17:49:27 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      if a.include?("/") && !b.include?("/")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        1
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      elsif !a.include?("/") && b.include?("/")
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        -1
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        a <=> b
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-07 20:41:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      end
							 | 
						
					
						
							
								
									
										
										
										
											2016-09-11 17:49:27 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    end
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-07 20:41:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-19 22:48:01 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  # Whether or not dylib is a harmless broken link, meaning that it's
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  # okay to skip (and not report) as broken.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  def harmless_broken_link?(dylib)
							 | 
						
					
						
							
								
									
										
										
										
											2017-07-22 15:39:53 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    # libgcc_s_* is referenced by programs that use the Java Service Wrapper,
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-19 22:48:01 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    # and is harmless on x86(_64) machines
							 | 
						
					
						
							
								
									
										
										
										
											2017-07-22 15:39:53 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    [
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      "/usr/lib/libgcc_s_ppc64.1.dylib",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      "/opt/local/lib/libgcc/libgcc_s.1.dylib",
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    ].include?(dylib)
							 | 
						
					
						
							
								
									
										
										
										
											2017-06-19 22:48:01 -04:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-07 20:41:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  # Display a list of things.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  # Things may either be an array, or a hash of (label -> array)
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-24 09:52:51 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  def display_items(label, things, puts_output: true)
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-07 20:41:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    return if things.empty?
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-24 09:52:51 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    output = "#{label}:"
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-07 20:41:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    if things.is_a? Hash
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-07 13:33:10 -05:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								      things.keys.sort.each do |list_label|
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        things[list_label].sort.each do |item|
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-24 09:52:51 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								          output += "\n  #{item} (#{list_label})"
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-07 20:41:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    else
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      things.sort.each do |item|
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-24 09:52:51 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        output += "\n  #{item}"
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-07 20:41:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								      end
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    end
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-24 09:52:51 +01:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    puts output if puts_output
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    output
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-07 20:41:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  end
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-14 13:14:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  def resolve_formula(keg)
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-15 17:45:21 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    Formulary.from_keg(keg)
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-14 13:14:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								  rescue FormulaUnavailableError
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    opoo "Formula unavailable: #{keg.name}"
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								  end
							 | 
						
					
						
							
								
									
										
										
										
											2016-07-07 20:41:14 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								end
							 | 
						
					
						
							
								
									
										
										
										
											2018-09-05 15:29:42 -07:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								require "extend/os/linkage_checker"
							 |