aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/compilers
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/compilers')
-rw-r--r--mesonbuild/compilers/c.py142
-rw-r--r--mesonbuild/compilers/compilers.py133
-rw-r--r--mesonbuild/compilers/cpp.py204
-rw-r--r--mesonbuild/compilers/cuda.py21
-rw-r--r--mesonbuild/compilers/d.py12
-rw-r--r--mesonbuild/compilers/fortran.py42
-rw-r--r--mesonbuild/compilers/mixins/arm.py7
-rw-r--r--mesonbuild/compilers/mixins/clang.py7
-rw-r--r--mesonbuild/compilers/mixins/clike.py7
-rw-r--r--mesonbuild/compilers/mixins/elbrus.py6
-rw-r--r--mesonbuild/compilers/mixins/emscripten.py8
-rw-r--r--mesonbuild/compilers/mixins/gnu.py14
-rw-r--r--mesonbuild/compilers/mixins/intel.py5
-rw-r--r--mesonbuild/compilers/mixins/islinker.py6
-rw-r--r--mesonbuild/compilers/mixins/pgi.py3
-rw-r--r--mesonbuild/compilers/mixins/visualstudio.py2
-rw-r--r--mesonbuild/compilers/objc.py2
-rw-r--r--mesonbuild/compilers/objcpp.py2
-rw-r--r--mesonbuild/compilers/rust.py21
-rw-r--r--mesonbuild/compilers/swift.py2
-rw-r--r--mesonbuild/compilers/vala.py8
21 files changed, 360 insertions, 294 deletions
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index 985f6f3..311e65a 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -16,7 +16,7 @@ import os.path
import typing as T
from .. import coredata
-from ..mesonlib import MachineChoice, MesonException, mlog, version_compare
+from ..mesonlib import MachineChoice, MesonException, mlog, version_compare, OptionKey
from ..linkers import LinkerEnvVarsMixin
from .c_function_attributes import C_FUNC_ATTRIBUTES
from .mixins.clike import CLikeCompiler
@@ -39,7 +39,7 @@ from .compilers import (
)
if T.TYPE_CHECKING:
- from ..coredata import OptionDictType
+ from ..coredata import KeyedOptionDictType
from ..dependencies import Dependency, ExternalProgram
from ..envconfig import MachineInfo
from ..environment import Environment
@@ -95,10 +95,10 @@ class CCompiler(CLikeCompiler, Compiler):
return self.compiles(t.format(**fargs), env, extra_args=extra_args,
dependencies=dependencies)
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = super().get_options()
opts.update({
- 'std': coredata.UserComboOption(
+ OptionKey('std', machine=self.for_machine, lang=self.language): coredata.UserComboOption(
'C langauge standard to use',
['none'],
'none',
@@ -119,7 +119,7 @@ class _ClangCStds(CompilerMixinBase):
_C18_VERSION = '>=8.0.0'
_C2X_VERSION = '>=9.0.0'
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = super().get_options()
c_stds = ['c89', 'c99', 'c11']
g_stds = ['gnu89', 'gnu99', 'gnu11']
@@ -134,7 +134,7 @@ class _ClangCStds(CompilerMixinBase):
if version_compare(self.version, self._C2X_VERSION):
c_stds += ['c2x']
g_stds += ['gnu2x']
- opts['std'].choices = ['none'] + c_stds + g_stds # type: ignore
+ opts[OptionKey('std', machine=self.for_machine, lang=self.language)].choices = ['none'] + c_stds + g_stds
return opts
@@ -153,28 +153,28 @@ class ClangCCompiler(_ClangCStds, ClangCompiler, CCompiler):
'2': default_warn_args + ['-Wextra'],
'3': default_warn_args + ['-Wextra', '-Wpedantic']}
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = super().get_options()
if self.info.is_windows() or self.info.is_cygwin():
opts.update({
- 'winlibs': coredata.UserArrayOption(
+ OptionKey('winlibs', machine=self.for_machine, lang=self.language): coredata.UserArrayOption(
'Standard Win libraries to link against',
gnu_winlibs,
),
})
return opts
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ std = options[OptionKey('std', machine=self.for_machine, lang=self.language)]
if std.value != 'none':
args.append('-std=' + std.value)
return args
- def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
if self.info.is_windows() or self.info.is_cygwin():
# without a typedict mypy can't understand this.
- libs = options['winlibs'].value.copy()
+ libs = options[OptionKey('winlibs', machine=self.for_machine, lang=self.language)].value.copy()
assert isinstance(libs, list)
for l in libs:
assert isinstance(l, str)
@@ -223,19 +223,20 @@ class ArmclangCCompiler(ArmclangCompiler, CCompiler):
'2': default_warn_args + ['-Wextra'],
'3': default_warn_args + ['-Wextra', '-Wpedantic']}
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = CCompiler.get_options(self)
- opts['std'].choices = ['none', 'c90', 'c99', 'c11', 'gnu90', 'gnu99', 'gnu11'] # type: ignore
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ opts[key].choices = ['none', 'c90', 'c99', 'c11', 'gnu90', 'gnu99', 'gnu11']
return opts
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ std = options[OptionKey('std', machine=self.for_machine, lang=self.language)]
if std.value != 'none':
args.append('-std=' + std.value)
return args
- def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return []
@@ -257,7 +258,7 @@ class GnuCCompiler(GnuCompiler, CCompiler):
'2': default_warn_args + ['-Wextra'],
'3': default_warn_args + ['-Wextra', '-Wpedantic']}
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = CCompiler.get_options(self)
c_stds = ['c89', 'c99', 'c11']
g_stds = ['gnu89', 'gnu99', 'gnu11']
@@ -267,27 +268,28 @@ class GnuCCompiler(GnuCompiler, CCompiler):
if version_compare(self.version, self._C2X_VERSION):
c_stds += ['c2x']
g_stds += ['gnu2x']
- opts['std'].choices = ['none'] + c_stds + g_stds # type: ignore
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ opts[key].choices = ['none'] + c_stds + g_stds
if self.info.is_windows() or self.info.is_cygwin():
opts.update({
- 'winlibs': coredata.UserArrayOption(
+ key.evolve('winlibs'): coredata.UserArrayOption(
'Standard Win libraries to link against',
gnu_winlibs,
),
})
return opts
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ std = options[OptionKey('std', lang=self.language, machine=self.for_machine)]
if std.value != 'none':
args.append('-std=' + std.value)
return args
- def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
if self.info.is_windows() or self.info.is_cygwin():
# without a typeddict mypy can't figure this out
- libs = options['winlibs'].value.copy()
+ libs: T.List[str] = options[OptionKey('winlibs', lang=self.language, machine=self.for_machine)].value.copy()
assert isinstance(libs, list)
for l in libs:
assert isinstance(l, str)
@@ -331,9 +333,9 @@ class ElbrusCCompiler(GnuCCompiler, ElbrusCompiler):
ElbrusCompiler.__init__(self)
# It does support some various ISO standards and c/gnu 90, 9x, 1x in addition to those which GNU CC supports.
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = CCompiler.get_options(self)
- opts['std'].choices = [ # type: ignore
+ opts[OptionKey('std', machine=self.for_machine, lang=self.language)].choices = [
'none', 'c89', 'c90', 'c9x', 'c99', 'c1x', 'c11',
'gnu89', 'gnu90', 'gnu9x', 'gnu99', 'gnu1x', 'gnu11',
'iso9899:2011', 'iso9899:1990', 'iso9899:199409', 'iso9899:1999',
@@ -368,18 +370,18 @@ class IntelCCompiler(IntelGnuLikeCompiler, CCompiler):
'2': default_warn_args + ['-Wextra'],
'3': default_warn_args + ['-Wextra']}
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = CCompiler.get_options(self)
c_stds = ['c89', 'c99']
g_stds = ['gnu89', 'gnu99']
if version_compare(self.version, '>=16.0.0'):
c_stds += ['c11']
- opts['std'].choices = ['none'] + c_stds + g_stds # type: ignore
+ opts[OptionKey('std', machine=self.for_machine, lang=self.language)].choices = ['none'] + c_stds + g_stds
return opts
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ std = options[OptionKey('std', machine=self.for_machine, lang=self.language)]
if std.value != 'none':
args.append('-std=' + std.value)
return args
@@ -389,19 +391,20 @@ class VisualStudioLikeCCompilerMixin(CompilerMixinBase):
"""Shared methods that apply to MSVC-like C compilers."""
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = super().get_options()
opts.update({
- 'winlibs': coredata.UserArrayOption(
+ OptionKey('winlibs', machine=self.for_machine, lang=self.language): coredata.UserArrayOption(
'Windows libs to link against.',
msvc_winlibs,
),
})
return opts
- def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
# need a TypeDict to make this work
- libs = options['winlibs'].value.copy()
+ key = OptionKey('winlibs', machine=self.for_machine, lang=self.language)
+ libs = options[key].value.copy()
assert isinstance(libs, list)
for l in libs:
assert isinstance(l, str)
@@ -423,7 +426,7 @@ class VisualStudioCCompiler(MSVCCompiler, VisualStudioLikeCCompilerMixin, CCompi
full_version=full_version)
MSVCCompiler.__init__(self, target)
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = super().get_options()
c_stds = ['c89', 'c99']
# Need to have these to be compatible with projects
@@ -436,12 +439,13 @@ class VisualStudioCCompiler(MSVCCompiler, VisualStudioLikeCCompilerMixin, CCompi
if version_compare(self.version, self._C17_VERSION):
c_stds += ['c17', 'c18']
g_stds += ['gnu17', 'gnu18']
- opts['std'].choices = ['none'] + c_stds + g_stds # type: ignore
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ opts[key].choices = ['none'] + c_stds + g_stds
return opts
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ std = options[OptionKey('std', machine=self.for_machine, lang=self.language)]
if std.value.startswith('gnu'):
mlog.log_once(
'cl.exe does not actually support gnu standards, and meson '
@@ -466,8 +470,9 @@ class ClangClCCompiler(_ClangCStds, ClangClCompiler, VisualStudioLikeCCompilerMi
full_version=full_version)
ClangClCompiler.__init__(self, target)
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
- std = options['std'].value
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ std = options[key].value
if std != "none":
return ['/clang:-std={}'.format(std)]
return []
@@ -487,14 +492,16 @@ class IntelClCCompiler(IntelVisualStudioLikeCompiler, VisualStudioLikeCCompilerM
full_version=full_version)
IntelVisualStudioLikeCompiler.__init__(self, target)
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = super().get_options()
- opts['std'].choices = ['none', 'c89', 'c99', 'c11'] # type: ignore
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ opts[key].choices = ['none', 'c89', 'c99', 'c11']
return opts
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ std = options[key]
if std.value == 'c89':
mlog.log_once("ICL doesn't explicitly implement c89, setting the standard to 'none', which is close.")
elif std.value != 'none':
@@ -513,14 +520,16 @@ class ArmCCompiler(ArmCompiler, CCompiler):
full_version=full_version)
ArmCompiler.__init__(self)
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = CCompiler.get_options(self)
- opts['std'].choices = ['none', 'c89', 'c99', 'c11'] # type: ignore
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ opts[key].choices = ['none', 'c89', 'c99', 'c11']
return opts
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ std = options[key]
if std.value != 'none':
args.append('--' + std.value)
return args
@@ -540,17 +549,19 @@ class CcrxCCompiler(CcrxCompiler, CCompiler):
def get_always_args(self) -> T.List[str]:
return ['-nologo']
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = CCompiler.get_options(self)
- opts['std'].choices = ['none', 'c89', 'c99'] # type: ignore
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ opts[key].choices = ['none', 'c89', 'c99']
return opts
def get_no_stdinc_args(self) -> T.List[str]:
return []
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ std = options[key]
if std.value == 'c89':
args.append('-lang=c')
elif std.value == 'c99':
@@ -585,17 +596,19 @@ class Xc16CCompiler(Xc16Compiler, CCompiler):
info, exe_wrapper, linker=linker, full_version=full_version)
Xc16Compiler.__init__(self)
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = CCompiler.get_options(self)
- opts['std'].choices = ['none', 'c89', 'c99', 'gnu89', 'gnu99'] # type: ignore
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ opts[key].choices = ['none', 'c89', 'c99', 'gnu89', 'gnu99']
return opts
def get_no_stdinc_args(self) -> T.List[str]:
return []
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['c_std']
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ std = options[key]
if std.value != 'none':
args.append('-ansi')
args.append('-std=' + std.value)
@@ -628,12 +641,13 @@ class CompCertCCompiler(CompCertCompiler, CCompiler):
info, exe_wrapper, linker=linker, full_version=full_version)
CompCertCompiler.__init__(self)
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = CCompiler.get_options(self)
- opts['std'].choices = ['none', 'c89', 'c99'] # type: ignore
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ opts[key].choices = ['none', 'c89', 'c99']
return opts
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return []
def get_no_optimization_args(self) -> T.List[str]:
@@ -664,17 +678,19 @@ class C2000CCompiler(C2000Compiler, CCompiler):
def get_always_args(self) -> T.List[str]:
return []
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = CCompiler.get_options(self)
- opts['std'].choices = ['none', 'c89', 'c99', 'c11'] # type: ignore
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ opts[key].choices = ['none', 'c89', 'c99', 'c11']
return opts
def get_no_stdinc_args(self) -> T.List[str]:
return []
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['c_std']
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ std = options[key]
if std.value != 'none':
args.append('--' + std.value)
return args
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 0bd2b4c..234ce06 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -25,7 +25,7 @@ from .. import mesonlib
from ..linkers import LinkerEnvVarsMixin
from ..mesonlib import (
EnvironmentException, MachineChoice, MesonException,
- Popen_safe, split_args, LibType, TemporaryDirectoryWinProof
+ Popen_safe, split_args, LibType, TemporaryDirectoryWinProof, OptionKey,
)
from ..envconfig import (
get_env_var
@@ -35,7 +35,7 @@ from ..arglist import CompilerArgs
if T.TYPE_CHECKING:
from ..build import BuildTarget
- from ..coredata import OptionDictType
+ from ..coredata import OptionDictType, KeyedOptionDictType
from ..envconfig import MachineInfo
from ..environment import Environment
from ..linkers import DynamicLinker # noqa: F401
@@ -265,36 +265,32 @@ cuda_debug_args = {False: [],
clike_debug_args = {False: [],
True: ['-g']} # type: T.Dict[bool, T.List[str]]
-base_options = {'b_pch': coredata.UserBooleanOption('Use precompiled headers', True),
- 'b_lto': coredata.UserBooleanOption('Use link time optimization', False),
- 'b_sanitize': coredata.UserComboOption('Code sanitizer to use',
- ['none', 'address', 'thread', 'undefined', 'memory', 'address,undefined'],
- 'none'),
- 'b_lundef': coredata.UserBooleanOption('Use -Wl,--no-undefined when linking', True),
- 'b_asneeded': coredata.UserBooleanOption('Use -Wl,--as-needed when linking', True),
- 'b_pgo': coredata.UserComboOption('Use profile guided optimization',
- ['off', 'generate', 'use'],
- 'off'),
- 'b_coverage': coredata.UserBooleanOption('Enable coverage tracking.',
- False),
- 'b_colorout': coredata.UserComboOption('Use colored output',
- ['auto', 'always', 'never'],
- 'always'),
- 'b_ndebug': coredata.UserComboOption('Disable asserts',
- ['true', 'false', 'if-release'], 'false'),
- 'b_staticpic': coredata.UserBooleanOption('Build static libraries as position independent',
- True),
- 'b_pie': coredata.UserBooleanOption('Build executables as position independent',
- False),
- 'b_bitcode': coredata.UserBooleanOption('Generate and embed bitcode (only macOS/iOS/tvOS)',
- False),
- 'b_vscrt': coredata.UserComboOption('VS run-time library type to use.',
- ['none', 'md', 'mdd', 'mt', 'mtd', 'from_buildtype', 'static_from_buildtype'],
- 'from_buildtype'),
- } # type: OptionDictType
-
-def option_enabled(boptions: T.List[str], options: 'OptionDictType',
- option: str) -> bool:
+base_options: 'KeyedOptionDictType' = {
+ OptionKey('b_pch'): coredata.UserBooleanOption('Use precompiled headers', True),
+ OptionKey('b_lto'): coredata.UserBooleanOption('Use link time optimization', False),
+ OptionKey('b_sanitize'): coredata.UserComboOption('Code sanitizer to use',
+ ['none', 'address', 'thread', 'undefined', 'memory', 'address,undefined'],
+ 'none'),
+ OptionKey('b_lundef'): coredata.UserBooleanOption('Use -Wl,--no-undefined when linking', True),
+ OptionKey('b_asneeded'): coredata.UserBooleanOption('Use -Wl,--as-needed when linking', True),
+ OptionKey('b_pgo'): coredata.UserComboOption('Use profile guided optimization',
+ ['off', 'generate', 'use'],
+ 'off'),
+ OptionKey('b_coverage'): coredata.UserBooleanOption('Enable coverage tracking.', False),
+ OptionKey('b_colorout'): coredata.UserComboOption('Use colored output',
+ ['auto', 'always', 'never'],
+ 'always'),
+ OptionKey('b_ndebug'): coredata.UserComboOption('Disable asserts', ['true', 'false', 'if-release'], 'false'),
+ OptionKey('b_staticpic'): coredata.UserBooleanOption('Build static libraries as position independent', True),
+ OptionKey('b_pie'): coredata.UserBooleanOption('Build executables as position independent', False),
+ OptionKey('b_bitcode'): coredata.UserBooleanOption('Generate and embed bitcode (only macOS/iOS/tvOS)', False),
+ OptionKey('b_vscrt'): coredata.UserComboOption('VS run-time library type to use.',
+ ['none', 'md', 'mdd', 'mt', 'mtd', 'from_buildtype', 'static_from_buildtype'],
+ 'from_buildtype'),
+}
+
+def option_enabled(boptions: T.Set[OptionKey], options: 'KeyedOptionDictType',
+ option: OptionKey) -> bool:
try:
if option not in boptions:
return False
@@ -304,23 +300,23 @@ def option_enabled(boptions: T.List[str], options: 'OptionDictType',
except KeyError:
return False
-def get_base_compile_args(options: 'OptionDictType', compiler: 'Compiler') -> T.List[str]:
+def get_base_compile_args(options: 'KeyedOptionDictType', compiler: 'Compiler') -> T.List[str]:
args = [] # type T.List[str]
try:
- if options['b_lto'].value:
+ if options[OptionKey('b_lto')].value:
args.extend(compiler.get_lto_compile_args())
except KeyError:
pass
try:
- args += compiler.get_colorout_args(options['b_colorout'].value)
+ args += compiler.get_colorout_args(options[OptionKey('b_colorout')].value)
except KeyError:
pass
try:
- args += compiler.sanitizer_compile_args(options['b_sanitize'].value)
+ args += compiler.sanitizer_compile_args(options[OptionKey('b_sanitize')].value)
except KeyError:
pass
try:
- pgo_val = options['b_pgo'].value
+ pgo_val = options[OptionKey('b_pgo')].value
if pgo_val == 'generate':
args.extend(compiler.get_profile_generate_args())
elif pgo_val == 'use':
@@ -328,23 +324,23 @@ def get_base_compile_args(options: 'OptionDictType', compiler: 'Compiler') -> T.
except KeyError:
pass
try:
- if options['b_coverage'].value:
+ if options[OptionKey('b_coverage')].value:
args += compiler.get_coverage_args()
except KeyError:
pass
try:
- if (options['b_ndebug'].value == 'true' or
- (options['b_ndebug'].value == 'if-release' and
- options['buildtype'].value in {'release', 'plain'})):
+ if (options[OptionKey('b_ndebug')].value == 'true' or
+ (options[OptionKey('b_ndebug')].value == 'if-release' and
+ options[OptionKey('buildtype')].value in {'release', 'plain'})):
args += compiler.get_disable_assert_args()
except KeyError:
pass
# This does not need a try...except
- if option_enabled(compiler.base_options, options, 'b_bitcode'):
+ if option_enabled(compiler.base_options, options, OptionKey('b_bitcode')):
args.append('-fembed-bitcode')
try:
- crt_val = options['b_vscrt'].value
- buildtype = options['buildtype'].value
+ crt_val = options[OptionKey('b_vscrt')].value
+ buildtype = options[OptionKey('buildtype')].value
try:
args += compiler.get_crt_compile_args(crt_val, buildtype)
except AttributeError:
@@ -353,20 +349,20 @@ def get_base_compile_args(options: 'OptionDictType', compiler: 'Compiler') -> T.
pass
return args
-def get_base_link_args(options: 'OptionDictType', linker: 'Compiler',
+def get_base_link_args(options: 'KeyedOptionDictType', linker: 'Compiler',
is_shared_module: bool) -> T.List[str]:
args = [] # type: T.List[str]
try:
- if options['b_lto'].value:
+ if options[OptionKey('b_lto')].value:
args.extend(linker.get_lto_link_args())
except KeyError:
pass
try:
- args += linker.sanitizer_link_args(options['b_sanitize'].value)
+ args += linker.sanitizer_link_args(options[OptionKey('b_sanitize')].value)
except KeyError:
pass
try:
- pgo_val = options['b_pgo'].value
+ pgo_val = options[OptionKey('b_pgo')].value
if pgo_val == 'generate':
args.extend(linker.get_profile_generate_args())
elif pgo_val == 'use':
@@ -374,13 +370,13 @@ def get_base_link_args(options: 'OptionDictType', linker: 'Compiler',
except KeyError:
pass
try:
- if options['b_coverage'].value:
+ if options[OptionKey('b_coverage')].value:
args += linker.get_coverage_link_args()
except KeyError:
pass
- as_needed = option_enabled(linker.base_options, options, 'b_asneeded')
- bitcode = option_enabled(linker.base_options, options, 'b_bitcode')
+ as_needed = option_enabled(linker.base_options, options, OptionKey('b_asneeded'))
+ bitcode = option_enabled(linker.base_options, options, OptionKey('b_bitcode'))
# Shared modules cannot be built with bitcode_bundle because
# -bitcode_bundle is incompatible with -undefined and -bundle
if bitcode and not is_shared_module:
@@ -394,14 +390,14 @@ def get_base_link_args(options: 'OptionDictType', linker: 'Compiler',
if not bitcode:
args.extend(linker.headerpad_args())
if (not is_shared_module and
- option_enabled(linker.base_options, options, 'b_lundef')):
+ option_enabled(linker.base_options, options, OptionKey('b_lundef'))):
args.extend(linker.no_undefined_link_args())
else:
args.extend(linker.get_allow_undefined_link_args())
try:
- crt_val = options['b_vscrt'].value
- buildtype = options['buildtype'].value
+ crt_val = options[OptionKey('b_vscrt')].value
+ buildtype = options[OptionKey('buildtype')].value
try:
args += linker.get_crt_link_args(crt_val, buildtype)
except AttributeError:
@@ -477,7 +473,7 @@ class Compiler(metaclass=abc.ABCMeta):
self.version = version
self.full_version = full_version
self.for_machine = for_machine
- self.base_options = [] # type: T.List[str]
+ self.base_options: T.Set[OptionKey] = set()
self.linker = linker
self.info = info
self.is_cross = is_cross
@@ -596,13 +592,13 @@ class Compiler(metaclass=abc.ABCMeta):
is_cross: bool) -> T.List[str]:
return self.linker.get_args_from_envvars(for_machine, is_cross)
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
return {}
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return []
- def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return self.linker.get_option_args(options)
def check_header(self, hname: str, prefix: str, env: 'Environment', *,
@@ -826,7 +822,7 @@ class Compiler(metaclass=abc.ABCMeta):
def get_std_shared_lib_link_args(self) -> T.List[str]:
return self.linker.get_std_shared_lib_args()
- def get_std_shared_module_link_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_std_shared_module_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return self.linker.get_std_shared_module_args(options)
def get_link_whole_for(self, args: T.List[str]) -> T.List[str]:
@@ -1243,17 +1239,19 @@ def get_args_from_envvars(lang: str,
def get_global_options(lang: str,
comp: T.Type[Compiler],
for_machine: MachineChoice,
- is_cross: bool) -> 'OptionDictType':
+ is_cross: bool) -> 'KeyedOptionDictType':
"""Retreive options that apply to all compilers for a given language."""
description = 'Extra arguments passed to the {}'.format(lang)
- opts = {
- 'args': coredata.UserArrayOption(
+ argkey = OptionKey('args', lang=lang, machine=for_machine)
+ largkey = argkey.evolve('link_args')
+ opts: 'KeyedOptionDictType' = {
+ argkey: coredata.UserArrayOption(
description + ' compiler',
[], split_args=True, user_input=True, allow_dups=True),
- 'link_args': coredata.UserArrayOption(
+ largkey: coredata.UserArrayOption(
description + ' linker',
[], split_args=True, user_input=True, allow_dups=True),
- } # type: OptionDictType
+ }
# Get from env vars.
compile_args, link_args = get_args_from_envvars(
@@ -1262,10 +1260,7 @@ def get_global_options(lang: str,
is_cross,
comp.INVOKES_LINKER)
- for k, o in opts.items():
- if k == 'args':
- o.set_value(compile_args)
- elif k == 'link_args':
- o.set_value(link_args)
+ opts[argkey].set_value(compile_args)
+ opts[largkey].set_value(link_args)
return opts
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index 607bea7..2e94e48 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -19,7 +19,7 @@ import typing as T
from .. import coredata
from .. import mlog
-from ..mesonlib import MesonException, MachineChoice, version_compare
+from ..mesonlib import MesonException, MachineChoice, version_compare, OptionKey
from ..linkers import LinkerEnvVarsMixin
from .compilers import (
@@ -42,7 +42,7 @@ from .mixins.pgi import PGICompiler
from .mixins.emscripten import EmscriptenMixin
if T.TYPE_CHECKING:
- from ..coredata import OptionDictType
+ from ..coredata import KeyedOptionDictType
from ..dependencies import Dependency, ExternalProgram
from ..envconfig import MachineInfo
from ..environment import Environment
@@ -169,10 +169,11 @@ class CPPCompiler(CLikeCompiler, Compiler):
raise MesonException('C++ Compiler does not support -std={}'.format(cpp_std))
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = super().get_options()
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
opts.update({
- 'std': coredata.UserComboOption(
+ key: coredata.UserComboOption(
'C++ language standard to use',
['none'],
'none',
@@ -196,47 +197,50 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler):
'2': default_warn_args + ['-Wextra'],
'3': default_warn_args + ['-Wextra', '-Wpedantic']}
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = CPPCompiler.get_options(self)
+ key = OptionKey('key', machine=self.for_machine, lang=self.language)
opts.update({
- 'eh': coredata.UserComboOption(
+ key.evolve('eh'): coredata.UserComboOption(
'C++ exception handling type.',
['none', 'default', 'a', 's', 'sc'],
'default',
),
- 'rtti': coredata.UserBooleanOption('Enable RTTI', True),
+ key.evolve('rtti'): coredata.UserBooleanOption('Enable RTTI', True),
})
- opts['std'].choices = [ # type: ignore
+ opts[key.evolve('std')].choices = [
'none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z',
'c++2a', 'c++20', 'gnu++11', 'gnu++14', 'gnu++17', 'gnu++1z',
'gnu++2a', 'gnu++20',
]
if self.info.is_windows() or self.info.is_cygwin():
opts.update({
- 'winlibs': coredata.UserArrayOption(
+ key.evolve('winlibs'): coredata.UserArrayOption(
'Standard Win libraries to link against',
gnu_winlibs,
),
})
return opts
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ std = options[key]
if std.value != 'none':
args.append(self._find_best_cpp_std(std.value))
- non_msvc_eh_options(options['eh'].value, args)
+ non_msvc_eh_options(options[key.evolve('eh')].value, args)
- if not options['rtti'].value:
+ if not options[key.evolve('rtti')].value:
args.append('-fno-rtti')
return args
- def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
if self.info.is_windows() or self.info.is_cygwin():
# without a typedict mypy can't understand this.
- libs = options['winlibs'].value.copy()
+ key = OptionKey('winlibs', machine=self.for_machine, lang=self.language)
+ libs = options[key].value.copy()
assert isinstance(libs, list)
for l in libs:
assert isinstance(l, str)
@@ -265,9 +269,10 @@ class EmscriptenCPPCompiler(EmscriptenMixin, LinkerEnvVarsMixin, ClangCPPCompile
defines=defines, full_version=full_version)
self.id = 'emscripten'
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ std = options[key]
if std.value != 'none':
args.append(self._find_best_cpp_std(std.value))
return args
@@ -287,32 +292,34 @@ class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler):
'2': default_warn_args + ['-Wextra'],
'3': default_warn_args + ['-Wextra', '-Wpedantic']}
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = CPPCompiler.get_options(self)
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
opts.update({
- 'eh': coredata.UserComboOption(
+ key.evolve('eh'): coredata.UserComboOption(
'C++ exception handling type.',
['none', 'default', 'a', 's', 'sc'],
'default',
),
})
- opts['std'].choices = [ # type: ignore
+ opts[key].choices = [
'none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'gnu++98',
'gnu++03', 'gnu++11', 'gnu++14', 'gnu++17',
]
return opts
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ std = options[key]
if std.value != 'none':
args.append('-std=' + std.value)
- non_msvc_eh_options(options['eh'].value, args)
+ non_msvc_eh_options(options[key.evolve('eh')].value, args)
return args
- def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return []
@@ -331,53 +338,56 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler):
'2': default_warn_args + ['-Wextra'],
'3': default_warn_args + ['-Wextra', '-Wpedantic']}
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
opts = CPPCompiler.get_options(self)
opts.update({
- 'eh': coredata.UserComboOption(
+ key.evolve('eh'): coredata.UserComboOption(
'C++ exception handling type.',
['none', 'default', 'a', 's', 'sc'],
'default',
),
- 'rtti': coredata.UserBooleanOption('Enable RTTI', True),
- 'debugstl': coredata.UserBooleanOption(
+ key.evolve('rtti'): coredata.UserBooleanOption('Enable RTTI', True),
+ key.evolve('debugstl'): coredata.UserBooleanOption(
'STL debug mode',
False,
)
})
- opts['std'].choices = [ # type: ignore
+ opts[key].choices = [
'none', 'c++98', 'c++03', 'c++11', 'c++14', 'c++17', 'c++1z',
'c++2a', 'c++20', 'gnu++03', 'gnu++11', 'gnu++14', 'gnu++17',
'gnu++1z', 'gnu++2a', 'gnu++20',
]
if self.info.is_windows() or self.info.is_cygwin():
opts.update({
- 'winlibs': coredata.UserArrayOption(
+ key.evolve('winlibs'): coredata.UserArrayOption(
'Standard Win libraries to link against',
gnu_winlibs,
),
})
return opts
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ std = options[key]
if std.value != 'none':
args.append(self._find_best_cpp_std(std.value))
- non_msvc_eh_options(options['eh'].value, args)
+ non_msvc_eh_options(options[key.evolve('eh')].value, args)
- if not options['rtti'].value:
+ if not options[key.evolve('rtti')].value:
args.append('-fno-rtti')
- if options['debugstl'].value:
+ if options[key.evolve('debugstl')].value:
args.append('-D_GLIBCXX_DEBUG=1')
return args
- def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
if self.info.is_windows() or self.info.is_cygwin():
# without a typedict mypy can't understand this.
- libs = options['winlibs'].value.copy()
+ key = OptionKey('winlibs', machine=self.for_machine, lang=self.language)
+ libs = options[key].value.copy()
assert isinstance(libs, list)
for l in libs:
assert isinstance(l, str)
@@ -424,7 +434,7 @@ class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler):
full_version=full_version, defines=defines)
ElbrusCompiler.__init__(self)
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = CPPCompiler.get_options(self)
cpp_stds = [
@@ -438,18 +448,19 @@ class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler):
if version_compare(self.version, '>=1.25.00'):
cpp_stds += [ 'c++2a', 'gnu++2a' ]
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
opts.update({
- 'eh': coredata.UserComboOption(
+ key.evolve('eh'): coredata.UserComboOption(
'C++ exception handling type.',
['none', 'default', 'a', 's', 'sc'],
'default',
),
- 'debugstl': coredata.UserBooleanOption(
+ key.evolve('debugstl'): coredata.UserBooleanOption(
'STL debug mode',
False,
),
})
- opts['std'].choices = cpp_stds # type: ignore
+ opts[key].choices = cpp_stds
return opts
# Elbrus C++ compiler does not have lchmod, but there is only linker warning, not compiler error.
@@ -465,15 +476,16 @@ class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler):
dependencies=dependencies)
# Elbrus C++ compiler does not support RTTI, so don't check for it.
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ std = options[key]
if std.value != 'none':
args.append(self._find_best_cpp_std(std.value))
- non_msvc_eh_options(options['eh'].value, args)
+ non_msvc_eh_options(options[key.evolve('eh')].value, args)
- if options['debugstl'].value:
+ if options[key.evolve('debugstl')].value:
args.append('-D_GLIBCXX_DEBUG=1')
return args
@@ -494,7 +506,7 @@ class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler):
'2': default_warn_args + ['-Wextra'],
'3': default_warn_args + ['-Wextra']}
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = CPPCompiler.get_options(self)
# Every Unix compiler under the sun seems to accept -std=c++03,
# with the exception of ICC. Instead of preventing the user from
@@ -511,36 +523,40 @@ class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler):
if version_compare(self.version, '>=19.1.0'):
c_stds += ['c++2a']
g_stds += ['gnu++2a']
+
+
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
opts.update({
- 'eh': coredata.UserComboOption(
+ key.evolve('eh'): coredata.UserComboOption(
'C++ exception handling type.',
['none', 'default', 'a', 's', 'sc'],
'default',
),
- 'rtti': coredata.UserBooleanOption('Enable RTTI', True),
- 'debugstl': coredata.UserBooleanOption('STL debug mode', False),
+ key.evolve('rtti'): coredata.UserBooleanOption('Enable RTTI', True),
+ key.evolve('debugstl'): coredata.UserBooleanOption('STL debug mode', False),
})
- opts['std'].choices = ['none'] + c_stds + g_stds # type: ignore
+ opts[key].choices = ['none'] + c_stds + g_stds
return opts
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ std = options[key]
if std.value != 'none':
remap_cpp03 = {
'c++03': 'c++98',
'gnu++03': 'gnu++98'
}
args.append('-std=' + remap_cpp03.get(std.value, std.value))
- if options['eh'].value == 'none':
+ if options[key.evolve('eh')].value == 'none':
args.append('-fno-exceptions')
- if not options['rtti'].value:
+ if not options[key.evolve('rtti')].value:
args.append('-fno-rtti')
- if options['debugstl'].value:
+ if options[key.evolve('debugstl')].value:
args.append('-D_GLIBCXX_DEBUG=1')
return args
- def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return []
@@ -560,30 +576,33 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase):
'c++latest': (False, "latest"),
}
- def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
# need a typeddict for this
- return T.cast(T.List[str], options['winlibs'].value[:])
+ key = OptionKey('winlibs', machine=self.for_machine, lang=self.language)
+ return T.cast(T.List[str], options[key].value[:])
- def _get_options_impl(self, opts: 'OptionDictType', cpp_stds: T.List[str]) -> 'OptionDictType':
+ def _get_options_impl(self, opts: 'KeyedOptionDictType', cpp_stds: T.List[str]) -> 'KeyedOptionDictType':
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
opts.update({
- 'eh': coredata.UserComboOption(
+ key.evolve('eh'): coredata.UserComboOption(
'C++ exception handling type.',
['none', 'default', 'a', 's', 'sc'],
'default',
),
- 'rtti': coredata.UserBooleanOption('Enable RTTI', True),
- 'winlibs': coredata.UserArrayOption(
+ key.evolve('rtti'): coredata.UserBooleanOption('Enable RTTI', True),
+ key.evolve('winlibs'): coredata.UserArrayOption(
'Windows libs to link against.',
msvc_winlibs,
),
})
- opts['std'].choices = cpp_stds # type: ignore
+ opts[key.evolve('std')].choices = cpp_stds
return opts
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
- eh = options['eh']
+ eh = options[key.evolve('eh')]
if eh.value == 'default':
args.append('/EHsc')
elif eh.value == 'none':
@@ -591,10 +610,10 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase):
else:
args.append('/EH' + eh.value)
- if not options['rtti'].value:
+ if not options[key.evolve('rtti')].value:
args.append('/GR-')
- permissive, ver = self.VC_VERSION_MAP[options['std'].value]
+ permissive, ver = self.VC_VERSION_MAP[options[key].value]
if ver is not None:
args.append('/std:c++{}'.format(ver))
@@ -616,22 +635,23 @@ class CPP11AsCPP14Mixin(CompilerMixinBase):
This is a limitation of Clang and MSVC that ICL doesn't share.
"""
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
# Note: there is no explicit flag for supporting C++11; we attempt to do the best we can
# which means setting the C++ standard version to C++14, in compilers that support it
# (i.e., after VS2015U3)
# if one is using anything before that point, one cannot set the standard.
- if options['std'].value in {'vc++11', 'c++11'}:
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ if options[key].value in {'vc++11', 'c++11'}:
mlog.warning(self.id, 'does not support C++11;',
'attempting best effort; setting the standard to C++14', once=True)
# Don't mutate anything we're going to change, we need to use
# deepcopy since we're messing with members, and we can't simply
# copy the members because the option proxy doesn't support it.
options = copy.deepcopy(options)
- if options['std'].value == 'vc++11':
- options['std'].value = 'vc++14'
+ if options[key].value == 'vc++11':
+ options[key].value = 'vc++14'
else:
- options['std'].value = 'c++14'
+ options[key].value = 'c++14'
return super().get_option_compile_args(options)
@@ -644,10 +664,10 @@ class VisualStudioCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixi
CPPCompiler.__init__(self, exelist, version, for_machine, is_cross,
info, exe_wrapper, linker=linker, full_version=full_version)
MSVCCompiler.__init__(self, target)
- self.base_options = ['b_pch', 'b_vscrt', 'b_ndebug'] # FIXME add lto, pgo and the like
+ self.base_options = {OptionKey(o) for o in ['b_pch', 'b_vscrt', 'b_ndebug']} # FIXME add lto, pgo and the like
self.id = 'msvc'
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
cpp_stds = ['none', 'c++11', 'vc++11']
# Visual Studio 2015 and later
if version_compare(self.version, '>=19'):
@@ -657,11 +677,12 @@ class VisualStudioCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixi
cpp_stds.extend(['vc++14', 'c++17', 'vc++17'])
return self._get_options_impl(super().get_options(), cpp_stds)
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
- if options['std'].value != 'none' and version_compare(self.version, '<19.00.24210'):
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ if options[key].value != 'none' and version_compare(self.version, '<19.00.24210'):
mlog.warning('This version of MSVC does not support cpp_std arguments')
options = copy.copy(options)
- options['std'].value = 'none'
+ options[key].value = 'none'
args = super().get_option_compile_args(options)
@@ -684,7 +705,7 @@ class ClangClCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixin, Cl
ClangClCompiler.__init__(self, target)
self.id = 'clang-cl'
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
cpp_stds = ['none', 'c++11', 'vc++11', 'c++14', 'vc++14', 'c++17', 'vc++17', 'c++latest']
return self._get_options_impl(super().get_options(), cpp_stds)
@@ -700,7 +721,7 @@ class IntelClCPPCompiler(VisualStudioLikeCPPCompilerMixin, IntelVisualStudioLike
info, exe_wrapper, linker=linker, full_version=full_version)
IntelVisualStudioLikeCompiler.__init__(self, target)
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
# This has only been tested with version 19.0,
cpp_stds = ['none', 'c++11', 'vc++11', 'c++14', 'vc++14', 'c++17', 'vc++17', 'c++latest']
return self._get_options_impl(super().get_options(), cpp_stds)
@@ -719,21 +740,23 @@ class ArmCPPCompiler(ArmCompiler, CPPCompiler):
info, exe_wrapper, linker=linker, full_version=full_version)
ArmCompiler.__init__(self)
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = CPPCompiler.get_options(self)
- opts['std'].choices = ['none', 'c++03', 'c++11'] # type: ignore
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ opts[key].choices = ['none', 'c++03', 'c++11']
return opts
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ std = options[key]
if std.value == 'c++11':
args.append('--cpp11')
elif std.value == 'c++03':
args.append('--cpp')
return args
- def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return []
def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]:
@@ -753,7 +776,7 @@ class CcrxCPPCompiler(CcrxCompiler, CPPCompiler):
def get_always_args(self) -> T.List[str]:
return ['-nologo', '-lang=cpp']
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return []
def get_compile_only_args(self) -> T.List[str]:
@@ -762,7 +785,7 @@ class CcrxCPPCompiler(CcrxCompiler, CPPCompiler):
def get_output_args(self, target: str) -> T.List[str]:
return ['-output=obj=%s' % target]
- def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return []
def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]:
@@ -777,15 +800,16 @@ class C2000CPPCompiler(C2000Compiler, CPPCompiler):
info, exe_wrapper, linker=linker, full_version=full_version)
C2000Compiler.__init__(self)
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = CPPCompiler.get_options(self)
- opts['std'].choices = ['none', 'c++03'] # type: ignore
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ opts[key].choices = ['none', 'c++03']
return opts
def get_always_args(self) -> T.List[str]:
return ['-nologo', '-lang=cpp']
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return []
def get_compile_only_args(self) -> T.List[str]:
@@ -794,7 +818,7 @@ class C2000CPPCompiler(C2000Compiler, CPPCompiler):
def get_output_args(self, target: str) -> T.List[str]:
return ['-output=obj=%s' % target]
- def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return []
def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]:
diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py
index 89fcf40..7fa3e4f 100644
--- a/mesonbuild/compilers/cuda.py
+++ b/mesonbuild/compilers/cuda.py
@@ -18,13 +18,16 @@ import typing as T
from .. import coredata
from .. import mlog
-from ..mesonlib import EnvironmentException, MachineChoice, Popen_safe, OptionOverrideProxy, is_windows, LibType
+from ..mesonlib import (
+ EnvironmentException, MachineChoice, Popen_safe, OptionOverrideProxy,
+ is_windows, LibType, OptionKey,
+)
from .compilers import (Compiler, cuda_buildtype_args, cuda_optimization_args,
cuda_debug_args)
if T.TYPE_CHECKING:
from ..build import BuildTarget
- from ..coredata import OptionDictType
+ from ..coredata import KeyedOptionDictType
from ..dependencies import Dependency, ExternalProgram
from ..environment import Environment # noqa: F401
from ..envconfig import MachineInfo
@@ -195,24 +198,26 @@ class CudaCompiler(Compiler):
}}'''
return self.compiles(t.format_map(fargs), env, extra_args=extra_args, dependencies=dependencies)
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = super().get_options()
- opts.update({'std': coredata.UserComboOption('C++ language standard to use with cuda',
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ opts.update({key: coredata.UserComboOption('C++ language standard to use with cuda',
['none', 'c++03', 'c++11', 'c++14'],
'none')})
return opts
- def _to_host_compiler_options(self, options: 'OptionDictType') -> 'OptionDictType':
+ def _to_host_compiler_options(self, options: 'KeyedOptionDictType') -> 'KeyedOptionDictType':
overrides = {name: opt.value for name, opt in options.items()}
return OptionOverrideProxy(overrides, self.host_compiler.get_options())
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
# On Windows, the version of the C++ standard used by nvcc is dictated by
# the combination of CUDA version and MSVC version; the --std= is thus ignored
# and attempting to use it will result in a warning: https://stackoverflow.com/a/51272091/741027
if not is_windows():
- std = options['std']
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ std = options[key]
if std.value != 'none':
args.append('--std=' + std.value)
@@ -229,7 +234,7 @@ class CudaCompiler(Compiler):
cooked.append(arg)
return cls._to_host_flags(cooked, _Phase.LINKER)
- def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return self._cook_link_args(self.host_compiler.get_option_link_args(self._to_host_compiler_options(options)))
def get_soname_args(self, env: 'Environment', prefix: str, shlib_name: str,
diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py
index ca6de38..eac2aa7 100644
--- a/mesonbuild/compilers/d.py
+++ b/mesonbuild/compilers/d.py
@@ -18,7 +18,7 @@ import subprocess
import typing as T
from ..mesonlib import (
- EnvironmentException, MachineChoice, version_compare,
+ EnvironmentException, MachineChoice, version_compare, OptionKey,
)
from ..arglist import CompilerArgs
@@ -653,8 +653,10 @@ class GnuDCompiler(GnuCompiler, DCompiler):
'1': default_warn_args,
'2': default_warn_args + ['-Wextra'],
'3': default_warn_args + ['-Wextra', '-Wpedantic']}
- self.base_options = ['b_colorout', 'b_sanitize', 'b_staticpic',
- 'b_vscrt', 'b_coverage', 'b_pgo', 'b_ndebug']
+ self.base_options = {
+ OptionKey(o) for o in [
+ 'b_colorout', 'b_sanitize', 'b_staticpic', 'b_vscrt',
+ 'b_coverage', 'b_pgo', 'b_ndebug']}
self._has_color_support = version_compare(self.version, '>=4.9')
# dependencies were implemented before, but broken - support was fixed in GCC 7.1+
@@ -724,7 +726,7 @@ class LLVMDCompiler(DmdLikeCompilerMixin, DCompiler):
full_version=full_version, is_cross=is_cross)
DmdLikeCompilerMixin.__init__(self, dmd_frontend_version=find_ldc_dmd_frontend_version(version_output))
self.id = 'llvm'
- self.base_options = ['b_coverage', 'b_colorout', 'b_vscrt', 'b_ndebug']
+ self.base_options = {OptionKey(o) for o in ['b_coverage', 'b_colorout', 'b_vscrt', 'b_ndebug']}
def get_colorout_args(self, colortype: str) -> T.List[str]:
if colortype == 'always':
@@ -782,7 +784,7 @@ class DmdDCompiler(DmdLikeCompilerMixin, DCompiler):
full_version=full_version, is_cross=is_cross)
DmdLikeCompilerMixin.__init__(self, version)
self.id = 'dmd'
- self.base_options = ['b_coverage', 'b_colorout', 'b_vscrt', 'b_ndebug']
+ self.base_options = {OptionKey(o) for o in ['b_coverage', 'b_colorout', 'b_vscrt', 'b_ndebug']}
def get_colorout_args(self, colortype: str) -> T.List[str]:
if colortype == 'always':
diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py
index 4b49e36..d65d585 100644
--- a/mesonbuild/compilers/fortran.py
+++ b/mesonbuild/compilers/fortran.py
@@ -31,11 +31,12 @@ from .mixins.elbrus import ElbrusCompiler
from .mixins.pgi import PGICompiler
from mesonbuild.mesonlib import (
- version_compare, EnvironmentException, MesonException, MachineChoice, LibType
+ version_compare, EnvironmentException, MesonException, MachineChoice,
+ LibType, OptionKey,
)
if T.TYPE_CHECKING:
- from ..coredata import OptionDictType
+ from ..coredata import KeyedOptionDictType
from ..dependencies import Dependency, ExternalProgram
from ..envconfig import MachineInfo
from ..environment import Environment
@@ -71,7 +72,7 @@ class FortranCompiler(CLikeCompiler, Compiler):
source_name.write_text('print *, "Fortran compilation is working."; end')
- extra_flags = []
+ extra_flags: T.List[str] = []
extra_flags += environment.coredata.get_external_args(self.for_machine, self.language)
extra_flags += environment.coredata.get_external_link_args(self.for_machine, self.language)
extra_flags += self.get_always_args()
@@ -150,10 +151,11 @@ class FortranCompiler(CLikeCompiler, Compiler):
def has_multi_link_arguments(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]:
return self._has_multi_link_arguments(args, env, 'stop; end program')
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = super().get_options()
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
opts.update({
- 'std': coredata.UserComboOption(
+ key: coredata.UserComboOption(
'Fortran language standard to use',
['none'],
'none',
@@ -179,19 +181,21 @@ class GnuFortranCompiler(GnuCompiler, FortranCompiler):
'2': default_warn_args + ['-Wextra'],
'3': default_warn_args + ['-Wextra', '-Wpedantic', '-fimplicit-none']}
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = FortranCompiler.get_options(self)
fortran_stds = ['legacy', 'f95', 'f2003']
if version_compare(self.version, '>=4.4.0'):
fortran_stds += ['f2008']
if version_compare(self.version, '>=8.0.0'):
fortran_stds += ['f2018']
- opts['std'].choices = ['none'] + fortran_stds # type: ignore
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ opts[key].choices = ['none'] + fortran_stds
return opts
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ std = options[key]
if std.value != 'none':
args.append('-std=' + std.value)
return args
@@ -313,14 +317,16 @@ class IntelFortranCompiler(IntelGnuLikeCompiler, FortranCompiler):
'2': default_warn_args + ['-warn', 'unused'],
'3': ['-warn', 'all']}
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = FortranCompiler.get_options(self)
- opts['std'].choices = ['none', 'legacy', 'f95', 'f2003', 'f2008', 'f2018'] # type: ignore
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ opts[key].choices = ['none', 'legacy', 'f95', 'f2003', 'f2008', 'f2018']
return opts
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ std = options[key]
stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'}
if std.value != 'none':
args.append('-stand=' + stds[std.value])
@@ -363,14 +369,16 @@ class IntelClFortranCompiler(IntelVisualStudioLikeCompiler, FortranCompiler):
'2': default_warn_args + ['/warn:unused'],
'3': ['/warn:all']}
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
opts = FortranCompiler.get_options(self)
- opts['std'].choices = ['none', 'legacy', 'f95', 'f2003', 'f2008', 'f2018'] # type: ignore
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ opts[key].choices = ['none', 'legacy', 'f95', 'f2003', 'f2008', 'f2018']
return opts
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ std = options[key]
stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'}
if std.value != 'none':
args.append('/stand:' + stds[std.value])
diff --git a/mesonbuild/compilers/mixins/arm.py b/mesonbuild/compilers/mixins/arm.py
index ee7d337..beb5fd5 100644
--- a/mesonbuild/compilers/mixins/arm.py
+++ b/mesonbuild/compilers/mixins/arm.py
@@ -19,6 +19,7 @@ import typing as T
from ... import mesonlib
from ...linkers import ArmClangDynamicLinker
+from ...mesonlib import OptionKey
from ..compilers import clike_debug_args
from .clang import clang_color_args
@@ -145,8 +146,10 @@ class ArmclangCompiler(Compiler):
if not mesonlib.version_compare(self.version, '==' + self.linker.version):
raise mesonlib.EnvironmentException('armlink version does not match with compiler version')
self.id = 'armclang'
- self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage',
- 'b_ndebug', 'b_staticpic', 'b_colorout']
+ self.base_options = {
+ OptionKey(o) for o in
+ ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage',
+ 'b_ndebug', 'b_staticpic', 'b_colorout']}
# Assembly
self.can_compile_suffixes.add('s')
diff --git a/mesonbuild/compilers/mixins/clang.py b/mesonbuild/compilers/mixins/clang.py
index 2e50577..fcb2225 100644
--- a/mesonbuild/compilers/mixins/clang.py
+++ b/mesonbuild/compilers/mixins/clang.py
@@ -20,6 +20,7 @@ import typing as T
from ... import mesonlib
from ...linkers import AppleDynamicLinker
+from ...mesonlib import OptionKey
from ..compilers import CompileCheckMode
from .gnu import GnuLikeCompiler
@@ -48,11 +49,11 @@ class ClangCompiler(GnuLikeCompiler):
super().__init__()
self.id = 'clang'
self.defines = defines or {}
- self.base_options.append('b_colorout')
+ self.base_options.add(OptionKey('b_colorout'))
# TODO: this really should be part of the linker base_options, but
# linkers don't have base_options.
if isinstance(self.linker, AppleDynamicLinker):
- self.base_options.append('b_bitcode')
+ self.base_options.add(OptionKey('b_bitcode'))
# All Clang backends can also do LLVM IR
self.can_compile_suffixes.add('ll')
@@ -108,7 +109,7 @@ class ClangCompiler(GnuLikeCompiler):
else:
# Shouldn't work, but it'll be checked explicitly in the OpenMP dependency.
return []
-
+
@classmethod
def use_linker_args(cls, linker: str) -> T.List[str]:
# Clang additionally can use a linker specified as a path, which GCC
diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py
index dca09ea..3288c00 100644
--- a/mesonbuild/compilers/mixins/clike.py
+++ b/mesonbuild/compilers/mixins/clike.py
@@ -35,6 +35,7 @@ from ... import mesonlib
from ... import mlog
from ...linkers import GnuLikeDynamicLinkerMixin, SolarisDynamicLinker, CompCertDynamicLinker
from ...mesonlib import LibType
+from ...coredata import OptionKey
from .. import compilers
from ..compilers import CompileCheckMode
from .visualstudio import VisualStudioLikeCompiler
@@ -393,14 +394,16 @@ class CLikeCompiler(Compiler):
# linking with static libraries since MSVC won't select a CRT for
# us in that case and will error out asking us to pick one.
try:
- crt_val = env.coredata.base_options['b_vscrt'].value
- buildtype = env.coredata.builtins['buildtype'].value
+ crt_val = env.coredata.options[OptionKey('b_vscrt')].value
+ buildtype = env.coredata.options[OptionKey('buildtype')].value
cargs += self.get_crt_compile_args(crt_val, buildtype)
except (KeyError, AttributeError):
pass
# Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS and CPPFLAGS from the env
sys_args = env.coredata.get_external_args(self.for_machine, self.language)
+ if isinstance(sys_args, str):
+ sys_args = [sys_args]
# Apparently it is a thing to inject linker flags both
# via CFLAGS _and_ LDFLAGS, even though the former are
# also used during linking. These flags can break
diff --git a/mesonbuild/compilers/mixins/elbrus.py b/mesonbuild/compilers/mixins/elbrus.py
index 2ea3599..16f6210 100644
--- a/mesonbuild/compilers/mixins/elbrus.py
+++ b/mesonbuild/compilers/mixins/elbrus.py
@@ -21,7 +21,7 @@ import re
from .gnu import GnuLikeCompiler
from .gnu import gnu_optimization_args
-from ...mesonlib import Popen_safe
+from ...mesonlib import Popen_safe, OptionKey
if T.TYPE_CHECKING:
from ...environment import Environment
@@ -34,9 +34,7 @@ class ElbrusCompiler(GnuLikeCompiler):
def __init__(self) -> None:
super().__init__()
self.id = 'lcc'
- self.base_options = ['b_pgo', 'b_coverage',
- 'b_ndebug', 'b_staticpic',
- 'b_lundef', 'b_asneeded']
+ self.base_options = {OptionKey(o) for o in ['b_pgo', 'b_coverage', 'b_ndebug', 'b_staticpic', 'b_lundef', 'b_asneeded']}
# FIXME: use _build_wrapper to call this so that linker flags from the env
# get applied
diff --git a/mesonbuild/compilers/mixins/emscripten.py b/mesonbuild/compilers/mixins/emscripten.py
index cd18b35..fc0b21e 100644
--- a/mesonbuild/compilers/mixins/emscripten.py
+++ b/mesonbuild/compilers/mixins/emscripten.py
@@ -18,6 +18,7 @@ import os.path
import typing as T
from ... import coredata
+from ...mesonlib import OptionKey
if T.TYPE_CHECKING:
from ...environment import Environment
@@ -50,15 +51,16 @@ class EmscriptenMixin(Compiler):
def thread_link_flags(self, env: 'Environment') -> T.List[str]:
args = ['-s', 'USE_PTHREADS=1']
- count = env.coredata.compiler_options[self.for_machine][self.language]['thread_count'].value # type: int
+ count: int = env.coredata.options[OptionKey('thread_count', lang=self.language, machine=self.for_machine)].value
if count:
args.extend(['-s', 'PTHREAD_POOL_SIZE={}'.format(count)])
return args
- def get_options(self) -> 'coredata.OptionDictType':
+ def get_options(self) -> 'coredata.KeyedOptionDictType':
opts = super().get_options()
+ key = OptionKey('thread_count', machine=self.for_machine, lang=self.language)
opts.update({
- 'thread_count': coredata.UserIntegerOption(
+ key: coredata.UserIntegerOption(
'Number of threads to use in web assembly, set to 0 to disable',
(0, None, 4), # Default was picked at random
),
diff --git a/mesonbuild/compilers/mixins/gnu.py b/mesonbuild/compilers/mixins/gnu.py
index 3d43162..95bcd7c 100644
--- a/mesonbuild/compilers/mixins/gnu.py
+++ b/mesonbuild/compilers/mixins/gnu.py
@@ -24,6 +24,7 @@ import typing as T
from ... import mesonlib
from ... import mlog
+from ...mesonlib import OptionKey
if T.TYPE_CHECKING:
from ...environment import Environment
@@ -146,14 +147,15 @@ class GnuLikeCompiler(Compiler, metaclass=abc.ABCMeta):
LINKER_PREFIX = '-Wl,'
def __init__(self) -> None:
- self.base_options = ['b_pch', 'b_lto', 'b_pgo', 'b_coverage',
- 'b_ndebug', 'b_staticpic', 'b_pie']
+ self.base_options = {
+ OptionKey(o) for o in ['b_pch', 'b_lto', 'b_pgo', 'b_coverage',
+ 'b_ndebug', 'b_staticpic', 'b_pie']}
if not (self.info.is_windows() or self.info.is_cygwin() or self.info.is_openbsd()):
- self.base_options.append('b_lundef')
+ self.base_options.add(OptionKey('b_lundef'))
if not self.info.is_windows() or self.info.is_cygwin():
- self.base_options.append('b_asneeded')
+ self.base_options.add(OptionKey('b_asneeded'))
if not self.info.is_hurd():
- self.base_options.append('b_sanitize')
+ self.base_options.add(OptionKey('b_sanitize'))
# All GCC-like backends can do assembly
self.can_compile_suffixes.add('s')
@@ -328,7 +330,7 @@ class GnuCompiler(GnuLikeCompiler):
super().__init__()
self.id = 'gcc'
self.defines = defines or {}
- self.base_options.append('b_colorout')
+ self.base_options.add(OptionKey('b_colorout'))
def get_colorout_args(self, colortype: str) -> T.List[str]:
if mesonlib.version_compare(self.version, '>=4.9.0'):
diff --git a/mesonbuild/compilers/mixins/intel.py b/mesonbuild/compilers/mixins/intel.py
index 442e8c7..5bca254 100644
--- a/mesonbuild/compilers/mixins/intel.py
+++ b/mesonbuild/compilers/mixins/intel.py
@@ -79,8 +79,9 @@ class IntelGnuLikeCompiler(GnuLikeCompiler):
# It does have IPO, which serves much the same purpose as LOT, but
# there is an unfortunate rule for using IPO (you can't control the
# name of the output file) which break assumptions meson makes
- self.base_options = ['b_pch', 'b_lundef', 'b_asneeded', 'b_pgo',
- 'b_coverage', 'b_ndebug', 'b_staticpic', 'b_pie']
+ self.base_options = {mesonlib.OptionKey(o) for o in [
+ 'b_pch', 'b_lundef', 'b_asneeded', 'b_pgo', 'b_coverage',
+ 'b_ndebug', 'b_staticpic', 'b_pie']}
self.id = 'intel'
self.lang_header = 'none'
diff --git a/mesonbuild/compilers/mixins/islinker.py b/mesonbuild/compilers/mixins/islinker.py
index 2445eec..3fe3382 100644
--- a/mesonbuild/compilers/mixins/islinker.py
+++ b/mesonbuild/compilers/mixins/islinker.py
@@ -25,7 +25,7 @@ import typing as T
from ... import mesonlib
if T.TYPE_CHECKING:
- from ...coredata import OptionDictType
+ from ...coredata import KeyedOptionDictType
from ...environment import Environment
from ...compilers.compilers import Compiler
else:
@@ -66,7 +66,7 @@ class BasicLinkerIsCompilerMixin(Compiler):
def get_linker_lib_prefix(self) -> str:
return ''
- def get_option_link_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_link_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return []
def has_multi_link_args(self, args: T.List[str], env: 'Environment') -> T.Tuple[bool, bool]:
@@ -78,7 +78,7 @@ class BasicLinkerIsCompilerMixin(Compiler):
def get_std_shared_lib_link_args(self) -> T.List[str]:
return []
- def get_std_shared_module_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_std_shared_module_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
return self.get_std_shared_lib_link_args()
def get_link_whole_for(self, args: T.List[str]) -> T.List[str]:
diff --git a/mesonbuild/compilers/mixins/pgi.py b/mesonbuild/compilers/mixins/pgi.py
index 61dee8d..8461574 100644
--- a/mesonbuild/compilers/mixins/pgi.py
+++ b/mesonbuild/compilers/mixins/pgi.py
@@ -19,6 +19,7 @@ import os
from pathlib import Path
from ..compilers import clike_debug_args, clike_optimization_args
+from ...mesonlib import OptionKey
if T.TYPE_CHECKING:
from ...environment import Environment
@@ -43,7 +44,7 @@ pgi_buildtype_args = {
class PGICompiler(Compiler):
def __init__(self) -> None:
- self.base_options = ['b_pch']
+ self.base_options = {OptionKey('b_pch')}
self.id = 'pgi'
default_warn_args = ['-Minform=inform']
diff --git a/mesonbuild/compilers/mixins/visualstudio.py b/mesonbuild/compilers/mixins/visualstudio.py
index c38d59a..92f4fcd 100644
--- a/mesonbuild/compilers/mixins/visualstudio.py
+++ b/mesonbuild/compilers/mixins/visualstudio.py
@@ -129,7 +129,7 @@ class VisualStudioLikeCompiler(Compiler, metaclass=abc.ABCMeta):
INVOKES_LINKER = False
def __init__(self, target: str):
- self.base_options = ['b_pch', 'b_ndebug', 'b_vscrt'] # FIXME add lto, pgo and the like
+ self.base_options = {mesonlib.OptionKey(o) for o in ['b_pch', 'b_ndebug', 'b_vscrt']} # FIXME add lto, pgo and the like
self.target = target
self.is_64 = ('x64' in target) or ('x86_64' in target)
# do some canonicalization of target machine
diff --git a/mesonbuild/compilers/objc.py b/mesonbuild/compilers/objc.py
index 1b280eb..e47bf2f 100644
--- a/mesonbuild/compilers/objc.py
+++ b/mesonbuild/compilers/objc.py
@@ -51,7 +51,7 @@ class ObjCCompiler(CLikeCompiler, Compiler):
# TODO try to use sanity_check_impl instead of duplicated code
source_name = os.path.join(work_dir, 'sanitycheckobjc.m')
binary_name = os.path.join(work_dir, 'sanitycheckobjc')
- extra_flags = []
+ extra_flags: T.List[str] = []
extra_flags += environment.coredata.get_external_args(self.for_machine, self.language)
if self.is_cross:
extra_flags += self.get_compile_only_args()
diff --git a/mesonbuild/compilers/objcpp.py b/mesonbuild/compilers/objcpp.py
index 16ba77e..c0f93d7 100644
--- a/mesonbuild/compilers/objcpp.py
+++ b/mesonbuild/compilers/objcpp.py
@@ -50,7 +50,7 @@ class ObjCPPCompiler(CLikeCompiler, Compiler):
# TODO try to use sanity_check_impl instead of duplicated code
source_name = os.path.join(work_dir, 'sanitycheckobjcpp.mm')
binary_name = os.path.join(work_dir, 'sanitycheckobjcpp')
- extra_flags = []
+ extra_flags: T.List[str] = []
extra_flags += environment.coredata.get_external_args(self.for_machine, self.language)
if self.is_cross:
extra_flags += self.get_compile_only_args()
diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py
index 312b3b6..fd58819 100644
--- a/mesonbuild/compilers/rust.py
+++ b/mesonbuild/compilers/rust.py
@@ -17,11 +17,14 @@ import textwrap
import typing as T
from .. import coredata
-from ..mesonlib import EnvironmentException, MachineChoice, MesonException, Popen_safe
+from ..mesonlib import (
+ EnvironmentException, MachineChoice, MesonException, Popen_safe,
+ OptionKey,
+)
from .compilers import Compiler, rust_buildtype_args, clike_debug_args
if T.TYPE_CHECKING:
- from ..coredata import OptionDictType
+ from ..coredata import KeyedOptionDictType
from ..dependencies import ExternalProgram
from ..envconfig import MachineInfo
from ..environment import Environment # noqa: F401
@@ -52,9 +55,9 @@ class RustCompiler(Compiler):
linker=linker)
self.exe_wrapper = exe_wrapper
self.id = 'rustc'
- self.base_options.append('b_colorout')
+ self.base_options.add(OptionKey('b_colorout'))
if 'link' in self.linker.id:
- self.base_options.append('b_vscrt')
+ self.base_options.add(OptionKey('b_vscrt'))
def needs_static_linker(self) -> bool:
return False
@@ -133,18 +136,20 @@ class RustCompiler(Compiler):
# C compiler for dynamic linking, as such we invoke the C compiler's
# use_linker_args method instead.
- def get_options(self) -> 'OptionDictType':
+ def get_options(self) -> 'KeyedOptionDictType':
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
return {
- 'std': coredata.UserComboOption(
+ key: coredata.UserComboOption(
'Rust Eddition to use',
['none', '2015', '2018'],
'none',
),
}
- def get_option_compile_args(self, options: 'OptionDictType') -> T.List[str]:
+ def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = []
- std = options['std']
+ key = OptionKey('std', machine=self.for_machine, lang=self.language)
+ std = options[key]
if std.value != 'none':
args.append('--edition=' + std.value)
return args
diff --git a/mesonbuild/compilers/swift.py b/mesonbuild/compilers/swift.py
index 8682e54..7b18591 100644
--- a/mesonbuild/compilers/swift.py
+++ b/mesonbuild/compilers/swift.py
@@ -101,7 +101,7 @@ class SwiftCompiler(Compiler):
src = 'swifttest.swift'
source_name = os.path.join(work_dir, src)
output_name = os.path.join(work_dir, 'swifttest')
- extra_flags = []
+ extra_flags: T.List[str] = []
extra_flags += environment.coredata.get_external_args(self.for_machine, self.language)
if self.is_cross:
extra_flags += self.get_compile_only_args()
diff --git a/mesonbuild/compilers/vala.py b/mesonbuild/compilers/vala.py
index af800c2..80e91f6 100644
--- a/mesonbuild/compilers/vala.py
+++ b/mesonbuild/compilers/vala.py
@@ -16,7 +16,7 @@ import os.path
import typing as T
from .. import mlog
-from ..mesonlib import EnvironmentException, MachineChoice, version_compare
+from ..mesonlib import EnvironmentException, MachineChoice, version_compare, OptionKey
from .compilers import Compiler, LibType
@@ -33,7 +33,7 @@ class ValaCompiler(Compiler):
super().__init__(exelist, version, for_machine, info, is_cross=is_cross)
self.version = version
self.id = 'valac'
- self.base_options = ['b_colorout']
+ self.base_options = {OptionKey('b_colorout')}
def needs_static_linker(self) -> bool:
return False # Because compiles into C.
@@ -92,7 +92,7 @@ class ValaCompiler(Compiler):
def sanity_check(self, work_dir: str, environment: 'Environment') -> None:
code = 'class MesonSanityCheck : Object { }'
- extra_flags = []
+ extra_flags: T.List[str] = []
extra_flags += environment.coredata.get_external_args(self.for_machine, self.language)
if self.is_cross:
extra_flags += self.get_compile_only_args()
@@ -116,7 +116,7 @@ class ValaCompiler(Compiler):
# no extra dirs are specified.
if not extra_dirs:
code = 'class MesonFindLibrary : Object { }'
- args = []
+ args: T.List[str] = []
args += env.coredata.get_external_args(self.for_machine, self.language)
vapi_args = ['--pkg', libname]
args += vapi_args