options: merge set_value and set_option
Which are basically the same, except for handling of deprecated options, and various bugs that only existed in one implementation or the other.
This commit is contained in:
parent
251f74dcf3
commit
c56e42c119
|
@ -417,7 +417,7 @@ class CoreData:
|
||||||
def set_option(self, key: OptionKey, value, first_invocation: bool = False) -> bool:
|
def set_option(self, key: OptionKey, value, first_invocation: bool = False) -> bool:
|
||||||
dirty = False
|
dirty = False
|
||||||
try:
|
try:
|
||||||
changed = self.optstore.set_value(key, value, first_invocation)
|
changed = self.optstore.set_option(key, value, first_invocation)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise MesonException(f'Tried to set unknown builtin option {str(key)}')
|
raise MesonException(f'Tried to set unknown builtin option {str(key)}')
|
||||||
dirty |= changed
|
dirty |= changed
|
||||||
|
@ -484,8 +484,8 @@ class CoreData:
|
||||||
assert value == 'custom'
|
assert value == 'custom'
|
||||||
return False
|
return False
|
||||||
|
|
||||||
dirty |= self.optstore.set_value('optimization', opt)
|
dirty |= self.optstore.set_option(OptionKey('optimization'), opt)
|
||||||
dirty |= self.optstore.set_value('debug', debug)
|
dirty |= self.optstore.set_option(OptionKey('debug'), debug)
|
||||||
|
|
||||||
return dirty
|
return dirty
|
||||||
|
|
||||||
|
@ -517,7 +517,7 @@ class CoreData:
|
||||||
|
|
||||||
oldval = self.optstore.get_value_object(key)
|
oldval = self.optstore.get_value_object(key)
|
||||||
if type(oldval) is not type(value):
|
if type(oldval) is not type(value):
|
||||||
self.optstore.set_value(key, value.value)
|
self.optstore.set_option(key, value.value)
|
||||||
elif options.choices_are_different(oldval, value):
|
elif options.choices_are_different(oldval, value):
|
||||||
# If the choices have changed, use the new value, but attempt
|
# If the choices have changed, use the new value, but attempt
|
||||||
# to keep the old options. If they are not valid keep the new
|
# to keep the old options. If they are not valid keep the new
|
||||||
|
@ -548,7 +548,7 @@ class CoreData:
|
||||||
assert not self.is_cross_build()
|
assert not self.is_cross_build()
|
||||||
for k in options.BUILTIN_OPTIONS_PER_MACHINE:
|
for k in options.BUILTIN_OPTIONS_PER_MACHINE:
|
||||||
o = self.optstore.get_value_object_for(k.name)
|
o = self.optstore.get_value_object_for(k.name)
|
||||||
dirty |= self.optstore.set_value(k, o.value, True)
|
dirty |= self.optstore.set_option(k, o.value, True)
|
||||||
for bk, bv in self.optstore.items():
|
for bk, bv in self.optstore.items():
|
||||||
if bk.machine is MachineChoice.BUILD:
|
if bk.machine is MachineChoice.BUILD:
|
||||||
hk = bk.as_host()
|
hk = bk.as_host()
|
||||||
|
@ -692,16 +692,16 @@ class CoreData:
|
||||||
if skey not in self.optstore:
|
if skey not in self.optstore:
|
||||||
self.optstore.add_system_option(skey, copy.deepcopy(compilers.BASE_OPTIONS[key]))
|
self.optstore.add_system_option(skey, copy.deepcopy(compilers.BASE_OPTIONS[key]))
|
||||||
if skey in env.options:
|
if skey in env.options:
|
||||||
self.optstore.set_value(skey, env.options[skey])
|
self.optstore.set_option(skey, env.options[skey])
|
||||||
elif subproject and key in env.options:
|
elif subproject and key in env.options:
|
||||||
self.optstore.set_value(skey, env.options[key])
|
self.optstore.set_option(skey, env.options[key])
|
||||||
# FIXME
|
# FIXME
|
||||||
#if subproject and not self.optstore.has_option(key):
|
#if subproject and not self.optstore.has_option(key):
|
||||||
# self.optstore[key] = copy.deepcopy(self.optstore[skey])
|
# self.optstore[key] = copy.deepcopy(self.optstore[skey])
|
||||||
elif skey in env.options:
|
elif skey in env.options:
|
||||||
self.optstore.set_value(skey, env.options[skey])
|
self.optstore.set_option(skey, env.options[skey])
|
||||||
elif subproject and key in env.options:
|
elif subproject and key in env.options:
|
||||||
self.optstore.set_value(skey, env.options[key])
|
self.optstore.set_option(skey, env.options[key])
|
||||||
self.emit_base_options_warnings()
|
self.emit_base_options_warnings()
|
||||||
|
|
||||||
def emit_base_options_warnings(self) -> None:
|
def emit_base_options_warnings(self) -> None:
|
||||||
|
|
|
@ -941,53 +941,27 @@ class OptionStore:
|
||||||
# .as_posix() keeps the posix-like file separators Meson uses.
|
# .as_posix() keeps the posix-like file separators Meson uses.
|
||||||
return value.as_posix()
|
return value.as_posix()
|
||||||
|
|
||||||
def set_value(self, key: T.Union[OptionKey, str], new_value: 'T.Any', first_invocation: bool = False) -> bool:
|
def _set_dependents(self, key: OptionKey, value: str) -> None:
|
||||||
key = self.ensure_and_validate_key(key)
|
|
||||||
if key.name == 'prefix':
|
|
||||||
new_value = self.sanitize_prefix(new_value)
|
|
||||||
elif self.is_builtin_option(key):
|
|
||||||
prefix = self.get_value_for('prefix')
|
|
||||||
assert isinstance(prefix, str)
|
|
||||||
new_value = self.sanitize_dir_option_value(prefix, key, new_value)
|
|
||||||
if key not in self.options:
|
|
||||||
raise MesonException(f'Unknown options: "{key.name}" not found.')
|
|
||||||
|
|
||||||
valobj = self.options[key]
|
|
||||||
old_value = valobj.value
|
|
||||||
changed = valobj.set_value(new_value)
|
|
||||||
|
|
||||||
if valobj.readonly and changed and not first_invocation:
|
|
||||||
raise MesonException(f'Tried to modify read only option {str(key)!r}')
|
|
||||||
|
|
||||||
if key.name == 'prefix' and first_invocation and changed:
|
|
||||||
assert isinstance(old_value, str)
|
|
||||||
self.reset_prefixed_options(old_value, new_value)
|
|
||||||
|
|
||||||
if changed:
|
|
||||||
self.set_dependents(key, new_value)
|
|
||||||
|
|
||||||
return changed
|
|
||||||
|
|
||||||
def set_dependents(self, key: OptionKey, value: str) -> None:
|
|
||||||
if key.name != 'buildtype':
|
|
||||||
return
|
|
||||||
opt, debug = self.DEFAULT_DEPENDENTS[value]
|
opt, debug = self.DEFAULT_DEPENDENTS[value]
|
||||||
dkey = key.evolve(name='debug')
|
dkey = key.evolve(name='debug')
|
||||||
optkey = key.evolve(name='optimization')
|
optkey = key.evolve(name='optimization')
|
||||||
self.options[dkey].set_value(debug)
|
self.options[dkey].set_value(debug)
|
||||||
self.options[optkey].set_value(opt)
|
self.options[optkey].set_value(opt)
|
||||||
|
|
||||||
def set_option(self, key: OptionKey, new_value: str, first_invocation: bool = False) -> bool:
|
def set_option(self, key: OptionKey, new_value: ElementaryOptionValues, first_invocation: bool = False) -> bool:
|
||||||
assert isinstance(key, OptionKey)
|
|
||||||
# FIXME, dupe of set_value
|
|
||||||
# Remove one of the two before merging to master.
|
|
||||||
if key.name == 'prefix':
|
if key.name == 'prefix':
|
||||||
|
assert isinstance(new_value, str), 'for mypy'
|
||||||
new_value = self.sanitize_prefix(new_value)
|
new_value = self.sanitize_prefix(new_value)
|
||||||
elif self.is_builtin_option(key):
|
elif self.is_builtin_option(key):
|
||||||
prefix = self.get_value_for('prefix')
|
prefix = self.get_value_for('prefix')
|
||||||
assert isinstance(prefix, str)
|
assert isinstance(prefix, str), 'for mypy'
|
||||||
new_value = self.sanitize_dir_option_value(prefix, key, new_value)
|
new_value = self.sanitize_dir_option_value(prefix, key, new_value)
|
||||||
opt = self.get_value_object_for(key)
|
|
||||||
|
try:
|
||||||
|
opt = self.get_value_object_for(key)
|
||||||
|
except KeyError:
|
||||||
|
raise MesonException(f'Unknown options: "{key!s}" not found.')
|
||||||
|
|
||||||
if opt.deprecated is True:
|
if opt.deprecated is True:
|
||||||
mlog.deprecation(f'Option {key.name!r} is deprecated')
|
mlog.deprecation(f'Option {key.name!r} is deprecated')
|
||||||
elif isinstance(opt.deprecated, list):
|
elif isinstance(opt.deprecated, list):
|
||||||
|
@ -1014,15 +988,17 @@ class OptionStore:
|
||||||
old_value = opt.value
|
old_value = opt.value
|
||||||
changed = opt.set_value(new_value)
|
changed = opt.set_value(new_value)
|
||||||
|
|
||||||
if opt.readonly and changed:
|
if opt.readonly and changed and not first_invocation:
|
||||||
raise MesonException(f'Tried modify read only option {str(key)!r}')
|
raise MesonException(f'Tried to modify read only option {str(key)!r}')
|
||||||
|
|
||||||
if key.name == 'prefix' and first_invocation and changed:
|
if key.name == 'prefix' and first_invocation and changed:
|
||||||
assert isinstance(old_value, str), 'for mypy'
|
assert isinstance(old_value, str), 'for mypy'
|
||||||
|
assert isinstance(new_value, str), 'for mypy'
|
||||||
self.reset_prefixed_options(old_value, new_value)
|
self.reset_prefixed_options(old_value, new_value)
|
||||||
|
|
||||||
if changed:
|
if changed and key.name == 'buildtype':
|
||||||
self.set_dependents(key, new_value)
|
assert isinstance(new_value, str), 'for mypy'
|
||||||
|
self._set_dependents(key, new_value)
|
||||||
|
|
||||||
return changed
|
return changed
|
||||||
|
|
||||||
|
@ -1032,9 +1008,9 @@ class OptionStore:
|
||||||
else:
|
else:
|
||||||
o = OptionKey.from_string(keystr)
|
o = OptionKey.from_string(keystr)
|
||||||
if o in self.options:
|
if o in self.options:
|
||||||
return self.set_value(o, new_value)
|
return self.set_option(o, new_value)
|
||||||
o = o.as_root()
|
o = o.as_root()
|
||||||
return self.set_value(o, new_value)
|
return self.set_option(o, new_value)
|
||||||
|
|
||||||
def set_from_configure_command(self, D_args: T.List[str], U_args: T.List[str]) -> bool:
|
def set_from_configure_command(self, D_args: T.List[str], U_args: T.List[str]) -> bool:
|
||||||
dirty = False
|
dirty = False
|
||||||
|
@ -1279,7 +1255,7 @@ class OptionStore:
|
||||||
augstr = str(key)
|
augstr = str(key)
|
||||||
self.augments[augstr] = valstr
|
self.augments[augstr] = valstr
|
||||||
elif key in self.options:
|
elif key in self.options:
|
||||||
self.set_value(key, valstr, first_invocation)
|
self.set_option(key, valstr, first_invocation)
|
||||||
else:
|
else:
|
||||||
proj_key = key.as_root()
|
proj_key = key.as_root()
|
||||||
if proj_key in self.options:
|
if proj_key in self.options:
|
||||||
|
@ -1330,7 +1306,7 @@ class OptionStore:
|
||||||
if not self.is_cross and key.is_for_build():
|
if not self.is_cross and key.is_for_build():
|
||||||
continue
|
continue
|
||||||
if key in self.options:
|
if key in self.options:
|
||||||
self.set_value(key, valstr, True)
|
self.set_option(key, valstr, True)
|
||||||
elif key.subproject is None:
|
elif key.subproject is None:
|
||||||
projectkey = key.as_root()
|
projectkey = key.as_root()
|
||||||
if projectkey in self.options:
|
if projectkey in self.options:
|
||||||
|
@ -1371,7 +1347,7 @@ class OptionStore:
|
||||||
# If the key points to a project option, set the value from that.
|
# If the key points to a project option, set the value from that.
|
||||||
# Otherwise set an augment.
|
# Otherwise set an augment.
|
||||||
if key in self.project_options:
|
if key in self.project_options:
|
||||||
self.set_value(key, valstr, is_first_invocation)
|
self.set_option(key, valstr, is_first_invocation)
|
||||||
else:
|
else:
|
||||||
self.pending_project_options.pop(key, None)
|
self.pending_project_options.pop(key, None)
|
||||||
aug_str = f'{subproject}:{keystr}'
|
aug_str = f'{subproject}:{keystr}'
|
||||||
|
@ -1385,6 +1361,6 @@ class OptionStore:
|
||||||
continue
|
continue
|
||||||
self.pending_project_options.pop(key, None)
|
self.pending_project_options.pop(key, None)
|
||||||
if key in self.options:
|
if key in self.options:
|
||||||
self.set_value(key, valstr, is_first_invocation)
|
self.set_option(key, valstr, is_first_invocation)
|
||||||
else:
|
else:
|
||||||
self.augments[str(key)] = valstr
|
self.augments[str(key)] = valstr
|
||||||
|
|
|
@ -451,7 +451,7 @@ class PlatformAgnosticTests(BasePlatformTests):
|
||||||
f.write(line)
|
f.write(line)
|
||||||
with self.assertRaises(subprocess.CalledProcessError) as e:
|
with self.assertRaises(subprocess.CalledProcessError) as e:
|
||||||
self.setconf('-Dneg_int_opt=0')
|
self.setconf('-Dneg_int_opt=0')
|
||||||
self.assertIn('Unknown options: "neg_int_opt"', e.exception.stdout)
|
self.assertIn('Unknown options: ":neg_int_opt"', e.exception.stdout)
|
||||||
|
|
||||||
def test_configure_option_changed_constraints(self) -> None:
|
def test_configure_option_changed_constraints(self) -> None:
|
||||||
"""Changing the constraints of an option without reconfiguring should work."""
|
"""Changing the constraints of an option without reconfiguring should work."""
|
||||||
|
@ -491,7 +491,7 @@ class PlatformAgnosticTests(BasePlatformTests):
|
||||||
os.unlink(os.path.join(testdir, 'meson_options.txt'))
|
os.unlink(os.path.join(testdir, 'meson_options.txt'))
|
||||||
with self.assertRaises(subprocess.CalledProcessError) as e:
|
with self.assertRaises(subprocess.CalledProcessError) as e:
|
||||||
self.setconf('-Dneg_int_opt=0')
|
self.setconf('-Dneg_int_opt=0')
|
||||||
self.assertIn('Unknown options: "neg_int_opt"', e.exception.stdout)
|
self.assertIn('Unknown options: ":neg_int_opt"', e.exception.stdout)
|
||||||
|
|
||||||
def test_configure_options_file_added(self) -> None:
|
def test_configure_options_file_added(self) -> None:
|
||||||
"""A new project option file should be detected."""
|
"""A new project option file should be detected."""
|
||||||
|
|
Loading…
Reference in New Issue