brew: Relocation breaks Qt installs on Linux

brew config output

HOMEBREW_VERSION: 3.6.2
ORIGIN: https://github.com/Homebrew/brew
HEAD: b8b195cc64a29595797651720ebb2ea09affb682
Last commit: 5 days ago
Core tap ORIGIN: https://github.com/Homebrew/homebrew-core
Core tap HEAD: 55e393266248529b58c2ff6df23485a90ba8a81e
Core tap last commit: 5 days ago
Core tap branch: master
HOMEBREW_PREFIX: /home/linuxbrew/.linuxbrew
HOMEBREW_CASK_OPTS: []
HOMEBREW_MAKE_JOBS: 4
Homebrew Ruby: 2.6.8 => /home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/vendor/portable-ruby/2.6.8_1/bin/ruby
CPU: quad-core 64-bit icelake
Clang: N/A
Git: 2.37.3 => /bin/git
Curl: 7.81.0 => /bin/curl
Kernel: Linux 5.10.109-0-virt x86_64 GNU/Linux
OS: Unknown
Host glibc: 2.35
/usr/bin/gcc: 11.2.0
/usr/bin/ruby: N/A
glibc: N/A
gcc@11: N/A
gcc@12: N/A
xorg: N/A

brew doctor output

Your system is ready to brew.

Verification

  • I ran brew update and am still able to reproduce my issue.
  • I have resolved all warnings from brew doctor and that did not fix my problem.

What were you trying to do (and why)?

Test Qt after pouring a just-built bottle for distribution.

What happened (include all command output)?

Running the test fails with

  ==> ./test
  ASSERT: "list.contains(fmt)" in file /tmp/qt-test-20220920-224400-u60d5/main.cpp, line 31

This is because relocation breaks the bottle. See Homebrew/homebrew-core#111031.

What did you expect to happen?

Successful test.

Step-by-step reproduction instructions (by running brew commands)

brew install --build-bottle qt
brew bottle --json qt --keep-old --only-json-tab
brew install --only-dependencies ./qt--6.3.1_4.x86_64_linux.bottle.tar.gz
brew install ./qt--6.3.1_4.x86_64_linux.bottle.tar.gz
brew test qt

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 17 (17 by maintainers)

Most upvoted comments

vgrep is probably also affected by this as it works fine when built directly from source but segfaults after being poured from a bottle.

Might be different than the note section issue but I’ve fixed a couple of other corruption bugs too in that commit so it could cover this - I’ll have a look as I’ll need to see the readelf dump of that binary (both directly from the bottle and the installed file after patching).

Does it not throw a specific error that we can catch? If so we can probably do that here. Or, if not, we can upstream the throwing a specific error with the justification that downstream projects should be able to decide how to handle the previous erroneous behaviour.

It throws a generic PatchError, but with a specific message.

However the problem is this raising the error will mean nothing is written to disk when we actually want a “best-effort” patch since patching nothing will result in a non-functional binary.

So the only real solution beyond a conditional is to make it a warning for the specific scope we need it to be, which I think can make sense as a backwards compatibility with older patchelf case.

Also see an issue in gopass (https://github.com/Homebrew/homebrew-core/pull/111620) which could be due to same root cause. At least brew install --build-bottle has working binary but brew bottle ... ; brew uninstall ... ; brew install ./<bottle> has broken binary with ELF issues seen via readelf and gdb.

Needs further analysis to know if all these issues (qt, openj9, gopass) are same.