Skip to content

Undefined reference issues when mixing Homebrew LLVM 21.1.0 with system libc++ #235411

@chrismile

Description

@chrismile

brew gist-logs <formula> link OR brew config AND brew doctor output

The output below is from the GitHub actions reproducer.

brew config:

HOMEBREW_VERSION: 4.6.7
ORIGIN: https://github.com/Homebrew/brew
HEAD: 02947ea4edbdef5fcce9ee57fa289547f4d096c9
Last commit: 4 days ago
Branch: stable
Core tap JSON: 28 Aug 23:14 UTC
Core cask tap JSON: 28 Aug 23:14 UTC
HOMEBREW_PREFIX: /opt/homebrew
HOMEBREW_CASK_OPTS: ["--no-quarantine"]
HOMEBREW_COLOR: set
HOMEBREW_FORBID_PACKAGES_FROM_PATHS: set
HOMEBREW_MAKE_JOBS: 3
HOMEBREW_NO_AUTO_UPDATE: set
HOMEBREW_NO_INSTALL_CLEANUP: set
Homebrew Ruby: 3.4.5 => /opt/homebrew/Library/Homebrew/vendor/portable-ruby/3.4.5/bin/ruby
CPU: 3-core 64-bit dunno
Clang: 16.0.0 build 1600
Git: 2.50.1 => /opt/homebrew/bin/git
Curl: 8.7.1 => /usr/bin/curl
macOS: 15.5-arm64
CLT: 16.4.0.0.1.1747106510
Xcode: 16.0 => /Applications/Xcode_16.app/Contents/Developer
Rosetta 2: false


brew doctor:

Your system is ready to brew.

Verification

  • My brew doctor output says Your system is ready to brew. and am still able to reproduce my issue.
  • 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.
  • I searched for recent similar issues at https://github.com/Homebrew/homebrew-core/issues?q=is%3Aissue and found no duplicates.
  • My issue is not about a failure to build a formula from source.

What were you trying to do (and why)?

LLVM 21.1.0 seems to have made some changes that make sources compiled with its headers incompatible with older versions of libc++.
See e.g.: llvm/llvm-project#155606

I run into this issue when using clang++ from the Homebrew llvm formula to compile a shared library using std::hash. I have created a small reproducer here using GitHub actions: https://github.com/chrismile/ActionsTestRepo4

I assume that this might be fixable with LDFLAGS="-L/opt/homebrew/opt/llvm/lib/c++", as the library is then linked with the correct version of libc++. But when installing the llvm formula, this message is explicitly printed:

To use the bundled libc++ please use the following LDFLAGS:
  LDFLAGS="-L/opt/homebrew/opt/llvm/lib/c++ -L/opt/homebrew/opt/llvm/lib/unwind -lunwind"
NOTE: You probably want to use the libunwind and libc++ provided by macOS unless you know what you're doing.

I think the notice that one should use "libc++ provided by macOS unless you know what you're doing" is problematic. There seems to be no guarantee that an app compiled with the LLVM version from Homebrew will work with the system libc++.

What happened (include all command output)?

Compilation stage of the reproducer:

/opt/homebrew/opt/llvm/bin/clang++ -Dtestlib_EXPORTS  -O3 -DNDEBUG -arch arm64 -fPIC -MD -MT CMakeFiles/testlib.dir/src/Main.cpp.o -MF CMakeFiles/testlib.dir/src/Main.cpp.o.d -o CMakeFiles/testlib.dir/src/Main.cpp.o -c /Users/runner/work/ActionsTestRepo4/ActionsTestRepo4/src/Main.cpp

Linking stage of the reproducer:

Undefined symbols for architecture arm64:
/opt/homebrew/opt/llvm/bin/clang++ -O3 -DNDEBUG -arch arm64 -dynamiclib -Wl,-headerpad_max_install_names -o libtestlib.dylib -install_name @rpath/libtestlib.dylib CMakeFiles/testlib.dir/src/Main.cpp.o
  "std::__1::__hash_memory(void const*, unsigned long)", referenced from:
[...]

What did you expect to happen?

That when using the recommended options, linking does not fail for a relatively simple program.

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

Reproducer app provided at https://github.com/chrismile/ActionsTestRepo4.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions