Skip to content

Commit

Permalink
Fix spurious error message
Browse files Browse the repository at this point in the history
Make it clear that reading meson.options or a meson -Dopt=value parameter
by using get_option() as a parameter to project() isn't allowed.
  • Loading branch information
bcorby committed Dec 18, 2024
1 parent bcb6052 commit 9e5af6d
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 23 deletions.
75 changes: 52 additions & 23 deletions mesonbuild/interpreter/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -1078,8 +1078,6 @@ def get_option_internal(self, optname: str) -> options.UserOption:
except KeyError:
pass

raise InterpreterException(f'Tried to access unknown option {optname!r}.')

@typed_pos_args('get_option', str)
@noKwargs
def func_get_option(self, nodes: mparser.BaseNode, args: T.Tuple[str],
Expand All @@ -1096,12 +1094,34 @@ def func_get_option(self, nodes: mparser.BaseNode, args: T.Tuple[str],
opt = self.get_option_internal(optname)
if isinstance(opt, options.UserFeatureOption):
opt.name = optname
return opt
_option_value = opt
elif isinstance(opt, options.UserOption):
if isinstance(opt.value, str):
return P_OBJ.OptionString(opt.value, f'{{{optname}}}')
return opt.value
return opt
_option_value = P_OBJ.OptionString(opt.value, f'{{{optname}}}')
else:
_option_value = opt.value
else:
_option_value = opt

self.load_options(nodes, args)
opt = self.get_option_internal(optname)
if isinstance(opt, options.UserFeatureOption):
opt.name = optname
option_value = opt
elif isinstance(opt, options.UserOption):
if isinstance(opt.value, str):
option_value = P_OBJ.OptionString(opt.value, f'{{{optname}}}')
else:
option_value = opt.value
else:
option_value = opt

if option_value is None and _option_value is None:
raise InterpreterException(f'Tried to access unknown option {optname!r}.')
elif not option_value == _option_value:
if not hasattr(self, 'prohibited_load_options_used'):
self.prohibited_load_options_used = {'option': optname, 'value': option_value}
return option_value

@typed_pos_args('configuration_data', optargs=[dict])
@noKwargs
Expand Down Expand Up @@ -1148,6 +1168,23 @@ def set_backend(self) -> None:
options = {k: v for k, v in self.environment.options.items() if self.environment.coredata.optstore.is_backend_option(k)}
self.coredata.set_options(options)

def load_options(self, node: mparser.FunctionNode, args: T.Tuple[str, T.List[str]]) -> None:
option_file = os.path.join(self.source_root, self.subdir, 'meson.options')
old_option_file = os.path.join(self.source_root, self.subdir, 'meson_options.txt')
if not os.path.exists(option_file):
option_file = old_option_file
if os.path.exists(option_file):
with open(option_file, 'rb') as f:
# We want fast not cryptographically secure, this is just to
# see if the option file has changed
self.coredata.options_files[self.subproject] = (option_file, hashlib.sha1(f.read()).hexdigest())
oi = optinterpreter.OptionInterpreter(self.environment.coredata.optstore, self.subproject)
oi.process(option_file)
self.coredata.update_project_options(oi.options, self.subproject)
self.add_build_def_file(option_file)
else:
self.coredata.options_files[self.subproject] = None

@typed_pos_args('project', str, varargs=str)
@typed_kwargs(
'project',
Expand All @@ -1169,19 +1206,19 @@ def func_project(self, node: mparser.FunctionNode, args: T.Tuple[str, T.List[str
if ':' in proj_name:
raise InvalidArguments(f"Project name {proj_name!r} must not contain ':'")

# Read in the options file.
self.load_options(node, args)

# This needs to be evaluated as early as possible, as meson uses this
# for things like deprecation testing.
if kwargs['meson_version']:
self.handle_meson_version(kwargs['meson_version'], node)
else:
mesonlib.project_meson_versions[self.subproject] = mesonlib.NoProjectVersion()

# Load "meson.options" before "meson_options.txt", and produce a warning if
# it is being used with an old version. I have added check that if both
# exist the warning isn't raised
# Warn about use of meson.options / meson_options.txt.
option_file = os.path.join(self.source_root, self.subdir, 'meson.options')
old_option_file = os.path.join(self.source_root, self.subdir, 'meson_options.txt')

if os.path.exists(option_file):
if os.path.exists(old_option_file):
if os.path.samefile(option_file, old_option_file):
Expand All @@ -1190,19 +1227,11 @@ def func_project(self, node: mparser.FunctionNode, args: T.Tuple[str, T.List[str
raise MesonException("meson.options and meson_options.txt both exist, but are not the same file.")
else:
FeatureNew.single_use('meson.options file', '1.1', self.subproject, 'Use meson_options.txt instead')
else:
option_file = old_option_file
if os.path.exists(option_file):
with open(option_file, 'rb') as f:
# We want fast not cryptographically secure, this is just to
# see if the option file has changed
self.coredata.options_files[self.subproject] = (option_file, hashlib.sha1(f.read()).hexdigest())
oi = optinterpreter.OptionInterpreter(self.environment.coredata.optstore, self.subproject)
oi.process(option_file)
self.coredata.update_project_options(oi.options, self.subproject)
self.add_build_def_file(option_file)
else:
self.coredata.options_files[self.subproject] = None

# Using get_option() in project() isn't allowed.
# For the reason see https://github.com/mesonbuild/meson/pull/14016
if hasattr(self, 'prohibited_load_options_used'):
FeatureBroken.single_use('Reading meson.options or a meson -Dopt=value parameter by using get_option() as a parameter to project() isn\'t allowed', '1.7', self.subproject, 'Instead use run_command(\'./get_value.py\', check: true).stdout().strip()')

if self.subproject:
self.project_default_options = {k.evolve(subproject=self.subproject): v
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Project
project('test', 'c', version: '1.0' + get_option('append_to_version'))
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
option('append_to_version', type : 'string', value : '.0001', description : 'append to version')
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"stdout": [
{
"line": "DEPRECATION: Project uses feature that was always broken, and is now deprecated since '1.7': Reading meson.options or a meson -Dopt=value parameter by using get_option() as a parameter to project() isn't allowed. Instead use run_command('./get_value.py', check: true).stdout().strip()"
}
]
}

0 comments on commit 9e5af6d

Please sign in to comment.