move OptionKey to mesonlib

There's starting to be a lot of things including coredata that coredata
needs to itself include. putting it in mesonlib makes more sense
pull/8080/head
Dylan Baker 4 years ago
parent fe973d9fc4
commit f9b19e73a5
  1. 4
      mesonbuild/ast/introspection.py
  2. 3
      mesonbuild/backend/ninjabackend.py
  3. 3
      mesonbuild/backend/vs2010backend.py
  4. 4
      mesonbuild/build.py
  5. 3
      mesonbuild/cmake/interpreter.py
  6. 3
      mesonbuild/compilers/c.py
  7. 3
      mesonbuild/compilers/compilers.py
  8. 4
      mesonbuild/compilers/cpp.py
  9. 6
      mesonbuild/compilers/cuda.py
  10. 4
      mesonbuild/compilers/fortran.py
  11. 5
      mesonbuild/compilers/mixins/emscripten.py
  12. 6
      mesonbuild/compilers/rust.py
  13. 198
      mesonbuild/coredata.py
  14. 24
      mesonbuild/environment.py
  15. 2
      mesonbuild/interpreter.py
  16. 3
      mesonbuild/mconf.py
  17. 197
      mesonbuild/mesonlib.py
  18. 3
      run_tests.py
  19. 3
      run_unittests.py

@ -19,7 +19,7 @@ from .interpreter import AstInterpreter
from .visitor import AstVisitor
from .. import compilers, environment, mesonlib, optinterpreter
from .. import coredata as cdata
from ..mesonlib import MachineChoice
from ..mesonlib import MachineChoice, OptionKey
from ..interpreterbase import InvalidArguments, TYPE_nvar
from ..build import BuildTarget, Executable, Jar, SharedLibrary, SharedModule, StaticLibrary
from ..mparser import BaseNode, ArithmeticNode, ArrayNode, ElementaryNode, IdNode, FunctionNode, StringNode
@ -65,7 +65,7 @@ class IntrospectionInterpreter(AstInterpreter):
self.coredata = self.environment.get_coredata()
self.option_file = os.path.join(self.source_root, self.subdir, 'meson_options.txt')
self.backend = backend
self.default_options = {cdata.OptionKey('backend'): self.backend}
self.default_options = {OptionKey('backend'): self.backend}
self.project_data = {} # type: T.Dict[str, T.Any]
self.targets = [] # type: T.List[T.Dict[str, T.Any]]
self.dependencies = [] # type: T.List[T.Dict[str, T.Any]]

@ -43,11 +43,10 @@ from ..mesonlib import (
File, LibType, MachineChoice, MesonException, OrderedSet, PerMachine,
ProgressBar, quote_arg, unholder,
)
from ..mesonlib import get_compiler_for_source, has_path_sep
from ..mesonlib import get_compiler_for_source, has_path_sep, OptionKey
from .backends import CleanTrees
from ..build import InvalidArguments
from ..interpreter import Interpreter
from ..coredata import OptionKey
if T.TYPE_CHECKING:
from ..linkers import StaticLinker

@ -28,10 +28,9 @@ from .. import mlog
from .. import compilers
from ..interpreter import Interpreter
from ..mesonlib import (
MesonException, File, python_command, replace_if_different
MesonException, File, python_command, replace_if_different, OptionKey,
)
from ..environment import Environment, build_filename
from ..coredata import OptionKey
def autodetect_vs_version(build: T.Optional[build.Build], interpreter: T.Optional[Interpreter]):
vs_version = os.getenv('VisualStudioVersion', None)

