|
|
@ -183,7 +183,48 @@ class CPPCompiler(CLikeCompiler, Compiler): |
|
|
|
return opts |
|
|
|
return opts |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ClangCPPCompiler(ClangCompiler, CPPCompiler): |
|
|
|
class _StdCPPLibMixin(CompilerMixinBase): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"""Detect whether to use libc++ or libstdc++.""" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@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. |
|
|
|
|
|
|
|
search_dirs = [f'-L{d}' for d in self.get_compiler_dirs(env, 'libraries')] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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): |
|
|
|
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, |
|
|
|
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, |
|
|
|
info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, |
|
|
|
info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, |
|
|
|
linker: T.Optional['DynamicLinker'] = None, |
|
|
|
linker: T.Optional['DynamicLinker'] = None, |
|
|
@ -249,16 +290,6 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler): |
|
|
|
return libs |
|
|
|
return libs |
|
|
|
return [] |
|
|
|
return [] |
|
|
|
|
|
|
|
|
|
|
|
def language_stdlib_only_link_flags(self, env: 'Environment') -> T.List[str]: |
|
|
|
|
|
|
|
# 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, |
|
|
|
|
|
|
|
search_dirs: T.List[str] = [] |
|
|
|
|
|
|
|
for d in self.get_compiler_dirs(env, 'libraries'): |
|
|
|
|
|
|
|
search_dirs.append(f'-L{d}') |
|
|
|
|
|
|
|
return search_dirs + ['-lstdc++'] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ArmLtdClangCPPCompiler(ClangCPPCompiler): |
|
|
|
class ArmLtdClangCPPCompiler(ClangCPPCompiler): |
|
|
|
|
|
|
|
|
|
|
@ -266,15 +297,7 @@ class ArmLtdClangCPPCompiler(ClangCPPCompiler): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AppleClangCPPCompiler(ClangCPPCompiler): |
|
|
|
class AppleClangCPPCompiler(ClangCPPCompiler): |
|
|
|
def language_stdlib_only_link_flags(self, env: 'Environment') -> T.List[str]: |
|
|
|
pass |
|
|
|
# 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, |
|
|
|
|
|
|
|
search_dirs: T.List[str] = [] |
|
|
|
|
|
|
|
for d in self.get_compiler_dirs(env, 'libraries'): |
|
|
|
|
|
|
|
search_dirs.append(f'-L{d}') |
|
|
|
|
|
|
|
return search_dirs + ['-lc++'] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class EmscriptenCPPCompiler(EmscriptenMixin, ClangCPPCompiler): |
|
|
|
class EmscriptenCPPCompiler(EmscriptenMixin, ClangCPPCompiler): |
|
|
@ -353,7 +376,7 @@ class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler): |
|
|
|
return [] |
|
|
|
return [] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class GnuCPPCompiler(GnuCompiler, CPPCompiler): |
|
|
|
class GnuCPPCompiler(_StdCPPLibMixin, GnuCompiler, CPPCompiler): |
|
|
|
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, |
|
|
|
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, |
|
|
|
info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, |
|
|
|
info: 'MachineInfo', exe_wrapper: T.Optional['ExternalProgram'] = None, |
|
|
|
linker: T.Optional['DynamicLinker'] = None, |
|
|
|
linker: T.Optional['DynamicLinker'] = None, |
|
|
@ -434,16 +457,6 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler): |
|
|
|
def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]: |
|
|
|
def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]: |
|
|
|
return ['-fpch-preprocess', '-include', os.path.basename(header)] |
|
|
|
return ['-fpch-preprocess', '-include', os.path.basename(header)] |
|
|
|
|
|
|
|
|
|
|
|
def language_stdlib_only_link_flags(self, env: 'Environment') -> T.List[str]: |
|
|
|
|
|
|
|
# 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, |
|
|
|
|
|
|
|
search_dirs: T.List[str] = [] |
|
|
|
|
|
|
|
for d in self.get_compiler_dirs(env, 'libraries'): |
|
|
|
|
|
|
|
search_dirs.append(f'-L{d}') |
|
|
|
|
|
|
|
return ['-lstdc++'] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PGICPPCompiler(PGICompiler, CPPCompiler): |
|
|
|
class PGICPPCompiler(PGICompiler, CPPCompiler): |
|
|
|
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, |
|
|
|
def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_machine: MachineChoice, is_cross: bool, |
|
|
|