Skip to content

Revert "Revert "Link versioned keg-only formulae by default""#21684

Merged
MikeMcQuaid merged 2 commits intomainfrom
revert-21682-revert_21676
Mar 7, 2026
Merged

Revert "Revert "Link versioned keg-only formulae by default""#21684
MikeMcQuaid merged 2 commits intomainfrom
revert-21682-revert_21676

Conversation

@MikeMcQuaid
Copy link
Copy Markdown
Member

@MikeMcQuaid MikeMcQuaid commented Mar 7, 2026

Take 2 of #21676
Reverts #21682

Will fix the issues before merge.

@MikeMcQuaid MikeMcQuaid force-pushed the revert-21682-revert_21676 branch from 3c6f6c0 to fbe324e Compare March 7, 2026 07:56
@MikeMcQuaid
Copy link
Copy Markdown
Member Author

Pushed fbe324e which restores the two-state link_keg T:Boolean and makes the default for non-keg-only kegs to be linked again.

@MikeMcQuaid MikeMcQuaid marked this pull request as ready for review March 7, 2026 07:56
Copilot AI review requested due to automatic review settings March 7, 2026 07:56
@MikeMcQuaid MikeMcQuaid enabled auto-merge March 7, 2026 07:57
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR re-introduces (after a revert) default-linking behavior for certain keg-only sibling formula variants (notably @-versioned and -full), along with the supporting “sibling overwrite” discovery/unlinking logic and updated user-facing output/caveats behavior.

Changes:

  • Add Formula APIs to discover “link overwrite” sibling relationships (versioned/unversioned and full/non-full) and generate reasons/warnings when linking is suppressed.
  • Update linking/unlinking flows to unlink sibling formulae before linking and to auto-link eligible versioned keg-only formulae by default.
  • Expand test coverage across Formula, Tap, FormulaInstaller, brew link, Caveats, and Unlink.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
Library/Homebrew/unlink.rb Renames/repurposes helper to unlink link-overwrite sibling formulae prior to linking.
Library/Homebrew/test/unlink_spec.rb Adds unit coverage for the new unlink helper behavior.
Library/Homebrew/test/tap_spec.rb Adds coverage for Tap#prefix_to_versioned_formulae_names grouping with -full variants.
Library/Homebrew/test/formula_spec.rb Adds coverage for new Formula sibling discovery APIs and behaviors.
Library/Homebrew/test/formula_installer_spec.rb Adds coverage for default linking behavior (including versioned keg-only auto-link decisions and warnings).
Library/Homebrew/test/cmd/link_spec.rb Ensures brew link doesn’t emit keg-only messaging for @-versioned / -full versioned keg-only formulae.
Library/Homebrew/test/caveats_spec.rb Verifies keg-only caveats are omitted when the formula is already linked.
Library/Homebrew/tap.rb Updates versioned-name prefix grouping to correctly account for -full variants.
Library/Homebrew/install.rb Adjusts link instructions to use full_name in the printed command.
Library/Homebrew/formula_installer.rb Implements auto-link defaulting for eligible versioned keg-only formulae and adds a manual-link warning.
Library/Homebrew/formula.rb Adds sibling relationship logic (unversioned_formula_name, full siblings, link-overwrite sets/reasons) and refines versioned name lookup.
Library/Homebrew/cmd/link.rb Avoids requiring --force and avoids printing keg-only output for versioned keg-only formulae; unlinks siblings before linking.
Library/Homebrew/caveats.rb Suppresses keg-only caveat text when the formula is linked.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@MikeMcQuaid MikeMcQuaid added this pull request to the merge queue Mar 7, 2026
Merged via the queue into main with commit 87b4b9d Mar 7, 2026
42 checks passed
@MikeMcQuaid MikeMcQuaid deleted the revert-21682-revert_21676 branch March 7, 2026 10:32
@cho-m
Copy link
Copy Markdown
Member

cho-m commented Mar 8, 2026

