Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Homebrew is producing bottles with problematic binstubs #11558

Closed
mistydemeo opened this issue Jun 18, 2021 · 11 comments
Closed

Homebrew is producing bottles with problematic binstubs #11558

mistydemeo opened this issue Jun 18, 2021 · 11 comments
Labels
outdated PR was locked due to age stale No recent activity

Comments

@mistydemeo
Copy link
Contributor

mistydemeo commented Jun 18, 2021

As of #11537, we're now producing binstubs which contain brew --prefix instead of the absolute path. This has unexpectedly introduced problems when using one of those bottles as a dependency when building formulae from source. Given the following:

  • When building a formula from source, it may need to run binaries from its dependencies, and
  • When building a formula from source, superenv guards the install method from having brew in its PATH,

Formulae can no longer safely call the binaries of their own dependencies during their build if those binaries are Homebrew-produced binstubs. This happened in the wild with the homebrew-sass tap, whose dart dependency uses Homebrew-produced binstubs. It lead to the following error when calling any of them:

/usr/local/opt/dart/bin/pub: line 2: brew: command not found
/usr/local/opt/dart/bin/pub: line 2: /dart/2.13.3/libexec/bin/pub: No such file or directory
/usr/local/opt/dart/bin/pub: line 2: exec: /dart/2.13.3/libexec/bin/pub: cannot execute: No such file or directory

I think the goal of ensuring we're not encoding Homebrew paths in scripts is good, but it's not safe to put calls to brew in them. Let's work out another prefix-independent way we can safely write these calls.

While we work to figure out an alternate solution, I'd like to back this change out ASAP. Otherwise, we're going to start shipping bottles that will cause issues when we depend on them in building bottles from other packages.

cc @alebcay

@carlocab
Copy link
Member

Needing brew to be in PATH for these binstubs to work isn't great. Would it defeat the purpose of the #11537 to replace the call to brew with a fully qualified path? i.e. #{HOMEBREW_PREFIX}/bin/brew instead of just brew.

@mistydemeo
Copy link
Contributor Author

That's what we had before that patch went in! The goal of that PR was to remove fully-qualified paths to make bottles prefix-independent.

Another option I guess would be to write a placeholder path specifically when building as a bottle, and have the bottle pouring process rewrite that placeholder path to the real one. Basically what we do with install_name modifications.

@carlocab
Copy link
Member

carlocab commented Jun 18, 2021

Another option I guess would be to write a placeholder path specifically when building as a bottle, and have the bottle pouring process rewrite that placeholder path to the real one. Basically what we do with install_name modifications.

Isn't that what happens already? I'm pretty sure we replace all instances of #{HOMEBREW_PREFIX} with @HOMEBREW_PREFIX@, etc upon bottling.

This does create some platform-dependent deviations between bottles, but not because of our binstubs. Usually, this is because there are some textfiles that contain /usr/local references that keg-relocation is too eager to replace with @HOMEBREW_PREFIX@ on Intel. This replacement doesn't happen on ARM, because keg relocation checks for /opt/homebrew there. (This replacement also doesn't happen with bottle :unneeded, hence my suggestion for a skip_relocation DSL in Homebrew/homebrew-core#75943. Unfortunately, the GitHub UI has made that suggestion hard to find. 😅)

I wonder if we should just replace /usr/local with /opt/homebrew on ARM too -- there's no reason things we install should be looking in /usr/local on ARM, I think. (This may not be the case for external taps, however.)


Found my comment! Homebrew/homebrew-core#75943 (comment)

@MikeMcQuaid
Copy link
Member

I wonder if we should just replace /usr/local with /opt/homebrew on ARM too -- there's no reason things we install should be looking in /usr/local on ARM, I think. (This may not be the case for external taps, however.)

We should stop replacing /usr/local entirely.

@carlocab
Copy link
Member

We should stop replacing /usr/local entirely.

We could do that, but I think we ought still replace

/usr/local/{bin,Cellar,etc,Frameworks,Homebrew,include,lib,opt,sbin,share,var}

or perhaps a somewhat more restrictive glob/regex that could potentially depend on the contents of the relevant kegs.

@Rylan12
Copy link
Member

Rylan12 commented Jun 18, 2021

I left a comment in slack but I figure I'll cross-post here:

When determining relocatability in binary files (on the default prefix), we already only check HOMEBREW_PREFIX/{opt,etc,var,share/vim}, (in addition to HOMEBREW_LIBRARY, sometimes HOMEBREW_REPOSITORY, and HOMEBREW_CELLAR. So, I think it makes sense that these same paths are the only ones relocated in text files.

@MikeMcQuaid
Copy link
Member

When determining relocatability in binary files (on the default prefix), we already only check HOMEBREW_PREFIX/{opt,etc,var,share/vim}, (in addition to HOMEBREW_LIBRARY, sometimes HOMEBREW_REPOSITORY, and HOMEBREW_CELLAR. So, I think it makes sense that these same paths are the only ones relocated in text files.

Agreed 👍🏻

or perhaps a somewhat more restrictive glob/regex that could potentially depend on the contents of the relevant kegs.

yes /usr/local/bin is generally not worth being replaced as it's present too often in non-Homebrew stuff.

@carlocab
Copy link
Member

Since this came up again in a related PR: I'm still not sure why we need #11537, as keg relocation already handles env scripts. For example, from a bottled env script (cf. Homebrew/homebrew-core#79575), we have:

#!/bin/bash
JAVA_HOME="@@HOMEBREW_PREFIX@@/opt/openjdk@11/libexec/openjdk.jdk/Contents/Home" exec "@@HOMEBREW_CELLAR@@/apache-drill/1.19.0/libexec/bin/drillbit.sh"  "$@"

so I don't think platform-dependent prefixes are an impediment to all bottles unless there's a bug in our relocation code.

Have I just misunderstood something here?

@alebcay
Copy link
Member

alebcay commented Jun 22, 2021

I was not aware that #11537 broke things this badly. Oops 💀 sorry for the inconvenience.

so I don't think platform-dependent prefixes are an impediment to all bottles unless there's a bug in our relocation code.

Yeah. I just took a peek in some bottles. I think now that #11537 was not needed after all.

At some point I ran into a weird case where I noticed in bottling up everything that something was not getting an all: bottle when it should have been, so I thought this was still an issue. In retrospect the difference was probably caused by something else.

@carlocab
Copy link
Member

For future reference:

There are some formulae where /usr/local/share is being bottled as @@HOMEBREW_PREFIX@@/share where we may not want them to be. Example: Homebrew/homebrew-core#79490

On the other hand, there are also formulae where this relocation is desirable, and we should be substituting /usr/local for $HOMEBREW_PREFIX: Homebrew/homebrew-core#79751

@github-actions
Copy link

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@github-actions github-actions bot added the stale No recent activity label Jul 14, 2021
@github-actions github-actions bot added the outdated PR was locked due to age label Aug 20, 2021
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 20, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
outdated PR was locked due to age stale No recent activity
Projects
None yet
Development

No branches or pull requests

5 participants