aboutsummaryrefslogtreecommitdiffstats
path: root/Library
diff options
context:
space:
mode:
authorMartin Afanasjew2015-11-18 21:49:20 +0100
committerMike McQuaid2015-11-19 08:54:58 +0000
commit6f5307fbd91670ac9395a4190a83e7d82211379d (patch)
treee3c7c430b08b4c99a9e7f01648617683691888a8 /Library
parentc6621faf183f175821fd5b7fcd98f2404c8a4be7 (diff)
downloadbrew-6f5307fbd91670ac9395a4190a83e7d82211379d.tar.bz2
keg_relocate: fix relocation of frameworks
When fixing references to regular dylibs, it is sufficient to search for a file with the same base name, e.g., `libpoppler.56.dylib`. However, if the broken reference is to a framework, we also have to take into account preceding path components to find a suitable match. Framework references (according to the `dyld` man page) come in two flavors: - `XXX.framework/Versions/YYY/XXX` (with version) - `XXX.framework/XXX` (without version) The change here is to detect these patterns and to make sure that the fixed library reference has the same suffix as the broken one. Prior to this fix, a broken framework reference (if originating in a sister framework) to `QtXml.framework/Versions/5/QtXml` would have been rewritten to `<qt5-keg>/lib/QtXml.framework/QtXml`. In practice, this mostly works, but is technically incorrect and thus creates problems like in Homebrew/homebrew#42191. With this fix, the framework reference is correctly rewritten to `<qt5-keg>/lib/QtXml.framework/Versions/5/QtXml`. Closes Homebrew/homebrew#45494. Signed-off-by: Mike McQuaid <mike@mikemcquaid.com>
Diffstat (limited to 'Library')
-rw-r--r--Library/Homebrew/keg_relocate.rb20
1 files changed, 17 insertions, 3 deletions
diff --git a/Library/Homebrew/keg_relocate.rb b/Library/Homebrew/keg_relocate.rb
index 11699433f..0490b05c6 100644
--- a/Library/Homebrew/keg_relocate.rb
+++ b/Library/Homebrew/keg_relocate.rb
@@ -130,7 +130,7 @@ class Keg
"@loader_path/#{bad_name}"
elsif file.mach_o_executable? && (lib + bad_name).exist?
"#{lib}/#{bad_name}"
- elsif (abs_name = find_dylib(Pathname.new(bad_name).basename)) && abs_name.exist?
+ elsif (abs_name = find_dylib(bad_name)) && abs_name.exist?
abs_name.to_s
else
opoo "Could not fix #{bad_name} in #{file}"
@@ -156,8 +156,22 @@ class Keg
opt_record.join(relative_dirname, basename).to_s
end
- def find_dylib(name)
- lib.find { |pn| break pn if pn.basename == name } if lib.directory?
+ # Matches framework references like `XXX.framework/Versions/YYY/XXX` and
+ # `XXX.framework/XXX`, both with or without a slash-delimited prefix.
+ FRAMEWORK_RX = %r{(?:^|/)(([^/]+)\.framework/(?:Versions/[^/]+/)?\2)$}.freeze
+
+ def find_dylib_suffix_from(bad_name)
+ if (framework = bad_name.match(FRAMEWORK_RX))
+ framework[1]
+ else
+ File.basename(bad_name)
+ end
+ end
+
+ def find_dylib(bad_name)
+ return unless lib.directory?
+ suffix = "/#{find_dylib_suffix_from(bad_name)}"
+ lib.find { |pn| break pn if pn.to_s.end_with?(suffix) }
end
def mach_o_files