There is a new CI error when testing versioned Node formulae - https://github.com/Homebrew/homebrew-core/actions/runs/22808128923/job/66161379475?pr=271139#step:3:708

  ==> Pouring node@22--22.22.1_1.arm64_sonoma.bottle.tar.gz
  The formula built, but is not symlinked into /opt/homebrew
  Error: The `brew link` step did not complete successfully
  Could not symlink lib/node_modules/npm/LICENSE
  Target /opt/homebrew/lib/node_modules/npm/LICENSE
  already exists. You may want to remove it:
    rm '/opt/homebrew/lib/node_modules/npm/LICENSE'
  
  To force the link and overwrite all conflicting files:
    brew link --overwrite node@22
  
  To list all files that would be deleted:
    brew link --overwrite node@22 --dry-run

This is an odd case where node postinstall will create files that are not managed by brew. I think this was intentional so that users can manage npm installation themselves.

Reproduction should be possible with

brew install node
brew uninstall node
brew install node@22

Maybe brew link of versioned formula should not error in this particular case.

@MikeMcQuaid
Copy link
Copy Markdown
Member Author

@cho-m Thanks taking a look.

@MikeMcQuaid
Copy link
Copy Markdown
Member Author

@cho-m should be fixed by #21689

@cho-m cho-m mentioned this pull request Mar 17, 2026
7 tasks
@mmuetzel
Copy link
Copy Markdown

There might be another fallout from this change (relating to simultaneously installing Qt5 and Qt6). See:
Homebrew/homebrew-core#266072 (comment)

Is there something we can do about that?

@mmuetzel
Copy link
Copy Markdown

Copying the content of the comment on the other PR to here:

The CI for Octave started to fail with the following error more or less recently:

==> Pouring qt@5--5.15.18.sonoma.bottle.1.tar.gz
The formula built, but is not symlinked into /usr/local
Error: The `brew link` step did not complete successfully
Could not symlink bin/macdeployqt
Target /usr/local/bin/macdeployqt
is a symlink belonging to qtbase. You can unlink it:
  brew unlink qtbase

To force the link and overwrite all conflicting files:
  brew link --overwrite qt@5

To list all files that would be deleted:
  brew link --overwrite qt@5 --dry-run

Possible conflicting files are:
/usr/local/bin/macdeployqt -> /usr/local/Cellar/qtbase/6.10.2/bin/macdeployqt
/usr/local/bin/qdbuscpp2xml -> /usr/local/Cellar/qtbase/6.10.2/bin/qdbuscpp2xml
/usr/local/bin/qdbusxml2cpp -> /usr/local/Cellar/qtbase/6.10.2/bin/qdbusxml2cpp
/usr/local/bin/qmake -> /usr/local/Cellar/qtbase/6.10.2/bin/qmake
/usr/local/bin/qml -> /usr/local/Cellar/qtdeclarative/6.10.2/bin/qml
/usr/local/bin/qmleasing -> /usr/local/Cellar/qtdeclarative/6.10.2/bin/qmleasing
/usr/local/bin/qmlformat -> /usr/local/Cellar/qtdeclarative/6.10.2/bin/qmlformat
/usr/local/bin/qmllint -> /usr/local/Cellar/qtdeclarative/6.10.2/bin/qmllint
/usr/local/bin/qmlplugindump -> /usr/local/Cellar/qtdeclarative/6.10.2/bin/qmlplugindump
/usr/local/bin/qmlpreview -> /usr/local/Cellar/qtdeclarative/6.10.2/bin/qmlpreview
/usr/local/bin/qmlprofiler -> /usr/local/Cellar/qtdeclarative/6.10.2/bin/qmlprofiler
/usr/local/bin/qmlscene -> /usr/local/Cellar/qtdeclarative/6.10.2/bin/qmlscene
/usr/local/bin/qmltestrunner -> /usr/local/Cellar/qtdeclarative/6.10.2/bin/qmltestrunner
/usr/local/bin/qmltime -> /usr/local/Cellar/qtdeclarative/6.10.2/bin/qmltime
/usr/local/bin/qtpaths -> /usr/local/Cellar/qtbase/6.10.2/bin/qtpaths
Error: Could not symlink include/QtDeviceDiscoverySupport/6.10.2/QtDeviceDiscoverySupport/private/qdevicediscovery_dummy_p.h
Target /usr/local/include/QtDeviceDiscoverySupport/6.10.2/QtDeviceDiscoverySupport/private/qdevicediscovery_dummy_p.h
is a symlink belonging to qtbase. You can unlink it:
  brew unlink qtbase

