aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/compilers/mixins/clang.py
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/compilers/mixins/clang.py')
-rw-r--r--mesonbuild/compilers/mixins/clang.py85
1 files changed, 80 insertions, 5 deletions
diff --git a/mesonbuild/compilers/mixins/clang.py b/mesonbuild/compilers/mixins/clang.py
index e9e83f2..72b987a 100644
--- a/mesonbuild/compilers/mixins/clang.py
+++ b/mesonbuild/compilers/mixins/clang.py
@@ -10,15 +10,22 @@ import shutil
import typing as T
from ... import mesonlib
+from ... import options
from ...linkers.linkers import AppleDynamicLinker, ClangClDynamicLinker, LLVMDynamicLinker, GnuGoldDynamicLinker, \
MoldDynamicLinker, MSVCDynamicLinker
-from ...mesonlib import OptionKey
+from ...options import OptionKey
from ..compilers import CompileCheckMode
from .gnu import GnuLikeCompiler
if T.TYPE_CHECKING:
+ from ...options import MutableKeyedOptionDictType
from ...environment import Environment
from ...dependencies import Dependency # noqa: F401
+ from ..compilers import Compiler
+
+ CompilerMixinBase = Compiler
+else:
+ CompilerMixinBase = object
clang_color_args: T.Dict[str, T.List[str]] = {
'auto': ['-fdiagnostics-color=auto'],
@@ -58,6 +65,8 @@ class ClangCompiler(GnuLikeCompiler):
# linkers don't have base_options.
if isinstance(self.linker, AppleDynamicLinker):
self.base_options.add(OptionKey('b_bitcode'))
+ elif isinstance(self.linker, MSVCDynamicLinker):
+ self.base_options.add(OptionKey('b_vscrt'))
# All Clang backends can also do LLVM IR
self.can_compile_suffixes.add('ll')
@@ -123,7 +132,7 @@ class ClangCompiler(GnuLikeCompiler):
return super().has_function(funcname, prefix, env, extra_args=extra_args,
dependencies=dependencies)
- def openmp_flags(self) -> T.List[str]:
+ def openmp_flags(self, env: Environment) -> T.List[str]:
if mesonlib.version_compare(self.version, '>=3.8.0'):
return ['-fopenmp']
elif mesonlib.version_compare(self.version, '>=3.7.0'):
@@ -133,7 +142,7 @@ class ClangCompiler(GnuLikeCompiler):
return []
def gen_vs_module_defs_args(self, defsfile: str) -> T.List[str]:
- if isinstance(self.linker, (MSVCDynamicLinker)):
+ if isinstance(self.linker, (ClangClDynamicLinker, MSVCDynamicLinker)):
# With MSVC, DLLs only export symbols that are explicitly exported,
# so if a module defs file is specified, we use that to export symbols
return ['-Wl,/DEF:' + defsfile]
@@ -146,7 +155,10 @@ class ClangCompiler(GnuLikeCompiler):
# llvm based) is retargetable, while GCC is not.
#
- # qcld: Qualcomm Snapdragon linker, based on LLVM
+ # eld: Qualcomm's opensource embedded linker
+ if linker == 'eld':
+ return ['-fuse-ld=eld']
+ # qcld: Qualcomm's deprecated linker
if linker == 'qcld':
return ['-fuse-ld=qcld']
if linker == 'mold':
@@ -185,7 +197,7 @@ class ClangCompiler(GnuLikeCompiler):
def linker_to_compiler_args(self, args: T.List[str]) -> T.List[str]:
if isinstance(self.linker, (ClangClDynamicLinker, MSVCDynamicLinker)):
- return [flag if flag.startswith('-Wl,') else f'-Wl,{flag}' for flag in args]
+ return [flag if flag.startswith('-Wl,') or flag.startswith('-fuse-ld=') else f'-Wl,{flag}' for flag in args]
else:
return args
@@ -202,3 +214,66 @@ class ClangCompiler(GnuLikeCompiler):
raise mesonlib.MesonException('clang support for LTO threads requires clang >=4.0')
args.append(f'-flto-jobs={threads}')
return args
+
+
+class ClangCStds(CompilerMixinBase):
+
+ """Mixin class for clang based compilers for setting C standards.
+
+ This is used by both ClangCCompiler and ClangClCompiler, as they share
+ the same versions
+ """
+
+ _C17_VERSION = '>=6.0.0'
+ _C18_VERSION = '>=8.0.0'
+ _C2X_VERSION = '>=9.0.0'
+ _C23_VERSION = '>=18.0.0'
+ _C2Y_VERSION = '>=19.0.0'
+
+ def get_options(self) -> MutableKeyedOptionDictType:
+ opts = super().get_options()
+ stds = ['c89', 'c99', 'c11']
+ # https://releases.llvm.org/6.0.0/tools/clang/docs/ReleaseNotes.html
+ # https://en.wikipedia.org/wiki/Xcode#Latest_versions
+ if mesonlib.version_compare(self.version, self._C17_VERSION):
+ stds += ['c17']
+ if mesonlib.version_compare(self.version, self._C18_VERSION):
+ stds += ['c18']
+ if mesonlib.version_compare(self.version, self._C2X_VERSION):
+ stds += ['c2x']
+ if mesonlib.version_compare(self.version, self._C23_VERSION):
+ stds += ['c23']
+ if mesonlib.version_compare(self.version, self._C2Y_VERSION):
+ stds += ['c2y']
+ key = self.form_compileropt_key('std')
+ std_opt = opts[key]
+ assert isinstance(std_opt, options.UserStdOption), 'for mypy'
+ std_opt.set_versions(stds, gnu=True)
+ return opts
+
+
+class ClangCPPStds(CompilerMixinBase):
+
+ """Mixin class for clang based compilers for setting C++ standards.
+
+ This is used by the ClangCPPCompiler
+ """
+
+ _CPP23_VERSION = '>=12.0.0'
+ _CPP26_VERSION = '>=17.0.0'
+
+ def get_options(self) -> MutableKeyedOptionDictType:
+ opts = super().get_options()
+ stds = [
+ 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z', 'c++2a',
+ 'c++20',
+ ]
+ if mesonlib.version_compare(self.version, self._CPP23_VERSION):
+ stds.append('c++23')
+ if mesonlib.version_compare(self.version, self._CPP26_VERSION):
+ stds.append('c++26')
+ key = self.form_compileropt_key('std')
+ std_opt = opts[key]
+ assert isinstance(std_opt, options.UserStdOption), 'for mypy'
+ std_opt.set_versions(stds, gnu=True)
+ return opts