From 186a76c741a92c25d58b85d597bbb9fb5774c668 Mon Sep 17 00:00:00 2001 From: Jack Nagel Date: Tue, 4 Sep 2012 10:49:14 -0500 Subject: [PATCH] Fix bad install names in executables Signed-off-by: Jack Nagel --- Library/Homebrew/keg_fix_install_names.rb | 41 +++++++++++++++-------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/Library/Homebrew/keg_fix_install_names.rb b/Library/Homebrew/keg_fix_install_names.rb index 75e1def22e..09cda18666 100644 --- a/Library/Homebrew/keg_fix_install_names.rb +++ b/Library/Homebrew/keg_fix_install_names.rb @@ -6,19 +6,17 @@ class Keg system MacOS.locate("install_name_tool"), "-id", id, file if file.dylib? bad_names.each do |bad_name| - new_name = bad_name - new_name = Pathname.new(bad_name).basename unless (file.parent + new_name).exist? - - # First check to see if the dylib is present in the current - # directory, so we can skip the more expensive search. - if (file.parent + new_name).exist? - system MacOS.locate("install_name_tool"), "-change", bad_name, "@loader_path/#{new_name}", file + # If file is a dylib or bundle itself, look for the dylib named by + # bad_name relative to the lib directory, so that we can skip the more + # expensive recursive search if possible. + if file.dylib? or file.mach_o_bundle? and (file.parent + bad_name).exist? + system MacOS.locate("install_name_tool"), "-change", bad_name, "@loader_path/#{bad_name}", file + elsif file.mach_o_executable? and (lib/bad_name).exist? + system MacOS.locate("install_name_tool"), "-change", bad_name, "#{lib}/#{bad_name}", file else - # Otherwise, try and locate the appropriate dylib by walking - # the entire 'lib' tree recursively. - abs_name = (self+'lib').find do |pn| - break pn if pn.basename == Pathname.new(new_name) - end + # Otherwise, try and locate the dylib by walking the entire + # lib tree recursively. + abs_name = find_dylib(Pathname.new(bad_name).basename) if abs_name and abs_name.exist? system MacOS.locate("install_name_tool"), "-change", bad_name, abs_name, file @@ -36,6 +34,8 @@ class Keg OTOOL_RX = /\t(.*) \(compatibility version (\d+\.)*\d+, current version (\d+\.)*\d+\)/ + def lib; join 'lib' end + def bad_install_names_for file ENV['HOMEBREW_MACH_O_FILE'] = file.to_s # solves all shell escaping problems install_names = `#{MacOS.locate("otool")} -L "$HOMEBREW_MACH_O_FILE"`.split "\n" @@ -43,8 +43,8 @@ class Keg install_names.shift # first line is fluff install_names.map!{ |s| OTOOL_RX =~ s && $1 } - # Bundles don't have an ID - id = install_names.shift unless file.mach_o_bundle? + # Bundles and executables do not have an ID + id = install_names.shift if file.dylib? install_names.compact! install_names.reject!{ |fn| fn =~ /^@(loader|executable)_path/ } @@ -67,6 +67,12 @@ class Keg yield id, install_names end + def find_dylib name + (join 'lib').find do |pn| + break pn if pn.basename == Pathname.new(name) + end + end + def mach_o_files mach_o_files = [] if (lib = join 'lib').directory? @@ -75,6 +81,13 @@ class Keg mach_o_files << pn if pn.dylib? or pn.mach_o_bundle? end end + + if (bin = join 'bin').directory? + bin.find do |pn| + next if pn.symlink? or pn.directory? + mach_o_files << pn if pn.mach_o_executable? + end + end mach_o_files end end