aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/compilers/cpp.py
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2023-06-29 09:28:19 -0700
committerDylan Baker <dylan@pnwbakers.com>2023-06-29 13:36:47 -0700
commita227768b378caa7a5f9faf42936bdad8cd6123dd (patch)
treeba330c60ae13e793c0aaa12edb11afbbe249116b /mesonbuild/compilers/cpp.py
parentf58bd2ae11429ee7aa911de631faece718fbfe14 (diff)
downloadmeson-a227768b378caa7a5f9faf42936bdad8cd6123dd.zip
meson-a227768b378caa7a5f9faf42936bdad8cd6123dd.tar.gz
meson-a227768b378caa7a5f9faf42936bdad8cd6123dd.tar.bz2
compilers/cpp: try to do a better job of detecting libc++ vs libstdc++
Currently, we hardcode libc++ for MacOS (and derivatives), and libstdc++ for all other cases. Clang had some hackery to make this work in many cases. However, this doesn't always work, namely if you try to to use Rust as the linker when libc++ is required. This implementation does, as an optimization, provide a hardcoded list of OSes we know always use libc++, and otherwise will attempt to detect it. As a second optimization, the detected values are cached, so the lookup is only done once fixes: #11921
Diffstat (limited to 'mesonbuild/compilers/cpp.py')
-rw-r--r--mesonbuild/compilers/cpp.py34
1 files changed, 31 insertions, 3 deletions
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index bec4529..081f656 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -187,13 +187,41 @@ class _StdCPPLibMixin(CompilerMixinBase):
"""Detect whether to use libc++ or libstdc++."""
- def language_stdlib_only_link_flags(self, env: 'Environment') -> T.List[str]:
+ @functools.lru_cache(None)
+ def language_stdlib_only_link_flags(self, env: Environment) -> T.List[str]:
+ """Detect the C++ stdlib and default search dirs
+
+ As an optimization, this method will cache the value, to avoid building the same values over and over
+
+ :param env: An Environment object
+ :raises MesonException: If a stdlib cannot be determined
+ """
+
# We need to apply the search prefix here, as these link arguments may
# be passed to a different compiler with a different set of default
# search paths, such as when using Clang for C/C++ and gfortran for
- # fortran,
+ # fortran.
search_dirs = [f'-L{d}' for d in self.get_compiler_dirs(env, 'libraries')]
- return search_dirs + ['-lstdc++']
+
+ machine = env.machines[self.for_machine]
+ assert machine is not None, 'for mypy'
+
+ # We need to determine whether to us libc++ or libstdc++ In some cases
+ # we know the answer, so we'll hardcode those cases. There are other
+ # cases where we can't know the answer just by looking at the OS, namely
+ # on Linux. In that case we have to fallback to manually checking
+ stdlib: str
+ if machine.system in {'android', 'darwin', 'dragonfly', 'freebsd', 'netbsd', 'openbsd'}:
+ stdlib = 'c++'
+ elif self.find_library('c++', env, []) is not None:
+ stdlib = 'c++'
+ elif self.find_library('stdc++', env, []) is not None:
+ stdlib = 'stdc++'
+ else:
+ # TODO: maybe a bug exception?
+ raise MesonException('Could not detect either libc++ or libstdc++ as your C++ stdlib implementation.')
+
+ return search_dirs + [f'-l{stdlib}']
class ClangCPPCompiler(_StdCPPLibMixin, ClangCompiler, CPPCompiler):