To force the link and overwrite all conflicting files:
  brew link --overwrite qtbase

To list all files that would be deleted:
  brew link --overwrite qtbase --dry-run

Error: Process completed with exit code 1.

We didn't see these file conflicts until recently. E.g., the successful build here:
https://github.com/gnu-octave/octave/actions/runs/22943966315/job/66591663588

The Qt6 packages are pulled in because we are installing gnuplot.
We try to install qt@5 explicitly (to check building Octave with Qt5). But that started to fail, e.g., here:
https://github.com/gnu-octave/octave/actions/runs/23204538967/job/67436063493#step:3:576

Are these file (or symlink?) conflicts expected?
Is there something we can do to work around that error? (I was thinking of using brew install --overwrite qt@5 after gnuplot was installed.)

@MikeMcQuaid
Copy link
Copy Markdown
Member Author

Are these file (or symlink?) conflicts expected?

Somewhat. It's debatable whether or not we should automatically overwrite links in this case. What do you think?

@mmuetzel
Copy link
Copy Markdown

mmuetzel commented Mar 17, 2026

What do you think?

I'm not sure. I only noticed that the workflow started to fail without an apparent change on Octave's side.
I'd be happy to adapt the workflow if these conflicts are the expected behavior now. Would brew install --overwrite qt@5 after gnuplot was installed be the "Right Thing" to fix that?

Edit: I went ahead with that to unblock the CI of Octave on macOS:
gnu-octave/octave@e1e5502
Please, let me know if you think that this is not the correct approach to resolve the file conflicts.

@mmuetzel
Copy link
Copy Markdown

mmuetzel commented Mar 22, 2026

I don't know if this is also related. But the CI workflow for ElmerFEM using Homebrew packages also started failing with no apparent change in the build rules or sources last Wednesday (March 18, 2026).

Compared to the last successful run (the day before), CMake seems to be picking a different compiler now. (Not sure if that is the reason for the failing builds though.)

Last successful run:
https://github.com/ElmerCSC/elmerfem/actions/runs/23189695773

-- The Fortran compiler identification is GNU 15.2.0
-- The C compiler identification is AppleClang 17.0.0.17000013
-- The CXX compiler identification is AppleClang 17.0.0.17000013
[...]
--   C compiler:              /usr/bin/clang
--   C flags:                  -Xclang -fopenmp -I/usr/local/opt/libomp/include -O2 -g -DNDEBUG
-- ------------------------------------------------
--   CXX compiler:            /usr/bin/clang++
--   CXX flags:                -Xclang -fopenmp -I/usr/local/opt/libomp/include -O2 -g -DNDEBUG

First failing run:
https://github.com/ElmerCSC/elmerfem/actions/runs/23265667995/job/67651943223

-- The Fortran compiler identification is GNU 15.2.0
-- The C compiler identification is Clang 18.1.8
-- The CXX compiler identification is Clang 18.1.8
[...]
--   C compiler:              /usr/local/bin/clang
--   C flags:                  -Xclang -fopenmp -I/usr/local/opt/libomp/include -O2 -g -DNDEBUG
-- ------------------------------------------------
--   CXX compiler:            /usr/local/bin/clang++
--   CXX flags:                -Xclang -fopenmp -I/usr/local/opt/libomp/include -O2 -g -DNDEBUG

Note that the last successful build picked the compilers from /usr/bin (and identified the compilers as "AppleClang"). The first failing build picked the compilers (or compiler wrappers?) from /usr/local/bin (and identified them as "Clang").

