Fix upgrading libdeps breaking stuff after cleanups

Fixes Homebrew/homebrew#2709.

By forcing dylibs to have an install_name id that is the HOMEBREW_PREFIX path, ie. the symlink’s path. Stuff that links to these dylibs will use this id and thus by immune to upgrades of underlying libraries.

Thus whatever keg is "current" ie. linked, will be the library that is used by the tool.

This fix is not retroactive. So there will still be breakage for existing installations of stuff.

The fix_install step in install is moved after the link step as the symlinking
is required to determine the eventual ids for each dylib.
This commit is contained in:
Max Howell 2011-06-16 15:11:41 +01:00
parent 527c841f1c
commit 215fcd3292
2 changed files with 18 additions and 13 deletions

View File

@ -119,16 +119,6 @@ def install f
keg = Keg.new f.prefix 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 begin
require 'cleaner' require 'cleaner'
Cleaner.new f if not f.pouring Cleaner.new f if not f.pouring
@ -204,6 +194,16 @@ def install f
end end
show_summary_heading = true show_summary_heading = true
end end
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
end end
ohai "Summary" if ARGV.verbose? or show_summary_heading ohai "Summary" if ARGV.verbose? or show_summary_heading

View File

@ -2,6 +2,9 @@ class Keg
def fix_install_names def fix_install_names
dylibs.each do |dylib| dylibs.each do |dylib|
bad_install_names_for dylib do |id, bad_names| bad_install_names_for dylib do |id, bad_names|
# avoid the chmod change if unecessary—I'm not convinced it reverses right
next if bad_names.empty? and id.to_s == dylib.to_s
dylib.ensure_writable do dylib.ensure_writable do
system "install_name_tool", "-id", id, dylib system "install_name_tool", "-id", id, dylib
bad_names.each do |bad_name| bad_names.each do |bad_name|
@ -30,9 +33,11 @@ class Keg
install_names.reject!{ |fn| fn =~ /^@(loader|executable)_path/ } install_names.reject!{ |fn| fn =~ /^@(loader|executable)_path/ }
install_names.reject!{ |fn| fn[0,1] == '/' } install_names.reject!{ |fn| fn[0,1] == '/' }
unless install_names.empty? and id == dylib # avoid the work if possible # the shortpath ensures that library upgrades dont break installed tools
yield dylib, install_names shortpath = HOMEBREW_PREFIX + Pathname.new(dylib).relative_path_from(self)
end id = if shortpath.exist? then shortpath else dylib end
yield id, install_names
end end
def dylibs def dylibs