coredata: remove extraneous keys when updating project_options
This can happen when a project's meson.options file is updated, and an
old option is removed.
diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py
index 046c0a2..17eb1d5 100644
--- a/mesonbuild/ast/introspection.py
+++ b/mesonbuild/ast/introspection.py
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2018 The Meson development team
+# Copyright © 2024 Intel Corporation
# This class contains the basic functionality needed to run any interpreter
# or an interpreter-based tool
@@ -106,7 +107,8 @@
if os.path.exists(optfile):
oi = optinterpreter.OptionInterpreter(self.subproject)
oi.process(optfile)
- self.coredata.update_project_options(oi.options)
+ assert isinstance(proj_name, str), 'for mypy'
+ self.coredata.update_project_options(oi.options, T.cast('SubProject', proj_name))
def_opts = self.flatten_args(kwargs.get('default_options', []))
_project_default_options = mesonlib.stringlistify(def_opts)
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index df57598..0c2f501 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright 2013-2024 The Meson development team
-# Copyright © 2023 Intel Corporation
+# Copyright © 2023-2024 Intel Corporation
from __future__ import annotations
@@ -15,7 +15,7 @@
from dataclasses import dataclass
from .mesonlib import (
- HoldableObject,
+ HoldableObject, MesonBugException,
MesonException, EnvironmentException, MachineChoice, PerMachine,
PerMachineDefaultable, default_libdir, default_libexecdir,
default_prefix, default_datadir, default_includedir, default_infodir,
@@ -40,6 +40,7 @@
from .environment import Environment
from .mesonlib import FileOrString
from .cmake.traceparser import CMakeCacheEntry
+ from .interpreterbase import SubProject
class SharedCMDOptions(Protocol):
@@ -892,13 +893,15 @@
# mypy cannot analyze type of OptionKey
return T.cast('T.List[str]', self.options[OptionKey('link_args', machine=for_machine, lang=lang)].value)
- def update_project_options(self, options: 'MutableKeyedOptionDictType') -> None:
+ def update_project_options(self, options: 'MutableKeyedOptionDictType', subproject: SubProject) -> None:
for key, value in options.items():
if not key.is_project():
continue
if key not in self.options:
self.options[key] = value
continue
+ if key.subproject != subproject:
+ raise MesonBugException(f'Tried to set an option for subproject {key.subproject} from {subproject}!')
oldval = self.options[key]
if type(oldval) is not type(value):
@@ -914,6 +917,11 @@
mlog.warning(f'Old value(s) of {key} are no longer valid, resetting to default ({value.value}).',
fatal=False)
+ # Find any extranious keys for this project and remove them
+ for key in list(self.options.keys() - options.keys()):
+ if key.is_project() and key.subproject == subproject:
+ del self.options[key]
+
def is_cross_build(self, when_building_for: MachineChoice = MachineChoice.HOST) -> bool:
if when_building_for == MachineChoice.BUILD:
return False
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index 47d0d2d..d870de1 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -1035,7 +1035,7 @@
FeatureNew.single_use('Cargo subproject', '1.3.0', self.subproject, location=self.current_node)
with mlog.nested(subp_name):
ast, options = cargo.interpret(subp_name, subdir, self.environment)
- self.coredata.update_project_options(options)
+ self.coredata.update_project_options(options, subp_name)
return self._do_subproject_meson(
subp_name, subdir, default_options, kwargs, ast,
# FIXME: Are there other files used by cargo interpreter?
@@ -1189,7 +1189,7 @@
if os.path.exists(option_file):
oi = optinterpreter.OptionInterpreter(self.subproject)
oi.process(option_file)
- self.coredata.update_project_options(oi.options)
+ self.coredata.update_project_options(oi.options, self.subproject)
self.add_build_def_file(option_file)
if self.subproject: