Skip to content

another round of option refactoring #14644

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 11 commits into from
Closed
9 changes: 5 additions & 4 deletions mesonbuild/coredata.py
Original file line number Diff line number Diff line change
Expand Up @@ -416,8 +416,8 @@ def get_option_for_target(self, target: 'BuildTarget', key: T.Union[str, OptionK
def set_from_configure_command(self, options: SharedCMDOptions) -> bool:
unset_opts = getattr(options, 'unset_opts', [])
all_D = options.projectoptions[:]
for keystr, valstr in options.cmd_line_options.items():
all_D.append(f'{keystr}={valstr}')
for key, valstr in options.cmd_line_options.items():
all_D.append(f'{key!s}={valstr}')
return self.optstore.set_from_configure_command(all_D, unset_opts)

def set_option(self, key: OptionKey, value, first_invocation: bool = False) -> bool:
Expand Down Expand Up @@ -712,9 +712,10 @@ def parse_cmd_line_options(args: SharedCMDOptions) -> None:
args.cmd_line_options = {}
for o in args.projectoptions:
try:
(key, value) = o.split('=', 1)
keystr, value = o.split('=', 1)
except ValueError:
raise MesonException(f'Option {o!r} must have a value separated by equals sign.')
key = OptionKey.from_string(keystr)
args.cmd_line_options[key] = value

# Merge builtin options set with --option into the dict.
Expand All @@ -730,7 +731,7 @@ def parse_cmd_line_options(args: SharedCMDOptions) -> None:
cmdline_name = options.argparse_name_to_arg(name)
raise MesonException(
f'Got argument {name} as both -D{name} and {cmdline_name}. Pick one.')
args.cmd_line_options[key.name] = value
args.cmd_line_options[key] = value
delattr(args, name)


Expand Down
6 changes: 3 additions & 3 deletions mesonbuild/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
if T.TYPE_CHECKING:
from .compilers import Compiler
from .compilers.mixins.visualstudio import VisualStudioLikeCompiler
from .options import ElementaryOptionValues
from .options import OptionDict, ElementaryOptionValues
from .wrap.wrap import Resolver
from . import cargo

Expand Down Expand Up @@ -646,12 +646,12 @@ def __init__(self, source_dir: str, build_dir: T.Optional[str], cmd_options: cor
#
# Note that order matters because of 'buildtype', if it is after
# 'optimization' and 'debug' keys, it override them.
self.options: T.MutableMapping[OptionKey, ElementaryOptionValues] = collections.OrderedDict()
self.options: OptionDict = collections.OrderedDict()

# Environment variables with the name converted into an OptionKey type.
# These have subtly different behavior compared to machine files, so do
# not store them in self.options. See _set_default_options_from_env.
self.env_opts: T.MutableMapping[OptionKey, ElementaryOptionValues] = {}
self.env_opts: OptionDict = {}

self.machinestore = machinefile.MachineFileStore(self.coredata.config_files, self.coredata.cross_files, self.source_dir)

Expand Down
22 changes: 10 additions & 12 deletions mesonbuild/interpreter/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ def __init__(
subproject: str = '',
subdir: str = '',
subproject_dir: str = 'subprojects',
invoker_method_default_options: T.Optional[T.Dict[OptionKey, str]] = None,
invoker_method_default_options: T.Optional[OptionDict] = None,
ast: T.Optional[mparser.CodeBlockNode] = None,
relaxations: T.Optional[T.Set[InterpreterRuleRelaxation]] = None,
user_defined_options: T.Optional[coredata.SharedCMDOptions] = None,
Expand Down Expand Up @@ -301,7 +301,7 @@ def __init__(
self.invoker_method_default_options = invoker_method_default_options
else:
self.invoker_method_default_options = {}
self.project_default_options: T.List[str] = []
self.project_default_options: OptionDict = {}
self.build_func_dict()
self.build_holder_map()
self.user_defined_options = user_defined_options
Expand Down Expand Up @@ -934,7 +934,8 @@ def do_subproject(self, subp_name: str, kwargs: kwtypes.DoSubproject, force_meth
m += ['method', mlog.bold(method)]
mlog.log(*m, '\n', nested=False)

methods_map: T.Dict[wrap.Method, T.Callable[[str, str, T.Dict[OptionKey, str, kwtypes.DoSubproject]], SubprojectHolder]] = {
methods_map: T.Dict[wrap.Method, T.Callable[[str, str, OptionDict, kwtypes.DoSubproject],
SubprojectHolder]] = {
'meson': self._do_subproject_meson,
'cmake': self._do_subproject_cmake,
'cargo': self._do_subproject_cargo,
Expand All @@ -956,7 +957,7 @@ def do_subproject(self, subp_name: str, kwargs: kwtypes.DoSubproject, force_meth
raise e

def _do_subproject_meson(self, subp_name: str, subdir: str,
default_options: T.Dict[str, options.ElementaryOptionValues],
default_options: OptionDict,
kwargs: kwtypes.DoSubproject,
ast: T.Optional[mparser.CodeBlockNode] = None,
build_def_files: T.Optional[T.List[str]] = None,
Expand Down Expand Up @@ -1016,7 +1017,7 @@ def _do_subproject_meson(self, subp_name: str, subdir: str,
return self.subprojects[subp_name]

def _do_subproject_cmake(self, subp_name: str, subdir: str,
default_options: T.Dict[str, options.ElementaryOptionValues],
default_options: OptionDict,
kwargs: kwtypes.DoSubproject) -> SubprojectHolder:
from ..cmake import CMakeInterpreter
with mlog.nested(subp_name):
Expand All @@ -1043,7 +1044,7 @@ def _do_subproject_cmake(self, subp_name: str, subdir: str,
return result

def _do_subproject_cargo(self, subp_name: str, subdir: str,
default_options: T.Dict[str, options.ElementaryOptionValues],
default_options: OptionDict,
kwargs: kwtypes.DoSubproject) -> SubprojectHolder:
from .. import cargo
FeatureNew.single_use('Cargo subproject', '1.3.0', self.subproject, location=self.current_node)
Expand Down Expand Up @@ -1189,9 +1190,6 @@ def func_project(self, node: mparser.FunctionNode, args: T.Tuple[str, T.List[str
self._load_option_file()

self.project_default_options = kwargs['default_options']
if isinstance(self.project_default_options, str):
self.project_default_options = [self.project_default_options]
assert isinstance(self.project_default_options, (list, dict))
if self.environment.first_invocation or (self.subproject != '' and self.subproject not in self.coredata.initialized_subprojects):
if self.subproject == '':
self.coredata.optstore.initialize_from_top_level_project_call(self.project_default_options,
Expand Down Expand Up @@ -1628,7 +1626,7 @@ def notfound_program(self, args: T.List[mesonlib.FileOrString]) -> ExternalProgr
# the host machine.
def find_program_impl(self, args: T.List[mesonlib.FileOrString],
for_machine: MachineChoice = MachineChoice.HOST,
default_options: T.Optional[T.Dict[OptionKey, options.ElementaryOptionValues]] = None,
default_options: T.Optional[OptionDict] = None,
required: bool = True, silent: bool = True,
wanted: T.Union[str, T.List[str]] = '',
search_dirs: T.Optional[T.List[str]] = None,
Expand Down Expand Up @@ -1659,7 +1657,7 @@ def find_program_impl(self, args: T.List[mesonlib.FileOrString],
return progobj

def program_lookup(self, args: T.List[mesonlib.FileOrString], for_machine: MachineChoice,
default_options: T.Optional[T.Dict[OptionKey, options.ElementaryOptionValues]],
default_options: T.Optional[OptionDict],
required: bool,
search_dirs: T.Optional[T.List[str]],
wanted: T.Union[str, T.List[str]],
Expand Down Expand Up @@ -1727,7 +1725,7 @@ def check_program_version(self, progobj: T.Union[ExternalProgram, build.Executab
return True

def find_program_fallback(self, fallback: str, args: T.List[mesonlib.FileOrString],
default_options: T.Dict[OptionKey, options.ElementaryOptionValues],
default_options: OptionDict,
required: bool, extra_info: T.List[mlog.TV_Loggable]
) -> T.Optional[T.Union[ExternalProgram, build.Executable, OverrideProgram]]:
mlog.log('Fallback to subproject', mlog.bold(fallback), 'which provides program',
Expand Down
20 changes: 10 additions & 10 deletions mesonbuild/msetup.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def generate(self, capture: bool = False, vslite_ctx: T.Optional[dict] = None) -
'Some other Meson process is already using this build directory. Exiting.'):
return self._generate(env, capture, vslite_ctx)

def check_unused_options(self, coredata: 'coredata.CoreData', cmd_line_options: T.Any, all_subprojects: T.Mapping[str, object]) -> None:
def check_unused_options(self, coredata: 'coredata.CoreData', cmd_line_options: T.Dict[OptionKey, str], all_subprojects: T.Mapping[str, object]) -> None:
pending = coredata.optstore.pending_options
errlist: T.List[str] = []
known_subprojects = all_subprojects.keys()
Expand All @@ -202,9 +202,8 @@ def check_unused_options(self, coredata: 'coredata.CoreData', cmd_line_options:
# because they might be used in future reconfigurations
if coredata.optstore.accept_as_pending_option(opt, known_subprojects):
continue
keystr = str(opt)
if keystr in cmd_line_options:
errlist.append(f'"{keystr}"')
if opt in cmd_line_options:
errlist.append(f'"{opt}"')
if errlist:
errstr = ', '.join(errlist)
raise MesonException(f'Unknown options: {errstr}')
Expand Down Expand Up @@ -348,17 +347,18 @@ def run_genvslite_setup(options: CMDOptions) -> None:
# invoke the appropriate 'meson compile ...' build commands upon the normal visual studio build/rebuild/clean actions, instead of using
# the native VS/msbuild system.
builddir_prefix = options.builddir
genvsliteval = options.cmd_line_options.pop('genvslite') # type: ignore [call-overload]
k_genvslite = OptionKey('genvslite')
genvsliteval = options.cmd_line_options.pop(k_genvslite)
# The command line may specify a '--backend' option, which doesn't make sense in conjunction with
# '--genvslite', where we always want to use a ninja back end -
k_backend = 'backend'
k_backend = OptionKey('backend')
if k_backend in options.cmd_line_options.keys():
if options.cmd_line_options[k_backend] != 'ninja': # type: ignore [index]
if options.cmd_line_options[k_backend] != 'ninja':
raise MesonException('Explicitly specifying a backend option with \'genvslite\' is not necessary '
'(the ninja backend is always used) but specifying a non-ninja backend '
'conflicts with a \'genvslite\' setup')
else:
options.cmd_line_options[k_backend] = 'ninja' # type: ignore [index]
options.cmd_line_options[k_backend] = 'ninja'
buildtypes_list = coredata.get_genvs_default_buildtype_list()
vslite_ctx = {}

Expand All @@ -369,7 +369,7 @@ def run_genvslite_setup(options: CMDOptions) -> None:
vslite_ctx[buildtypestr] = app.generate(capture=True)
#Now for generating the 'lite' solution and project files, which will use these builds we've just set up, above.
options.builddir = f'{builddir_prefix}_vs'
options.cmd_line_options[OptionKey('genvslite')] = genvsliteval
options.cmd_line_options[k_genvslite] = genvsliteval
app = MesonApp(options)
app.generate(capture=False, vslite_ctx=vslite_ctx)

Expand All @@ -385,7 +385,7 @@ def run(options: T.Union[CMDOptions, T.List[str]]) -> int:
# lie
options.pager = False

if 'genvslite' in options.cmd_line_options.keys():
if OptionKey('genvslite') in options.cmd_line_options.keys():
run_genvslite_setup(options)
else:
app = MesonApp(options)
Expand Down
Loading
Loading