The build eventually fails with errors like the following:

In file included from /Users/runner/work/elmerfem/elmerfem/ElmerGUI/Application/src/bodypropertyeditor.cpp:41:
In file included from /usr/local/lib/QtGui.framework/Headers/QtGui:3:
In file included from /usr/local/lib/QtGui.framework/Headers/QtGuiDepends:3:
In file included from /usr/local/lib/QtCore.framework/Headers/QtCore:4:
In file included from /usr/local/lib/QtCore.framework/Headers/qglobal.h:13:
In file included from /usr/local/bin/../include/c++/v1/type_traits:425:
In file included from /usr/local/bin/../include/c++/v1/__type_traits/add_pointer.h:17:
In file included from /usr/local/bin/../include/c++/v1/__type_traits/remove_reference.h:13:
/usr/local/bin/../include/c++/v1/cstddef:46:5: error: <cstddef> tried including <stddef.h> but didn't find libc++'s <stddef.h> header.           This usually means that your header search paths are not configured properly.           The header search paths should contain the C++ Standard Library headers before           any C Standard Library, and you are probably using compiler flags that make that           not be the case.
   46 | #   error <cstddef> tried including <stddef.h> but didn't find libc++'s <stddef.h> header. \
      |     ^
/usr/local/bin/../include/c++/v1/cstddef:59:9: error: no member named 'nullptr_t' in the global namespace
   59 | using ::nullptr_t;
      |       ~~^

Edit: It started to build successfully again without any changes to the workflow.

siko1056 pushed a commit to gnu-octave/octave that referenced this pull request Mar 22, 2026
The Homebrew packages for Qt5 and Qt6 started to conflict with each other.
See: Homebrew/brew#21684

This is affecting the CI rules of Octave because the Homebrew package for
gnuplot depends on Qt6 while we try to test building Octave with Qt5.

Work around these conflicts by force installing Qt5 from Homebrew after
installing all other dependencies from Homebrew. That overrides the files for
which there would otherwise be a conflict.

* .github/workflows/make-macos.yaml (install dependencies): Force install Qt
packages after other dependencies.
@mmuetzel
Copy link
Copy Markdown

See also actions/runner-images#13827 for more fallout caused by this change in GitHub CI workflows of multiple projects.

@MikeMcQuaid
Copy link
Copy Markdown
Member Author

I'm not sure. I only noticed that the workflow started to fail without an apparent change on Octave's side.
I'd be happy to adapt the workflow if these conflicts are the expected behavior now. Would brew install --overwrite qt@5 after gnuplot was installed be the "Right Thing" to fix that?

I will investigate/consider making this automatic.

Compared to the last successful run (the day before), CMake seems to be picking a different compiler now. (Not sure if that is the reason for the failing builds though.)
See also actions/runner-images#13827 for more fallout caused by this change in GitHub CI workflows of multiple projects.

Homebrew changing behaviour here is due to (many) user requests over many years. We announced in the release notes that we would be linking in these cases. End-users will have to adjust their e.g. CMake and/or Homebrew configuration accordingly.

@mmuetzel
Copy link
Copy Markdown

Thank you for looking into this and for the clarifications.

End-users will have to adjust their e.g. CMake and/or Homebrew configuration accordingly.

What exactly would an end-user need to do to be able to use the system compilers (and the corresponding headers and libraries) with CMake after these changes?

@MikeMcQuaid
Copy link
Copy Markdown
Member Author

What exactly would an end-user need to do to be able to use the system compilers (and the corresponding headers and libraries) with CMake after these changes?

I'm not a CMake expert any more but: however you would usually configure a tool or compiler in CMake: adjust your PATH, set CMake variables, edit the cache, etc.

@MikeMcQuaid
Copy link
Copy Markdown
Member Author

@mmuetzel for LLVM/Clang specifically, this should help things: #21824

For Qt, it's a bit of a one-off given the split into sub-formulae not applying to versioned ones and it's worth just using --overwrite instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants