diff options
Diffstat (limited to 'mesonbuild/compilers/mixins/clang.py')
-rw-r--r-- | mesonbuild/compilers/mixins/clang.py | 85 |
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 |