formula: add rpath helper method#11187
formula: add rpath helper method#11187carlocab merged 1 commit intoHomebrew:masterfrom carlocab:cmake-rpath
Conversation
About 40 formulae set `CMAKE_INSTALL_RPATH` to `lib` or `opt_lib`, but this breaks bottle relocatability. The correct solution is to use `@loader_path/../lib`, but this is macOS specific, so it requires some OS-specific logic. Rather than replicating this logic over many formulae, we may as well define a helper method for it. See Homebrew/homebrew-core#75458.
|
Review period will end on 2021-04-20 at 08:30:16 UTC. |
|
Is this cmake specific or more general? If it's cmake specific I would like to propose to use |
|
It's likely to be used with |
MikeMcQuaid
left a comment
There was a problem hiding this comment.
This makes sense to me but can you define a def rpath in formula.rb (either with the Linux or macOS version) so it'll work on a "generic" OS.
|
There is a |
I cannot read 🤦🏻. |
|
Review period ended. |
|
I didn't see this PR until now. For the future, I'm very interested in getting a review request on PRs that affect Linux bottles and their ability to be relocated. |
| end | ||
|
|
||
| def rpath | ||
| "'$ORIGIN/../lib'" |
There was a problem hiding this comment.
The single quotes here seem very suspicious to me. I've verified that the RPATH of abseil does get set correctly to $ORIGIN/../lib without single quotes, but I strongly suspect that it should be up to the caller to add the single quotes when needed.
There was a problem hiding this comment.
We can drop it if it's not needed. I was just concerned about the shell eating the $, so I put that in there. I don't quite know how much the shell interprets things when you make system calls in the install method, however.
There was a problem hiding this comment.
The form system "foo bar baz" does go through the shell and shell expansion, but the preferred form system "foo", "bar", "baz" does not go through the shell and shell expansion.
There was a problem hiding this comment.
Does it hurt though? I think waiting for the caller to make sure the $ is not interpreted by the shell is a footgun. If there's a reason to give callers that, then we can do so, but I'm not sure there is.
|
An |
|
Thank you for this work, Carlo. I like the general idea. Here's an alternative. |
|
For the |
|
Thanks for the comments, @sjackman! I'll remember to request a review from you in the future for PRs like this. While I do like the added flexibility you suggest, I don't see where it could be used at the moment. This PR was designed to make it easy to pass a value to I was contemplating a slightly less sophisticated change to this, which, with a little bit more verbosity might let you do something similar to what you suggest, I think: Homebrew/homebrew-core#75566 (comment) Note that this value of |
Good point! In that case particular case, although |
|
Well the idea is that it should work for both libraries and executables with no intervention :) |
|
My biggest concern is that |
|
Are there any formulae that could make use of the added flexibility? I agree it makes a big assumption, but it's an assumption that standard build systems make. It's also an assumption that I believe is true for each of the ~40 cases I intend to use it in. |
Homebrew/homebrew-core#75566 (comment) |
|
https://github.com/Homebrew/homebrew-core/blob/bf3cc1388d68d829bfbeb7f9cdfb71ac57b4692c/Formula/standardese.rb#L24 |
|
If If it has executables installed in |
f = Formula["hello"]
# The RPATH for an executable installed in bin looking for a library installed in lib.
p "@loader_path/#{f.lib.relative_path_from f.bin}"
# "@loader_path/../lib"
# The RPATH for an executable installed in bin looking for a library installed in Frameworks.
p "@loader_path/#{f.frameworks.relative_path_from f.bin}"
# "@loader_path/../Frameworks"
# The RPATH for a library installed in lib looking for a library installed in lib.
p "@loader_path/#{f.lib.relative_path_from f.lib}"
# "@loader_path/."
# The RPATH for an executable installed in bin looking for a library installed in libexec/lib.
p "@loader_path/#{(f.libexec/"lib").relative_path_from f.bin}"
# "@loader_path/../libexec/lib"
# The RPATH for an executable installed in libexec/bin looking for a library installed in lib.
p "@loader_path/#{f.lib.relative_path_from f.libexec/"bin"}"
# "@loader_path/../../lib"A few different cases to consider. |
|
Perhaps something like… class Pathname
def relative_rpath_from base_directory
"@loader_path/#{self.relative_path_from base_directory}"
end
end |
$ otool -l /usr/local/Cellar/standardese/0.5.1/bin/standardese | grep -A2 LC_RPATH
cmd LC_RPATH
cmdsize 56
path /usr/local/opt/standardese/libexec/lib (offset 12)The |
It does, but I don't think we'll be using an
I know. I put them there in Homebrew/homebrew-core@8916862, because I wasn't sure if putting them in |
|
After looking over the 37 formulae that use It does make me a tad nervous that if the executable is installed in a subdirectory like say Thanks for improving bottle relocation, Carlo! |
|
No apologies necessary! Always happy to discuss changes to make sure they're the right ones to make. I actually really like the idea of a more flexible I agree with your concern about breaking stuff though: I'll be careful, and double check the built bottles for stray binary objects living somewhere the current definition of |
brew stylewith your changes locally?brew typecheckwith your changes locally?brew testswith your changes locally?About 40 formulae set
CMAKE_INSTALL_RPATHtoliboropt_lib, butthis breaks bottle relocatability.
The correct solution is to use
@loader_path/../lib, but this is macOSspecific, so it requires some OS-specific logic. Rather than replicating
this logic over many formulae, we may as well define a helper method for
it.
See Homebrew/homebrew-core#75458.