From acae97e70fe0c6c3354960e2e89a1157d06cfdaa Mon Sep 17 00:00:00 2001 From: Carlo Cabrera <30379873+carlocab@users.noreply.github.com> Date: Thu, 27 Jul 2023 11:53:46 +0800 Subject: [PATCH] os/mac/mach: resolve rpaths too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can add a small amount of logic to `#resolve_variable_name` that will allow us to perform (limited) resolution of rpath references. This is for informational purposes only: failing to resolve an `@rpath` reference will not (and should not) result in `brew linkage` failures. `dyld` will typically have more information than we do to resolve these references, so not failing `brew linkage` when we fail to resolve an `@rpath` reference is the right behaviour here. As an example, before: ❯ brew linkage jpeg-turbo System libraries: /usr/lib/libSystem.B.dylib @rpath-referenced libraries: @rpath/libjpeg.8.dylib @rpath/libturbojpeg.0.dylib After: ❯ brew linkage jpeg-turbo System libraries: /usr/lib/libSystem.B.dylib Homebrew libraries: /usr/local/Cellar/jpeg-turbo/3.0.0/lib/libjpeg.8.dylib (jpeg-turbo) /usr/local/Cellar/jpeg-turbo/3.0.0/lib/libturbojpeg.0.dylib (jpeg-turbo) --- Library/Homebrew/os/mac/mach.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Library/Homebrew/os/mac/mach.rb b/Library/Homebrew/os/mac/mach.rb index f9818d6f84..38f52dc4c9 100644 --- a/Library/Homebrew/os/mac/mach.rb +++ b/Library/Homebrew/os/mac/mach.rb @@ -110,11 +110,22 @@ module MachOShim Pathname(name.sub("@loader_path", dirname)).cleanpath.to_s elsif name.start_with?("@executable_path") && binary_executable? Pathname(name.sub("@executable_path", dirname)).cleanpath.to_s + elsif name.start_with?("@rpath") && (target = resolve_rpath(name)).present? + target else name end end + def resolve_rpath(name) + target = T.let(nil, T.nilable(String)) + return unless rpaths(resolve_variable_references: true).find do |rpath| + File.exist?(target = File.join(rpath, name.delete_prefix("@rpath"))) + end + + target + end + def archs mach_data.map { |m| m.fetch :arch } end