aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/build.py6
-rw-r--r--mesonbuild/compilers/cuda.py4
-rw-r--r--mesonbuild/coredata.py46
-rw-r--r--mesonbuild/utils/universal.py50
4 files changed, 48 insertions, 58 deletions
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 8fed785..edec75d 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -34,7 +34,7 @@ from .mesonlib import (
File, MesonException, MachineChoice, PerMachine, OrderedSet, listify,
extract_as_list, typeslistify, stringlistify, classify_unity_sources,
get_filenames_templates_dict, substitute_values, has_path_sep,
- OptionKey, PerMachineDefaultable, OptionOverrideProxy,
+ OptionKey, PerMachineDefaultable,
MesonBugException, EnvironmentVariables, pickle_load,
)
from .compilers import (
@@ -535,7 +535,7 @@ class Target(HoldableObject, metaclass=abc.ABCMeta):
for k, v in overrides.items()}
else:
ovr = {}
- self.options = OptionOverrideProxy(ovr, self.environment.coredata.options, self.subproject)
+ self.options = coredata.OptionsView(self.environment.coredata.options, self.subproject, ovr)
# XXX: this should happen in the interpreter
if has_path_sep(self.name):
# Fix failing test 53 when this becomes an error.
@@ -655,7 +655,7 @@ class Target(HoldableObject, metaclass=abc.ABCMeta):
else:
self.options.overrides[k] = v
- def get_options(self) -> OptionOverrideProxy:
+ def get_options(self) -> coredata.OptionsView:
return self.options
def get_option(self, key: 'OptionKey') -> T.Union[str, int, bool, 'WrapMode']:
diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py
index 8ed7fa4..09a7d6a 100644
--- a/mesonbuild/compilers/cuda.py
+++ b/mesonbuild/compilers/cuda.py
@@ -21,7 +21,7 @@ import typing as T
from .. import coredata
from .. import mlog
from ..mesonlib import (
- EnvironmentException, Popen_safe, OptionOverrideProxy,
+ EnvironmentException, Popen_safe,
is_windows, LibType, OptionKey, version_compare,
)
from .compilers import (Compiler, cuda_buildtype_args, cuda_optimization_args,
@@ -650,7 +650,7 @@ class CudaCompiler(Compiler):
host_options = {key: options.get(key, opt) for key, opt in self.host_compiler.get_options().items()}
std_key = OptionKey('std', machine=self.for_machine, lang=self.host_compiler.language)
overrides = {std_key: 'none'}
- return OptionOverrideProxy(overrides, host_options)
+ return coredata.OptionsView(host_options, overrides=overrides)
def get_option_compile_args(self, options: 'KeyedOptionDictType') -> T.List[str]:
args = self.get_ccbin_args(options)
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 4b0f9af..f151c7b 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -19,7 +19,9 @@ import pickle, os, uuid
import sys
from itertools import chain
from pathlib import PurePath
-from collections import OrderedDict
+from collections import OrderedDict, abc
+from dataclasses import dataclass
+
from .mesonlib import (
HoldableObject,
MesonException, EnvironmentException, MachineChoice, PerMachine,
@@ -42,12 +44,12 @@ if T.TYPE_CHECKING:
from .compilers.compilers import Compiler, CompileResult, RunResult, CompileCheckMode
from .dependencies.detect import TV_DepID
from .environment import Environment
- from .mesonlib import OptionOverrideProxy, FileOrString
+ from .mesonlib import FileOrString
from .cmake.traceparser import CMakeCacheEntry
- OptionDictType = T.Union[T.Dict[str, 'UserOption[T.Any]'], OptionOverrideProxy]
+ OptionDictType = T.Union[T.Dict[str, 'UserOption[T.Any]'], 'OptionsView']
MutableKeyedOptionDictType = T.Dict['OptionKey', 'UserOption[T.Any]']
- KeyedOptionDictType = T.Union[MutableKeyedOptionDictType, OptionOverrideProxy]
+ KeyedOptionDictType = T.Union[MutableKeyedOptionDictType, 'OptionsView']
CompilerCheckCacheKey = T.Tuple[T.Tuple[str, ...], str, FileOrString, T.Tuple[str, ...], CompileCheckMode]
# code, args
RunCheckCacheKey = T.Tuple[str, T.Tuple[str, ...]]
@@ -375,6 +377,42 @@ class UserStdOption(UserComboOption):
raise MesonException(f'None of values {candidates} are supported by the {self.lang.upper()} compiler. ' +
f'Possible values are {self.choices}')
+@dataclass
+class OptionsView(abc.Mapping):
+ '''A view on an options dictionary for a given subproject and with overrides.
+ '''
+
+ # TODO: the typing here could be made more explicit using a TypeDict from
+ # python 3.8 or typing_extensions
+ options: KeyedOptionDictType
+ subproject: T.Optional[str] = None
+ overrides: T.Optional[T.Mapping[OptionKey, T.Union[str, int, bool, T.List[str]]]] = None
+
+ def __getitem__(self, key: OptionKey) -> UserOption:
+ # FIXME: This is fundamentally the same algorithm than interpreter.get_option_internal().
+ # We should try to share the code somehow.
+ key = key.evolve(subproject=self.subproject)
+ if not key.is_project():
+ opt = self.options.get(key)
+ if opt is None or opt.yielding:
+ opt = self.options[key.as_root()]
+ else:
+ opt = self.options[key]
+ if opt.yielding:
+ opt = self.options.get(key.as_root(), opt)
+ if self.overrides:
+ override_value = self.overrides.get(key.as_root())
+ if override_value is not None:
+ opt = copy.copy(opt)
+ opt.set_value(override_value)
+ return opt
+
+ def __iter__(self) -> T.Iterator[OptionKey]:
+ return iter(self.options)
+
+ def __len__(self) -> int:
+ return len(self.options)
+
class DependencyCacheType(enum.Enum):
OTHER = 0
diff --git a/mesonbuild/utils/universal.py b/mesonbuild/utils/universal.py
index d44ec03..7f0f385 100644
--- a/mesonbuild/utils/universal.py
+++ b/mesonbuild/utils/universal.py
@@ -29,7 +29,6 @@ from itertools import tee
from tempfile import TemporaryDirectory, NamedTemporaryFile
import typing as T
import textwrap
-import copy
import pickle
import errno
import json
@@ -42,7 +41,7 @@ if T.TYPE_CHECKING:
from .._typing import ImmutableListProtocol
from ..build import ConfigurationData
- from ..coredata import KeyedOptionDictType, UserOption, StrOrBytesPath
+ from ..coredata import StrOrBytesPath
from ..environment import Environment
from ..compilers.compilers import Compiler
from ..interpreterbase.baseobjects import SubProject
@@ -79,7 +78,6 @@ __all__ = [
'GitException',
'OptionKey',
'dump_conf_header',
- 'OptionOverrideProxy',
'OptionType',
'OrderedSet',
'PerMachine',
@@ -2124,52 +2122,6 @@ def generate_list(func: T.Callable[..., T.Generator[_T, None, None]]) -> T.Calla
return wrapper
-class OptionOverrideProxy(collections.abc.Mapping):
- '''Mimic an option list but transparently override selected option
- values.
- '''
-
- # TODO: the typing here could be made more explicit using a TypeDict from
- # python 3.8 or typing_extensions
-
- def __init__(self, overrides: T.Dict['OptionKey', T.Any], options: 'KeyedOptionDictType',
- subproject: T.Optional[str] = None):
- self.overrides = overrides
- self.options = options
- self.subproject = subproject
-
- def __getitem__(self, key: 'OptionKey') -> 'UserOption':
- # FIXME: This is fundamentally the same algorithm than interpreter.get_option_internal().
- # We should try to share the code somehow.
- key = key.evolve(subproject=self.subproject)
- if not key.is_project():
- opt = self.options.get(key)
- if opt is None or opt.yielding:
- opt = self.options[key.as_root()]
- else:
- opt = self.options[key]
- if opt.yielding:
- opt = self.options.get(key.as_root(), opt)
- override_value = self.overrides.get(key.as_root())
- if override_value is not None:
- opt = copy.copy(opt)
- opt.set_value(override_value)
- return opt
-
- def __iter__(self) -> T.Iterator['OptionKey']:
- return iter(self.options)
-
- def __len__(self) -> int:
- return len(self.options)
-
- def __eq__(self, other: object) -> bool:
- if not isinstance(other, OptionOverrideProxy):
- return NotImplemented
- t1 = (self.overrides, self.subproject, self.options)
- t2 = (other.overrides, other.subproject, other.options)
- return t1 == t2
-
-
class OptionType(enum.IntEnum):
"""Enum used to specify what kind of argument a thing is."""