compilers: cpp: improve libc++ vs libstdc++ detection (again)

The previous approach wasn't great because you couldn't control what the
detected C++ stdlib impl was. We just had a preference list we tweaked the
searched order for per OS. That doesn't work great for e.g. Gentoo with libc++
or Gentoo Prefix on macOS where we might be using libstdc++ even though the host
is libc++.

Jonathan Wakely, the libstdc++ maintainer, gave a helpful answer on how
to best detect libc++ vs libstdc++ via macros on SO [0]. Implement it.

TL;DR: Use <version> from C++20 if we can, use <ciso646> otherwise. Check for
_LIBCPP_VERSION as libstdc++ doesn't always define a macro.

[0] https://stackoverflow.com/a/31658120

Signed-off-by: Sam James <sam@gentoo.org>
Signed-off-by: Eli Schwartz <eschwartz93@gmail.com>
pull/12965/head
Sam James 8 months ago committed by Eli Schwartz
parent eb74bb8dbf
commit 675b47b069
No known key found for this signature in database
GPG Key ID: CEB167EFB5722BD6
  1. 19
      mesonbuild/compilers/cpp.py

@ -203,17 +203,14 @@ class _StdCPPLibMixin(CompilerMixinBase):
machine = env.machines[self.for_machine]
assert machine is not None, 'for mypy'
# We need to determine whether to use libc++ or libstdc++. We can't
# really know the answer in most cases, only the most likely answer,
# because a user can install things themselves or build custom images.
search_order: T.List[str] = []
if machine.system in {'android', 'darwin', 'dragonfly', 'freebsd', 'netbsd', 'openbsd'}:
search_order = ['c++', 'stdc++']
else:
search_order = ['stdc++', 'c++']
for lib in search_order:
if self.find_library(lib, env, []) is not None:
return search_dirs + [f'-l{lib}']
# https://stackoverflow.com/a/31658120
header = 'version' if self.has_header('<version>', '', env) else 'ciso646'
is_libcxx = self.has_header_symbol(header, '_LIBCPP_VERSION', '', env)[0]
lib = 'c++' if is_libcxx else 'stdc++'
if self.find_library(lib, env, []) is not None:
return search_dirs + [f'-l{lib}']
# TODO: maybe a bug exception?
raise MesonException('Could not detect either libc++ or libstdc++ as your C++ stdlib implementation.')

Loading…
Cancel
Save