@ -28,7 +28,8 @@ from . import mlog
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, unholder
get_filenames_templates_dict, substitute_values, has_path_sep, unholder,
OptionKey,
)
from .compilers import (
Compiler, all_languages, is_object, clink_langs, sort_clink, lang_suffixes,
@ -36,7 +37,6 @@ from .compilers import (
)
from .linkers import StaticLinker
from .interpreterbase import FeatureNew
from .coredata import OptionKey
if T.TYPE_CHECKING:
from .coredata import KeyedOptionDictType, OptionDictType

@ -22,7 +22,7 @@ from .executor import CMakeExecutor
from .toolchain import CMakeToolchain, CMakeExecScope
from .traceparser import CMakeTraceParser, CMakeGeneratorTarget
from .. import mlog, mesonlib
from ..mesonlib import MachineChoice, OrderedSet, version_compare, path_is_in_root, relative_to_if_possible
from ..mesonlib import MachineChoice, OrderedSet, version_compare, path_is_in_root, relative_to_if_possible, OptionKey
from ..mesondata import mesondata
from ..compilers.compilers import lang_suffixes, header_suffixes, obj_suffixes, lib_suffixes, is_header
from enum import Enum
@ -31,7 +31,6 @@ from pathlib import Path
import typing as T
import re
from os import environ
from ..coredata import OptionKey
from ..mparser import (
Token,

@ -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
@ -37,7 +37,6 @@ from .compilers import (
msvc_winlibs,
Compiler,
)
from ..coredata import OptionKey
if T.TYPE_CHECKING:
from ..coredata import KeyedOptionDictType

@ -25,14 +25,13 @@ 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
)
from ..arglist import CompilerArgs
from ..coredata import OptionKey
if T.TYPE_CHECKING:
from ..build import BuildTarget

@ -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 (
@ -41,8 +41,6 @@ from .mixins.elbrus import ElbrusCompiler
from .mixins.pgi import PGICompiler
from .mixins.emscripten import EmscriptenMixin
from ..coredata import OptionKey
if T.TYPE_CHECKING:
from ..coredata import KeyedOptionDictType
from ..dependencies import Dependency, ExternalProgram

@ -17,9 +17,11 @@ import os.path
import typing as T
from .. import coredata
from ..coredata import OptionKey
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)

@ -17,7 +17,6 @@ import typing as T
import subprocess, os
from .. import coredata
from ..coredata import OptionKey
from .compilers import (
clike_debug_args,
Compiler,
@ -32,7 +31,8 @@ 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:

@ -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,14 +51,14 @@ class EmscriptenMixin(Compiler):
def thread_link_flags(self, env: 'Environment') -> T.List[str]:
args = ['-s', 'USE_PTHREADS=1']
count: int = env.coredata.compiler_options[coredata.OptionKey('thread_count', lang=self.language, machine=self.for_machine)].value # type: ignore
count: int = env.coredata.compiler_options[OptionKey('thread_count', lang=self.language, machine=self.for_machine)].value # type: ignore
if count:
args.extend(['-s', 'PTHREAD_POOL_SIZE={}'.format(count)])
return args
def get_options(self) -> 'coredata.KeyedOptionDictType':
opts = super().get_options()
key = coredata.OptionKey('thread_count', machine=self.for_machine, lang=self.language)
key = OptionKey('thread_count', machine=self.for_machine, lang=self.language)
opts.update({
key: coredata.UserIntegerOption(
'Number of threads to use in web assembly, set to 0 to disable',

@ -17,8 +17,10 @@ import textwrap
import typing as T
from .. import coredata
from ..coredata import OptionKey
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:

@ -20,7 +20,8 @@ from pathlib import PurePath
from collections import OrderedDict, defaultdict
from .mesonlib import (
MesonException, EnvironmentException, MachineChoice, PerMachine,
default_libdir, default_libexecdir, default_prefix, split_args
default_libdir, default_libexecdir, default_prefix, split_args,
OptionKey,
)
from .wrap import WrapMode
import ast
@ -49,201 +50,6 @@ default_yielding = False
_T = T.TypeVar('_T')
class OptionType(enum.Enum):
"""Enum used to specify what kind of argument a thing is."""
BUILTIN = 0
BASE = 1
COMPILER = 2
PROJECT = 3
BACKEND = 4
def classify_argument(key: 'OptionKey') -> OptionType:
"""Classify arguments into groups so we know which dict to assign them to."""
from .compilers import base_options
all_builtins = set(BUILTIN_OPTIONS) | set(BUILTIN_OPTIONS_PER_MACHINE) | set(builtin_dir_noprefix_options)
if key.name in base_options:
assert key.machine is MachineChoice.HOST, str(key)
return OptionType.BASE
elif key.lang is not None:
return OptionType.COMPILER
elif key.name in all_builtins:
return OptionType.BUILTIN
elif key.name.startswith('backend_'):
assert key.machine is MachineChoice.HOST, str(key)
return OptionType.BACKEND
else:
assert key.machine is MachineChoice.HOST, str(key)
return OptionType.PROJECT
class OptionKey:
"""Represents an option key in the various option dictionaries.
This provides a flexible, powerful way to map option names from their
external form (things like subproject:build.option) to something that
internally easier to reason about and produce.
"""
__slots__ = ['name', 'subproject', 'machine', 'lang', '_hash', 'type']
name: str
subproject: str
machine: MachineChoice
lang: T.Optional[str]
_hash: int
type: OptionType
def __init__(self, name: str, subproject: str = '',
machine: MachineChoice = MachineChoice.HOST,
lang: T.Optional[str] = None, _type: T.Optional[OptionType] = None):
# the _type option to the constructor is kinda private. We want to be
# able tos ave the state and avoid the lookup function when
# pickling/unpickling, but we need to be able to calculate it when
# constructing a new OptionKey
object.__setattr__(self, 'name', name)
object.__setattr__(self, 'subproject', subproject)
object.__setattr__(self, 'machine', machine)
object.__setattr__(self, 'lang', lang)
object.__setattr__(self, '_hash', hash((name, subproject, machine, lang)))
if _type is None:
_type = classify_argument(self)
object.__setattr__(self, 'type', _type)
def __setattr__(self, key: str, value: T.Any) -> None:
raise AttributeError('OptionKey instances do not support mutation.')
def __getstate__(self) -> T.Dict[str, T.Any]:
return {
'name': self.name,
'subproject': self.subproject,
'machine': self.machine,
'lang': self.lang,
'_type': self.type,
}
def __setstate__(self, state: T.Dict[str, T.Any]) -> None:
"""De-serialize the state of a pickle.
This is very clever. __init__ is not a constructor, it's an
initializer, therefore it's safe to call more than once. We create a
state in the custom __getstate__ method, which is valid to pass
unsplatted to the initializer.
"""
self.__init__(**state)
def __hash__(self) -> int:
return self._hash
def __eq__(self, other: object) -> bool:
if isinstance(other, OptionKey):
return (
self.name == other.name and
self.subproject == other.subproject and
self.machine is other.machine and
self.lang == other.lang)
return NotImplemented
def __str__(self) -> str:
out = self.name
if self.lang:
out = f'{self.lang}_{out}'
if self.machine is MachineChoice.BUILD:
out = f'build.{out}'
if self.subproject:
out = f'{self.subproject}:{out}'
return out
def __repr__(self) -> str:
return f'OptionKey({repr(self.name)}, {repr(self.subproject)}, {repr(self.machine)}, {repr(self.lang)})'
@classmethod
def from_string(cls, raw: str) -> 'OptionKey':
"""Parse the raw command line format into a three part tuple.
This takes strings like `mysubproject:build.myoption` and Creates an
OptionKey out of them.
"""
try:
subproject, raw2 = raw.split(':')
except ValueError:
subproject, raw2 = '', raw
if raw2.startswith('build.'):
raw3 = raw2.lstrip('build.')
for_machine = MachineChoice.BUILD
else:
raw3 = raw2
for_machine = MachineChoice.HOST
from .compilers import all_languages
if any(raw3.startswith(f'{l}_') for l in all_languages):
lang, opt = raw3.split('_', 1)
else:
lang, opt = None, raw3
assert ':' not in opt
assert 'build.' not in opt
return cls(opt, subproject, for_machine, lang)
def evolve(self, name: T.Optional[str] = None, subproject: T.Optional[str] = None,
machine: T.Optional[MachineChoice] = None, lang: T.Optional[str] = '') -> 'OptionKey':
"""Create a new copy of this key, but with alterted members.
For example:
>>> a = OptionKey('foo', '', MachineChoice.Host)
>>> b = OptionKey('foo', 'bar', MachineChoice.Host)
>>> b == a.evolve(subproject='bar')
True
"""
# We have to be a little clever with lang here, because lang is valid
# as None, for non-compiler options
return OptionKey(
name if name is not None else self.name,
subproject if subproject is not None else self.subproject,
machine if machine is not None else self.machine,
lang if lang != '' else self.lang,
)
def as_root(self) -> 'OptionKey':
"""Convenience method for key.evolve(subproject='')."""
return self.evolve(subproject='')
def as_build(self) -> 'OptionKey':
"""Convenience method for key.evolve(machine=MachinceChoice.BUILD)."""
return self.evolve(machine=MachineChoice.BUILD)
def as_host(self) -> 'OptionKey':
"""Convenience method for key.evolve(machine=MachinceChoice.HOST)."""
return self.evolve(machine=MachineChoice.HOST)
def is_backend(self) -> bool:
"""Convenience method to check if this is a backend option."""
return self.type is OptionType.BACKEND
def is_builtin(self) -> bool:
"""Convenience method to check if this is a builtin option."""
return self.type is OptionType.BUILTIN
def is_compiler(self) -> bool:
"""Convenience method to check if this is a builtin option."""
return self.type is OptionType.COMPILER
def is_project(self) -> bool:
"""Convenience method to check if this is a project option."""
return self.type is OptionType.PROJECT
def is_base(self) -> bool:
"""Convenience method to check if this is a base option."""
return self.type is OptionType.BASE
class MesonVersionMismatchException(MesonException):
'''Build directory generated with Meson version is incompatible with current version'''
def __init__(self, old_version: str, current_version: str) -> None:

@ -23,7 +23,7 @@ from .linkers import ArLinker, ArmarLinker, VisualStudioLinker, DLinker, CcrxLin
from . import mesonlib
from .mesonlib import (
MesonException, EnvironmentException, MachineChoice, Popen_safe,
PerMachineDefaultable, PerThreeMachineDefaultable, split_args, quote_arg
PerMachineDefaultable, PerThreeMachineDefaultable, split_args, quote_arg, OptionKey
)
from . import mlog
@ -605,7 +605,7 @@ class Environment:
#
# Note that order matters because of 'buildtype', if it is after
# 'optimization' and 'debug' keys, it override them.
self.options: T.MutableMapping[coredata.OptionKey, str] = collections.OrderedDict()
self.options: T.MutableMapping[OptionKey, str] = collections.OrderedDict()
## Read in native file(s) to override build machine configuration
@ -655,9 +655,9 @@ class Environment:
# Warn if the user is using two different ways of setting build-type
# options that override each other
bt = coredata.OptionKey('buildtype')
db = coredata.OptionKey('debug')
op = coredata.OptionKey('optimization')
bt = OptionKey('buildtype')
db = OptionKey('debug')
op = OptionKey('optimization')
if bt in self.options and (db in self.options or op in self.options):
mlog.warning('Recommend using either -Dbuildtype or -Doptimization + -Ddebug. '
'Using both is redundant since they override each other. '
@ -723,7 +723,7 @@ class Environment:
if paths:
mlog.deprecation('The [paths] section is deprecated, use the [built-in options] section instead.')
for k, v in paths.items():
self.options[coredata.OptionKey.from_string(k).evolve(machine=machine)] = v
self.options[OptionKey.from_string(k).evolve(machine=machine)] = v
deprecated_properties = set()
for lang in compilers.all_languages:
deprecated_properties.add(lang + '_args')
@ -731,7 +731,7 @@ class Environment:
for k, v in properties.properties.copy().items():
if k in deprecated_properties:
mlog.deprecation('{} in the [properties] section of the machine file is deprecated, use the [built-in options] section.'.format(k))
self.options[coredata.OptionKey.from_string(k).evolve(machine=machine)] = v
self.options[OptionKey.from_string(k).evolve(machine=machine)] = v
del properties.properties[k]
for section, values in config.items():
if ':' in section:
@ -740,12 +740,12 @@ class Environment:
subproject = ''
if section == 'built-in options':
for k, v in values.items():
key = coredata.OptionKey.from_string(k).evolve(subproject=subproject, machine=machine)
key = OptionKey.from_string(k).evolve(subproject=subproject, machine=machine)
self.options[key] = v
elif section == 'project options':
for k, v in values.items():
# Project options are always for the machine machine
key = coredata.OptionKey.from_string(k).evolve(subproject=subproject)
key = OptionKey.from_string(k).evolve(subproject=subproject)
self.options[key] = v
def set_default_options_from_env(self) -> None:
@ -763,7 +763,7 @@ class Environment:
# FIXME: We should remember if we took the value from env to warn
# if it changes on future invocations.
if self.first_invocation:
key = coredata.OptionKey(keyname, machine=for_machine)
key = OptionKey(keyname, machine=for_machine)
self.options.setdefault(key, p_list)
def create_new_coredata(self, options: 'argparse.Namespace') -> None:
@ -938,7 +938,7 @@ class Environment:
elif isinstance(comp_class.LINKER_PREFIX, list):
check_args = comp_class.LINKER_PREFIX + ['/logo'] + comp_class.LINKER_PREFIX + ['--version']
check_args += self.coredata.compiler_options[coredata.OptionKey('args', lang=comp_class.language, machine=for_machine)].value
check_args += self.coredata.compiler_options[OptionKey('args', lang=comp_class.language, machine=for_machine)].value
override = [] # type: T.List[str]
value = self.lookup_binary_entry(for_machine, comp_class.language + '_ld')
@ -1004,7 +1004,7 @@ class Environment:
"""
self.coredata.add_lang_args(comp_class.language, comp_class, for_machine, self)
extra_args = extra_args or []
extra_args += self.coredata.compiler_options[coredata.OptionKey('args', lang=comp_class.language, machine=for_machine)].value
extra_args += self.coredata.compiler_options[OptionKey('args', lang=comp_class.language, machine=for_machine)].value
if isinstance(comp_class.LINKER_PREFIX, str):
check_args = [comp_class.LINKER_PREFIX + '--version'] + extra_args

@ -3067,7 +3067,7 @@ external dependencies (including libraries) must go to "dependencies".''')
if v is not None:
return v
key = coredata.OptionKey.from_string(optname)
key = mesonlib.OptionKey.from_string(optname)
for opts in [self.coredata.compiler_options]:
v = opts.get(key)
if v is None or v.yielding:

@ -21,7 +21,8 @@ from .mesonlib import MachineChoice
if T.TYPE_CHECKING:
import argparse
from .coredata import OptionKey, UserOption
from .coredata import UserOption
from .mesonlib import OptionKey
def add_arguments(parser: 'argparse.ArgumentParser') -> None:
coredata.register_builtin_arguments(parser)

@ -14,6 +14,7 @@
"""A library of random helper functionality."""
from pathlib import Path
import enum
import sys
import stat
import time
@ -1780,3 +1781,199 @@ class OptionOverrideProxy(collections.abc.MutableMapping):
def copy(self) -> 'OptionOverrideProxy':
return OptionOverrideProxy(self.overrides.copy(), self.options.copy())
class OptionType(enum.Enum):
"""Enum used to specify what kind of argument a thing is."""
BUILTIN = 0
BASE = 1
COMPILER = 2
PROJECT = 3
BACKEND = 4
def _classify_argument(key: 'OptionKey') -> OptionType:
"""Classify arguments into groups so we know which dict to assign them to."""
from .compilers import base_options
from .coredata import BUILTIN_OPTIONS, BUILTIN_OPTIONS_PER_MACHINE, builtin_dir_noprefix_options
all_builtins = set(BUILTIN_OPTIONS) | set(BUILTIN_OPTIONS_PER_MACHINE) | set(builtin_dir_noprefix_options)
if key.name in base_options:
assert key.machine is MachineChoice.HOST, str(key)
return OptionType.BASE
elif key.lang is not None:
return OptionType.COMPILER
elif key.name in all_builtins:
return OptionType.BUILTIN
elif key.name.startswith('backend_'):
assert key.machine is MachineChoice.HOST, str(key)
return OptionType.BACKEND
else:
assert key.machine is MachineChoice.HOST, str(key)
return OptionType.PROJECT
class OptionKey:
"""Represents an option key in the various option dictionaries.
This provides a flexible, powerful way to map option names from their
external form (things like subproject:build.option) to something that
internally easier to reason about and produce.
"""
__slots__ = ['name', 'subproject', 'machine', 'lang', '_hash', 'type']
name: str
subproject: str
machine: MachineChoice
lang: T.Optional[str]
_hash: int
type: OptionType
def __init__(self, name: str, subproject: str = '',
machine: MachineChoice = MachineChoice.HOST,
lang: T.Optional[str] = None, _type: T.Optional[OptionType] = None):
# the _type option to the constructor is kinda private. We want to be
# able tos ave the state and avoid the lookup function when
# pickling/unpickling, but we need to be able to calculate it when
# constructing a new OptionKey
object.__setattr__(self, 'name', name)
object.__setattr__(self, 'subproject', subproject)
object.__setattr__(self, 'machine', machine)
object.__setattr__(self, 'lang', lang)
object.__setattr__(self, '_hash', hash((name, subproject, machine, lang)))
if _type is None:
_type = _classify_argument(self)
object.__setattr__(self, 'type', _type)
def __setattr__(self, key: str, value: T.Any) -> None:
raise AttributeError('OptionKey instances do not support mutation.')
def __getstate__(self) -> T.Dict[str, T.Any]:
return {
'name': self.name,
'subproject': self.subproject,
'machine': self.machine,
'lang': self.lang,
'_type': self.type,
}
def __setstate__(self, state: T.Dict[str, T.Any]) -> None:
"""De-serialize the state of a pickle.
This is very clever. __init__ is not a constructor, it's an
initializer, therefore it's safe to call more than once. We create a
state in the custom __getstate__ method, which is valid to pass
unsplatted to the initializer.
"""
self.__init__(**state)
def __hash__(self) -> int:
return self._hash
def __eq__(self, other: object) -> bool:
if isinstance(other, OptionKey):
return (
self.name == other.name and
self.subproject == other.subproject and
self.machine is other.machine and
self.lang == other.lang)
return NotImplemented
def __str__(self) -> str:
out = self.name
if self.lang:
out = f'{self.lang}_{out}'
if self.machine is MachineChoice.BUILD:
out = f'build.{out}'
if self.subproject:
out = f'{self.subproject}:{out}'
return out
def __repr__(self) -> str:
return f'OptionKey({repr(self.name)}, {repr(self.subproject)}, {repr(self.machine)}, {repr(self.lang)})'
@classmethod
def from_string(cls, raw: str) -> 'OptionKey':
"""Parse the raw command line format into a three part tuple.
This takes strings like `mysubproject:build.myoption` and Creates an
OptionKey out of them.
"""
try:
subproject, raw2 = raw.split(':')
except ValueError:
subproject, raw2 = '', raw
if raw2.startswith('build.'):
raw3 = raw2.lstrip('build.')
for_machine = MachineChoice.BUILD
else:
raw3 = raw2
for_machine = MachineChoice.HOST
from .compilers import all_languages
if any(raw3.startswith(f'{l}_') for l in all_languages):
lang, opt = raw3.split('_', 1)
else:
lang, opt = None, raw3
assert ':' not in opt
assert 'build.' not in opt
return cls(opt, subproject, for_machine, lang)
def evolve(self, name: T.Optional[str] = None, subproject: T.Optional[str] = None,
machine: T.Optional[MachineChoice] = None, lang: T.Optional[str] = '') -> 'OptionKey':
"""Create a new copy of this key, but with alterted members.
For example:
>>> a = OptionKey('foo', '', MachineChoice.Host)
>>> b = OptionKey('foo', 'bar', MachineChoice.Host)
>>> b == a.evolve(subproject='bar')
True
"""
# We have to be a little clever with lang here, because lang is valid
# as None, for non-compiler options
return OptionKey(
name if name is not None else self.name,
subproject if subproject is not None else self.subproject,
machine if machine is not None else self.machine,
lang if lang != '' else self.lang,
)
def as_root(self) -> 'OptionKey':
"""Convenience method for key.evolve(subproject='')."""
return self.evolve(subproject='')
def as_build(self) -> 'OptionKey':
"""Convenience method for key.evolve(machine=MachinceChoice.BUILD)."""
return self.evolve(machine=MachineChoice.BUILD)
def as_host(self) -> 'OptionKey':
"""Convenience method for key.evolve(machine=MachinceChoice.HOST)."""
return self.evolve(machine=MachineChoice.HOST)
def is_backend(self) -> bool:
"""Convenience method to check if this is a backend option."""
return self.type is OptionType.BACKEND
def is_builtin(self) -> bool:
"""Convenience method to check if this is a builtin option."""
return self.type is OptionType.BUILTIN
def is_compiler(self) -> bool:
"""Convenience method to check if this is a builtin option."""
return self.type is OptionType.COMPILER
def is_project(self) -> bool:
"""Convenience method to check if this is a project option."""
return self.type is OptionType.PROJECT
def is_base(self) -> bool:
"""Convenience method to check if this is a base option."""
return self.type is OptionType.BASE

@ -34,7 +34,8 @@ from mesonbuild import mesonmain
from mesonbuild import mtest
from mesonbuild import mlog
from mesonbuild.environment import Environment, detect_ninja
from mesonbuild.coredata import backendlist, version as meson_version, OptionKey
from mesonbuild.coredata import backendlist, version as meson_version
from mesonbuild.mesonlib import OptionKey
NINJA_1_9_OR_NEWER = False
NINJA_CMD = None

@ -59,12 +59,11 @@ from mesonbuild.mesonlib import (
quote_arg, relpath, is_linux, git, GIT
)
from mesonbuild.environment import detect_ninja
from mesonbuild.mesonlib import MesonException, EnvironmentException
from mesonbuild.mesonlib import MesonException, EnvironmentException, OptionKey
from mesonbuild.dependencies import PkgConfigDependency, ExternalProgram
import mesonbuild.dependencies.base
from mesonbuild.build import Target, ConfigurationData
import mesonbuild.modules.pkgconfig
from mesonbuild.coredata import OptionKey
from mesonbuild.mtest import TAPParser, TestResult

Loading…
Cancel
Save