brew icon indicating copy to clipboard operation
brew copied to clipboard

Add formula DSL support for omitting install name rewriting for `@rpath/*` install names

Open carlocab opened this issue 1 year ago • 5 comments

Verification

  • [X] This issue's title and/or description do not reference a single formula e.g. brew install wget. If they do, open an issue at https://github.com/Homebrew/homebrew-core/issues/new/choose instead.

Provide a detailed description of the proposed feature

Currently, we rewrite all library install names to something like opt_prefix/library_install_name.basename.

https://github.com/Homebrew/brew/blob/e62a839001faf69160965c352b66870006c2af65/Library/Homebrew/extend/os/mac/keg_relocate.rb#L24-L27

Typically, these will be because the install name refers to a Cellar path, e.g., prefix/library_install_name.basename. The install name rewriting allows us to avoid unnecessary rebuilds of dependents with version/revision bumps.

This install name rewriting isn't needed when the install name starts with @rpath, because these will typically not hardcode a Cellar path reference that will need to be rebuilt on version/revision bumps.

Formulae should support some sort of DSL that makes the code in keg_relocate.rb skip rewriting an install name if it starts with @rpath.

What is the motivation for the feature?

Our rewriting of @rpath-prefixed install names breaks macdeployqt. See Homebrew/discussions#2823.

This is arguably an upstream bug, but convincing upstream to fix it is unlikely to succeed without a reproduction of the issue outside of Homebrew, and I don't think anyone has the time or energy to do this. Even if one had such a reproducer, it would likely still be rather difficult to convince upstream to fix this short of providing a patch.

Such a DSL could also replace a very old workaround in Rust:

  def post_install
    Dir["#{lib}/rustlib/**/*.dylib"].each do |dylib|
      chmod 0664, dylib
      MachO::Tools.change_dylib_id(dylib, "@rpath/#{File.basename(dylib)}")
      MachO.codesign!(dylib) if Hardware::CPU.arm?
      chmod 0444, dylib
    end
  end

How will the feature be relevant to at least 90% of Homebrew users?

It probably won't be, but it would likely be relevant to our users who use Qt, which form a non-negligible fraction of our user base.

What alternatives to the feature have been considered?

See alternatives described in this comment.

carlocab avatar May 03 '23 05:05 carlocab

Also, to explain why we want an additional DSL rather than just skipping the rewriting of @rpath/* install names entirely:

Typically, these will make linking with libraries harder. For example, if libfoo.dylib has an absolute path for its install name, linking with libfoo only requires

-L$HOMEBREW_PREFIX/lib -lfoo

However, if libfoo has @rpath/libfoo.dylib for its install name, one would need some variation of

-L$HOMEBREW_PREFIX/lib -lfoo -Wl,-rpath,$HOMEBREW_PREFIX/lib

which is likely to trip up many users and result in may issues/discussion posts created.

If we had such a DSL, the above would not be a consideration for Rust (cargo handles linker invocation), and isn't likely to be a significant problem for Qt (since upstream ships libraries/frameworks with install names that start with @rpath in their pre-built binaries).

carlocab avatar May 03 '23 05:05 carlocab

Thanks @carlocab. Agree with everything you've said here and the desire for this for both Qt and Rust.

MikeMcQuaid avatar May 03 '23 10:05 MikeMcQuaid

@carlocab May I ask for the progress of this PR? If this fixes the "Cannot resolve rpath" errors described here, it would help us a lot to get LibrePCB migrated to Qt6. Currently this task is blocked by the broken deployment with macdeployqt.

ubruhin avatar Mar 08 '24 20:03 ubruhin

What's the status of this?

pawsaw avatar Aug 01 '24 09:08 pawsaw

@pawsaw We're waiting for someone to implement it.

MikeMcQuaid avatar Aug 01 '24 18:08 MikeMcQuaid