summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam James <sam@gentoo.org>2024-03-12 23:35:48 +0000
committerEli Schwartz <eschwartz93@gmail.com>2024-03-13 00:56:33 -0400
commit675b47b0692131fae974298829ba807d730ab098 (patch)
treefa3a276a8068b550482e26e32fb98211452c3d8f
parenteb74bb8dbf74ac22a02e369b6622ee0ef8b5d6a3 (diff)
downloadmeson-675b47b0692131fae974298829ba807d730ab098.tar.gz
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>
-rw-r--r--mesonbuild/compilers/cpp.py19
1 files changed, 8 insertions, 11 deletions
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index c5c2735ad..fdf632a8c 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/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.')