Skip to content

Commit 675b47b

Browse files
thesamesameli-schwartz
authored andcommitted
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 <[email protected]> Signed-off-by: Eli Schwartz <[email protected]>
1 parent eb74bb8 commit 675b47b

File tree

1 file changed

+8
-11
lines changed

1 file changed

+8
-11
lines changed

mesonbuild/compilers/cpp.py

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -203,17 +203,14 @@ def language_stdlib_only_link_flags(self, env: Environment) -> T.List[str]:
203203
machine = env.machines[self.for_machine]
204204
assert machine is not None, 'for mypy'
205205

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

0 commit comments

Comments
 (0)