From 521f1ec95904dcf4064d23831ca2e484b930bc26 Mon Sep 17 00:00:00 2001 From: Max Howell Date: Mon, 10 May 2010 00:19:14 +0100 Subject: [PATCH] A install name fix step during install We currently only fix relative paths, but we should expand this more. --- Library/Homebrew/install.rb | 16 +++++++- Library/Homebrew/keg.rb | 2 + Library/Homebrew/keg_fix_install_names.rb | 45 +++++++++++++++++++++++ 3 files changed, 61 insertions(+), 2 deletions(-) create mode 100644 Library/Homebrew/keg_fix_install_names.rb diff --git a/Library/Homebrew/install.rb b/Library/Homebrew/install.rb index 880d9081f9..b7de5df106 100755 --- a/Library/Homebrew/install.rb +++ b/Library/Homebrew/install.rb @@ -120,6 +120,18 @@ def install f ohai 'Finishing up' if ARGV.verbose? + keg = Keg.new f.prefix + + begin + keg.fix_install_names + rescue Exception => e + onoe "Failed to fix install names" + puts "The formula built, but you may encounter issues using it or linking other" + puts "formula against it." + ohai e, e.backtrace if ARGV.debug? + show_summary_heading = true + end + begin require 'cleaner' Cleaner.new f @@ -177,10 +189,10 @@ def install f # link from Cellar to Prefix begin - Keg.new(f.prefix).link + keg.link rescue Exception => e onoe "The linking step did not complete successfully" - puts "The package built, but is not symlinked into #{HOMEBREW_PREFIX}" + puts "The formula built, but is not symlinked into #{HOMEBREW_PREFIX}" puts "You can try again using `brew link #{f.name}'" if ARGV.debug? ohai e, e.backtrace diff --git a/Library/Homebrew/keg.rb b/Library/Homebrew/keg.rb index 22bf40bc3b..0d3c796996 100644 --- a/Library/Homebrew/keg.rb +++ b/Library/Homebrew/keg.rb @@ -122,3 +122,5 @@ protected end end end + +require 'keg_fix_install_names' diff --git a/Library/Homebrew/keg_fix_install_names.rb b/Library/Homebrew/keg_fix_install_names.rb new file mode 100644 index 0000000000..dd23c7755f --- /dev/null +++ b/Library/Homebrew/keg_fix_install_names.rb @@ -0,0 +1,45 @@ +class Keg + def fix_install_names + dylibs.each do |dylib| + bad_install_names_for dylib do |id, bad_names| + dylib.ensure_writable do + system "install_name_tool", "-id", id, dylib + bad_names.each do |bad_name| + # we should be more careful here, check the path we point to exists etc. + system "install_name_tool", "-change", bad_name, "@loader_path/#{bad_name}", dylib + end + end + end + end + end + + private + + OTOOL_RX = /\t(.*) \(compatibility version (\d+\.)*\d+, current version (\d+\.)*\d+\)/ + + def bad_install_names_for dylib + dylib = dylib.to_s + + ENV['HOMEBREW_DYLIB'] = dylib # solves all shell escaping problems + install_names = `otool -L "$HOMEBREW_DYLIB"`.split "\n" + + install_names.shift # first line is fluff + install_names.map!{ |s| OTOOL_RX =~ s && $1 } + id = install_names.shift + install_names.compact! + install_names.reject!{ |fn| fn =~ /^@(loader|executable)_path/ } + install_names.reject!{ |fn| fn.start_with? '/' } + + unless install_names.empty? and id == dylib # avoid the work if possible + yield dylib, install_names + end + end + + def dylibs + if (lib = join 'lib').directory? + lib.children.select{ |pn| pn.extname == '.dylib' and not pn.symlink? } + else + [] + end + end +end