From 5fffd564183d3b73a04e1b9bd3d35931a52c2103 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Mon, 6 Apr 2026 08:50:31 -0700 Subject: [PATCH 01/22] modules/gnome: Fix annotations of GenerateGir There are some missing values here, and some places where we are casting back to `dict[str, Any]` because of this. Let's fix the annotations --- mesonbuild/modules/gnome.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index 6dec8c43ba87..b4ac147f534b 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 # Copyright 2015-2016 The Meson development team -# Copyright © 2023-2025 Intel Corporation +# Copyright © 2023-2026 Intel Corporation '''This module provides helper functions for Gnome/GLib related functionality such as gobject-introspection, gresources and gtk-doc''' @@ -44,7 +44,7 @@ from ..compilers import Compiler from ..interpreter import Interpreter from ..interpreterbase import TYPE_var, TYPE_kwargs - from ..mesonlib import FileOrString + from ..mesonlib import EnvironmentVariables, FileOrString from ..programs import Program, CommandList, CommandListEntry class PostInstall(TypedDict): @@ -84,6 +84,7 @@ class GenerateGir(TypedDict): build_by_default: bool dependencies: T.List[Dependency] doc_format: T.Optional[str] + env: EnvironmentVariables export_packages: T.List[str] extra_args: T.List[str] fatal_warnings: bool @@ -92,8 +93,10 @@ class GenerateGir(TypedDict): include_directories: T.List[T.Union[build.IncludeDirs, str]] includes: T.List[T.Union[str, GirTarget]] install: bool - install_dir_gir: T.Optional[str] - install_dir_typelib: T.Optional[str] + install_gir: T.Optional[bool] + install_dir_gir: T.Union[str, None, Literal[False]] + install_typelib: T.Optional[bool] + install_dir_typelib: T.Union[str, None, Literal[False]] link_with: T.List[T.Union[build.SharedLibrary, build.StaticLibrary]] namespace: str nsversion: str @@ -972,7 +975,7 @@ def _make_gir_target( generated_files: T.Sequence[T.Union[str, mesonlib.File, build.GeneratedTypes]], depends: T.Sequence[T.Union['FileOrString', build.BuildTarget, 'build.GeneratedTypes', build.StructuredSources]], env_flags: T.Sequence[str], - kwargs: T.Dict[str, T.Any]) -> GirTarget: + kwargs: GenerateGir) -> GirTarget: install = kwargs['install_gir'] if install is None: install = kwargs['install'] @@ -1023,7 +1026,7 @@ def _make_gir_target( def _make_typelib_target(state: 'ModuleState', typelib_output: str, typelib_cmd: T.Sequence[T.Union[str, CustomTarget, Program]], generated_files: T.Sequence[T.Union[str, mesonlib.File, build.GeneratedTypes]], - kwargs: T.Dict[str, T.Any]) -> TypelibTarget: + kwargs: GenerateGir) -> TypelibTarget: install = kwargs['install_typelib'] if install is None: install = kwargs['install'] @@ -1244,9 +1247,8 @@ def generate_gir(self, state: 'ModuleState', args: T.Tuple[T.List[T.Union[Execut generated_files = [f for f in libsources if isinstance(f, (GeneratedList, CustomTarget, CustomTargetIndex))] scan_target = self._make_gir_target( - state, girfile, scan_command, generated_files, depends, scan_env_ldflags, - # We have to cast here because mypy can't figure this out - T.cast('T.Dict[str, T.Any]', kwargs)) + state, girfile, scan_command, generated_files, depends, + scan_env_ldflags, kwargs) typelib_output = f'{ns}-{nsversion}.typelib' typelib_cmd: T.List[T.Union[str, Program, CustomTarget]] @@ -1256,7 +1258,8 @@ def generate_gir(self, state: 'ModuleState', args: T.Tuple[T.List[T.Union[Execut for incdir in typelib_includes: typelib_cmd += ["--includedir=" + incdir] - typelib_target = self._make_typelib_target(state, typelib_output, typelib_cmd, generated_files, T.cast('T.Dict[str, T.Any]', kwargs)) + typelib_target = self._make_typelib_target( + state, typelib_output, typelib_cmd, generated_files, kwargs) self._devenv_prepend('GI_TYPELIB_PATH', os.path.join(state.environment.get_build_dir(), state.subdir)) From aecb028483be3496a39838d49e44ccb99d0f9d23 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 3 Apr 2026 09:07:31 -0700 Subject: [PATCH 02/22] compilers: Don't pass Environment into compiler methods Compilers and Linkers already have an Environment reference, so passing them in complicates the API needlessly. --- mesonbuild/backend/vs2010backend.py | 2 +- mesonbuild/compilers/asm.py | 14 +++++++------- mesonbuild/compilers/compilers.py | 13 +++++++------ mesonbuild/compilers/cuda.py | 10 +++++----- mesonbuild/compilers/d.py | 16 ++++++++-------- mesonbuild/compilers/mixins/clang.py | 9 ++++----- mesonbuild/compilers/mixins/clike.py | 8 ++++---- mesonbuild/compilers/mixins/visualstudio.py | 5 ++--- mesonbuild/compilers/rust.py | 6 +++--- mesonbuild/dependencies/boost.py | 2 +- 10 files changed, 42 insertions(+), 43 deletions(-) diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index 4f78f6708454..049b86a7074e 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -1349,7 +1349,7 @@ def add_non_makefile_vcxproj_elements( ET.SubElement(clconf, 'OpenMPSupport').text = 'true' # CRT type; debug or release vscrt_type = self.get_target_option(target, 'b_vscrt') - vscrt_val = compiler.get_crt_val(vscrt_type, self.environment) + vscrt_val = compiler.get_crt_val(vscrt_type) if vscrt_val == 'mdd': ET.SubElement(type_config, 'UseDebugLibraries').text = 'true' ET.SubElement(clconf, 'RuntimeLibrary').text = 'MultiThreadedDebugDLL' diff --git a/mesonbuild/compilers/asm.py b/mesonbuild/compilers/asm.py index c8dfc2371f83..6902652e8509 100644 --- a/mesonbuild/compilers/asm.py +++ b/mesonbuild/compilers/asm.py @@ -148,16 +148,16 @@ def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:])) return parameter_list - def get_crt_compile_args(self, crt_val: str, env: Environment) -> T.List[str]: + def get_crt_compile_args(self, crt_val: str) -> T.List[str]: return [] # Linking ASM-only objects into an executable or DLL # require this, otherwise it'll fail to find # _WinMain or _DllMainCRTStartup. - def get_crt_link_args(self, crt_val: str, env: Environment) -> T.List[str]: + def get_crt_link_args(self, crt_val: str) -> T.List[str]: if not isinstance(self.linker, VisualStudioLikeLinkerMixin): return [] - return self.crt_args[self.get_crt_val(crt_val, env)] + return self.crt_args[self.get_crt_val(crt_val)] class YasmCompiler(NasmCompiler): id = 'yasm' @@ -233,7 +233,7 @@ def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:])) return parameter_list - def get_crt_compile_args(self, crt_val: str, env: Environment) -> T.List[str]: + def get_crt_compile_args(self, crt_val: str) -> T.List[str]: return [] def depfile_for_object(self, objfile: str) -> T.Optional[str]: @@ -281,7 +281,7 @@ def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:])) return parameter_list - def get_crt_compile_args(self, crt_val: str, env: Environment) -> T.List[str]: + def get_crt_compile_args(self, crt_val: str) -> T.List[str]: return [] def get_depfile_format(self) -> str: @@ -309,7 +309,7 @@ def needs_static_linker(self) -> bool: def get_always_args(self) -> T.List[str]: return [] - def get_crt_compile_args(self, crt_val: str, env: Environment) -> T.List[str]: + def get_crt_compile_args(self, crt_val: str) -> T.List[str]: return [] def get_depfile_suffix(self) -> str: @@ -334,7 +334,7 @@ def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, 'everything': []} self.can_compile_suffixes.add('s') - def get_crt_compile_args(self, crt_val: str, env: Environment) -> T.List[str]: + def get_crt_compile_args(self, crt_val: str) -> T.List[str]: return [] def get_optimization_args(self, optimization_level: str) -> T.List[str]: diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 370ccc3f2b07..9c6aec5c96eb 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -344,7 +344,7 @@ def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Env crt_val = env.coredata.get_option_for_target(target, 'b_vscrt') assert isinstance(crt_val, str) try: - args += compiler.get_crt_compile_args(crt_val, env) + args += compiler.get_crt_compile_args(crt_val) except AttributeError: pass except KeyError: @@ -432,7 +432,7 @@ def get_base_link_args(target: 'BuildTarget', crt_val = env.coredata.get_option_for_target(target, 'b_vscrt') assert isinstance(crt_val, str) try: - crtargs = linker.get_crt_link_args(crt_val, env) + crtargs = linker.get_crt_link_args(crt_val) assert isinstance(crtargs, list) args += crtargs except AttributeError: @@ -1160,7 +1160,7 @@ def get_assert_args(self, disable: bool) -> T.List[str]: """ return [] - def get_crt_val(self, crt_val: str, env: Environment) -> str: + def get_crt_val(self, crt_val: str) -> str: if crt_val in options.MSCRT_VALS: return crt_val assert crt_val in {'from_buildtype', 'static_from_buildtype'} @@ -1172,7 +1172,8 @@ def get_crt_val(self, crt_val: str, env: Environment) -> str: rel = 'mt' # Match what build type flags used to do. - buildtype = env.coredata.optstore.get_value_for('buildtype') + buildtype = self.environment.coredata.optstore.get_value_for('buildtype') + assert isinstance(buildtype, str), 'for mypy' if buildtype == 'plain': return 'none' elif buildtype == 'debug': @@ -1183,10 +1184,10 @@ def get_crt_val(self, crt_val: str, env: Environment) -> str: assert buildtype == 'custom' raise EnvironmentException('Requested C runtime based on buildtype, but buildtype is "custom".') - def get_crt_compile_args(self, crt_val: str, env: Environment) -> T.List[str]: + def get_crt_compile_args(self, crt_val: str) -> T.List[str]: raise EnvironmentException('This compiler does not support Windows CRT selection') - def get_crt_link_args(self, crt_val: str, env: Environment) -> T.List[str]: + def get_crt_link_args(self, crt_val: str) -> T.List[str]: raise EnvironmentException('This compiler does not support Windows CRT selection') def get_compile_only_args(self) -> T.List[str]: diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py index 485adddfc695..73a73331602c 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -725,17 +725,17 @@ def find_library(self, libname: str, extra_dirs: T.List[str], libtype: LibType = skip_link_check: bool = False) -> T.Optional[T.List[str]]: return self.host_compiler.find_library(libname, extra_dirs, libtype, lib_prefix_warning, ignore_system_dirs, skip_link_check) - def get_crt_compile_args(self, crt_val: str, env: Environment) -> T.List[str]: - return self._to_host_flags(self.host_compiler.get_crt_compile_args(crt_val, env)) + def get_crt_compile_args(self, crt_val: str) -> T.List[str]: + return self._to_host_flags(self.host_compiler.get_crt_compile_args(crt_val)) - def get_crt_link_args(self, crt_val: str, env: Environment) -> T.List[str]: + def get_crt_link_args(self, crt_val: str) -> T.List[str]: # nvcc defaults to static, release version of msvc runtime and provides no # native option to override it; override it with /NODEFAULTLIB host_link_arg_overrides = [] - host_crt_compile_args = self.host_compiler.get_crt_compile_args(crt_val, env) + host_crt_compile_args = self.host_compiler.get_crt_compile_args(crt_val) if any(arg in {'/MDd', '/MD', '/MTd'} for arg in host_crt_compile_args): host_link_arg_overrides += ['/NODEFAULTLIB:LIBCMT.lib'] - return self._to_host_flags(host_link_arg_overrides + self.host_compiler.get_crt_link_args(crt_val, env), Phase.LINKER) + return self._to_host_flags(host_link_arg_overrides + self.host_compiler.get_crt_link_args(crt_val), Phase.LINKER) def get_target_link_args(self, target: 'BuildTarget') -> T.List[str]: return self._to_host_flags(super().get_target_link_args(target), Phase.LINKER) diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py index 38997fb28ade..31c342303a55 100644 --- a/mesonbuild/compilers/d.py +++ b/mesonbuild/compilers/d.py @@ -371,10 +371,10 @@ def get_debug_args(self, is_debug: bool) -> T.List[str]: return clike_debug_args[is_debug] + ddebug_args - def _get_crt_args(self, crt_val: str, env: Environment) -> T.List[str]: + def _get_crt_args(self, crt_val: str) -> T.List[str]: if not self.info.is_windows(): return [] - return self.mscrt_args[self.get_crt_val(crt_val, env)] + return self.mscrt_args[self.get_crt_val(crt_val)] def get_soname_args(self, prefix: str, shlib_name: str, suffix: str, soversion: str, darwin_versions: T.Tuple[str, str]) -> T.List[str]: @@ -527,10 +527,10 @@ def _get_target_arch_args(self) -> T.List[str]: return ['-m32'] return [] - def get_crt_compile_args(self, crt_val: str, env: Environment) -> T.List[str]: + def get_crt_compile_args(self, crt_val: str) -> T.List[str]: return [] - def get_crt_link_args(self, crt_val: str, env: Environment) -> T.List[str]: + def get_crt_link_args(self, crt_val: str) -> T.List[str]: return [] def _get_compile_extra_args(self, extra_args: T.Union[T.List[str], T.Callable[[CompileCheckMode], T.List[str]], None] = None) -> T.List[str]: @@ -718,8 +718,8 @@ def get_warn_args(self, level: str) -> T.List[str]: def get_pic_args(self) -> T.List[str]: return ['-relocation-model=pic'] - def get_crt_link_args(self, crt_val: str, env: Environment) -> T.List[str]: - return self._get_crt_args(crt_val, env) + def get_crt_link_args(self, crt_val: str) -> T.List[str]: + return self._get_crt_args(crt_val) def unix_args_to_native(self, args: T.List[str]) -> T.List[str]: return self._unix_args_to_native(args, self.info, self.linker.id) @@ -803,8 +803,8 @@ def _get_target_arch_args(self) -> T.List[str]: return ['-m32'] return [] - def get_crt_compile_args(self, crt_val: str, env: Environment) -> T.List[str]: - return self._get_crt_args(crt_val, env) + def get_crt_compile_args(self, crt_val: str) -> T.List[str]: + return self._get_crt_args(crt_val) def unix_args_to_native(self, args: T.List[str]) -> T.List[str]: return self._unix_args_to_native(args, self.info, self.linker.id) diff --git a/mesonbuild/compilers/mixins/clang.py b/mesonbuild/compilers/mixins/clang.py index f52f4e1181ab..69d29b70f1bc 100644 --- a/mesonbuild/compilers/mixins/clang.py +++ b/mesonbuild/compilers/mixins/clang.py @@ -21,7 +21,6 @@ from ...options import MutableKeyedOptionDictType from ...dependencies import Dependency # noqa: F401 from ...build import BuildTarget - from ...environment import Environment from ..compilers import Compiler CompilerMixinBase = Compiler @@ -91,16 +90,16 @@ def __init__(self, defines: T.Optional[T.Dict[str, str]]): # All Clang backends can also do LLVM IR self.can_compile_suffixes.add('ll') - def get_crt_compile_args(self, crt_val: str, env: Environment) -> T.List[str]: + def get_crt_compile_args(self, crt_val: str) -> T.List[str]: if not isinstance(self.linker, VisualStudioLikeLinkerMixin): return [] - crt_val = self.get_crt_val(crt_val, env) + crt_val = self.get_crt_val(crt_val) return self.CRT_D_ARGS[crt_val] - def get_crt_link_args(self, crt_val: str, env: Environment) -> T.List[str]: + def get_crt_link_args(self, crt_val: str) -> T.List[str]: if not isinstance(self.linker, VisualStudioLikeLinkerMixin): return [] - crt_val = self.get_crt_val(crt_val, env) + crt_val = self.get_crt_val(crt_val) return self.CRT_ARGS[crt_val] def get_colorout_args(self, colortype: str) -> T.List[str]: diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index 9cbf64d5a4d7..e54ad7538162 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -333,8 +333,8 @@ def _get_basic_compiler_args(self, mode: CompileCheckMode) -> T.Tuple[T.List[str try: crt_val = self.environment.coredata.optstore.get_value_for('b_vscrt') assert isinstance(crt_val, str), 'for mypy' - cargs += self.get_crt_compile_args(crt_val, self.environment) - largs += self.get_crt_link_args(crt_val, self.environment) + cargs += self.get_crt_compile_args(crt_val) + largs += self.get_crt_link_args(crt_val) except (KeyError, AttributeError): pass @@ -1242,11 +1242,11 @@ def find_framework(self, name: str, extra_dirs: T.List[str], # TODO: should probably check for macOS? return self._find_framework_impl(name, extra_dirs, allow_system) - def get_crt_compile_args(self, crt_val: str, env: Environment) -> T.List[str]: + def get_crt_compile_args(self, crt_val: str) -> T.List[str]: # TODO: does this belong here or in GnuLike or maybe PosixLike? return [] - def get_crt_link_args(self, crt_val: str, env: Environment) -> T.List[str]: + def get_crt_link_args(self, crt_val: str) -> T.List[str]: # TODO: does this belong here or in GnuLike or maybe PosixLike? return [] diff --git a/mesonbuild/compilers/mixins/visualstudio.py b/mesonbuild/compilers/mixins/visualstudio.py index a809dbf62218..acf1bbc7bdc1 100644 --- a/mesonbuild/compilers/mixins/visualstudio.py +++ b/mesonbuild/compilers/mixins/visualstudio.py @@ -20,7 +20,6 @@ if T.TYPE_CHECKING: from ...build import BuildTarget - from ...environment import Environment from .clike import CLikeCompiler as Compiler else: # This is a bit clever, for mypy we pretend that these mixins descend from @@ -317,8 +316,8 @@ def get_default_include_dirs(self) -> T.List[str]: return [] return os.environ['INCLUDE'].split(os.pathsep) - def get_crt_compile_args(self, crt_val: str, env: Environment) -> T.List[str]: - crt_val = self.get_crt_val(crt_val, env) + def get_crt_compile_args(self, crt_val: str) -> T.List[str]: + crt_val = self.get_crt_val(crt_val) return self.crt_args[crt_val] def has_func_attribute(self, name: str) -> T.Tuple[bool, bool]: diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py index 919baca86db4..20b3cff1f37f 100644 --- a/mesonbuild/compilers/rust.py +++ b/mesonbuild/compilers/rust.py @@ -394,17 +394,17 @@ def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = args.append('--edition=' + std) return args - def get_crt_compile_args(self, crt_val: str, env: Environment) -> T.List[str]: + def get_crt_compile_args(self, crt_val: str) -> T.List[str]: # Rust handles this for us, we don't need to do anything return [] - def get_crt_link_args(self, crt_val: str, env: Environment) -> T.List[str]: + def get_crt_link_args(self, crt_val: str) -> T.List[str]: if not isinstance(self.linker, VisualStudioLikeLinkerMixin): return [] # Rustc always use non-debug Windows runtime. Inject the one selected # by Meson options instead. # https://github.com/rust-lang/rust/issues/39016 - return self.MSVCRT_ARGS[self.get_crt_val(crt_val, env)] + return self.MSVCRT_ARGS[self.get_crt_val(crt_val)] def get_colorout_args(self, colortype: str) -> T.List[str]: if colortype in {'always', 'never', 'auto'}: diff --git a/mesonbuild/dependencies/boost.py b/mesonbuild/dependencies/boost.py index 2a86c8264120..fe3fade03a2c 100644 --- a/mesonbuild/dependencies/boost.py +++ b/mesonbuild/dependencies/boost.py @@ -606,7 +606,7 @@ def filter_libraries(self, libs: T.List[BoostLibraryFile], lib_vers: str) -> T.L try: crt_val = self.env.coredata.optstore.get_value_for('b_vscrt') assert isinstance(crt_val, str) - vscrt = self.clib_compiler.get_crt_compile_args(crt_val, self.env)[0] + vscrt = self.clib_compiler.get_crt_compile_args(crt_val)[0] except (KeyError, IndexError, AttributeError): pass From c41b0cef3a82a10b1666bf3f660abc79c6d62260 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 11 Mar 2026 10:16:07 -0700 Subject: [PATCH 03/22] options: Move get_option_for_target to Options This leaves a wrapper in the coredata struct, which will allow us to have one big mechanical change in the next commit --- mesonbuild/coredata.py | 21 +-------------------- mesonbuild/options.py | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 5f84cb10a893..16cbea020f78 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -341,26 +341,7 @@ def init_backend_options(self, backend_name: str) -> None: '')) def get_option_for_target(self, target: 'BuildTarget', key: T.Union[str, OptionKey]) -> ElementaryOptionValues: - if isinstance(key, str): - assert ':' not in key - newkey = OptionKey(key, target.subproject) - else: - newkey = key - if newkey.subproject != target.subproject: - # FIXME: this should be an error. The caller needs to ensure that - # key and target have the same subproject for consistency. - # Now just do this to get things going. - newkey = newkey.evolve(subproject=target.subproject) - if self.is_cross_build(): - newkey = newkey.evolve(machine=target.for_machine) - option_object, value = self.optstore.get_option_and_value_for(newkey) - override = target.get_override(newkey.name) - if override is not None: - try: - return option_object.validate_value(override) - except MesonException as e: - raise MesonException(f'In override_options for {target}: {e!s}') - return value + return self.optstore.get_option_for_target(target, key) def set_from_configure_command(self, options: SharedCMDOptions) -> bool: return self.optstore.set_from_configure_command(options.cmd_line_options) diff --git a/mesonbuild/options.py b/mesonbuild/options.py index 8a831ad520f2..f7dd9647c503 100644 --- a/mesonbuild/options.py +++ b/mesonbuild/options.py @@ -35,6 +35,7 @@ if T.TYPE_CHECKING: from typing_extensions import Literal, Final, TypeAlias + from .build import BuildTarget from .envconfig import MachineInfo from .interpreterbase import SubProject from .compilers.compilers import Language @@ -883,6 +884,28 @@ def get_value_for(self, name: 'T.Union[OptionKey, str]', subproject: T.Optional[ _, resolved_value = self.get_option_and_value_for(key) return resolved_value + def get_option_for_target(self, target: 'BuildTarget', key: T.Union[str, OptionKey]) -> ElementaryOptionValues: + if isinstance(key, str): + assert ':' not in key + newkey = OptionKey(key, target.subproject) + else: + newkey = key + if newkey.subproject != target.subproject: + # FIXME: this should be an error. The caller needs to ensure that + # key and target have the same subproject for consistency. + # Now just do this to get things going. + newkey = newkey.evolve(subproject=target.subproject) + if self.is_cross: + newkey = newkey.evolve(machine=target.for_machine) + option_object, value = self.get_option_and_value_for(newkey) + override = target.get_override(newkey.name) + if override is not None: + try: + return option_object.validate_value(override) + except MesonException as e: + raise MesonException(f'In override_options for {target}: {e!s}') + return value + def add_system_option(self, key: T.Union[OptionKey, str], valobj: AnyOptionType) -> None: key = self.ensure_and_validate_key(key) if '.' in key.name: From 37d9e4fb7aaa4a17415893c1bfe70f6b7db6cd38 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 11 Mar 2026 10:18:25 -0700 Subject: [PATCH 04/22] Use the OptionStore version of get_option_for_target This is mostly generated through search and replace, but with the wrapper in CoreData removed manually --- mesonbuild/backend/backends.py | 2 +- mesonbuild/backend/ninjabackend.py | 2 +- mesonbuild/backend/vs2010backend.py | 2 +- mesonbuild/build.py | 12 +++---- mesonbuild/compilers/compilers.py | 36 ++++++++++---------- mesonbuild/compilers/cpp.py | 4 +-- mesonbuild/compilers/cuda.py | 2 +- mesonbuild/compilers/mixins/elbrus.py | 2 +- mesonbuild/compilers/objc.py | 2 +- mesonbuild/compilers/objcpp.py | 2 +- mesonbuild/compilers/rust.py | 2 +- mesonbuild/coredata.py | 6 +--- mesonbuild/interpreter/interpreterobjects.py | 2 +- 13 files changed, 36 insertions(+), 40 deletions(-) diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 7494b1ac19ba..1d7ab5b98107 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -2098,4 +2098,4 @@ def get_target_option(self, target: build.BuildTarget, name: T.Union[str, Option key = name else: raise MesonBugException('Internal error: invalid option type.') - return self.environment.coredata.get_option_for_target(target, key) + return self.environment.coredata.optstore.get_option_for_target(target, key) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index b45dbaa9b53a..63f794846214 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -3342,7 +3342,7 @@ def target_uses_import_std(self, target: build.BuildTarget) -> bool: if 'cpp' not in target.compilers: return False try: - if self.environment.coredata.get_option_for_target(target, 'cpp_importstd') == 'true': + if self.environment.coredata.optstore.get_option_for_target(target, 'cpp_importstd') == 'true': return True except KeyError: return False diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index 049b86a7074e..ce1937a9ea32 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -1386,7 +1386,7 @@ def add_non_makefile_vcxproj_elements( # Exception handling has to be set in the xml in addition to the "AdditionalOptions" because otherwise # cl will give warning D9025: overriding '/Ehs' with cpp_eh value if 'cpp' in target.compilers: - eh = self.environment.coredata.get_option_for_target(target, OptionKey('cpp_eh', machine=target.for_machine)) + eh = self.environment.coredata.optstore.get_option_for_target(target, OptionKey('cpp_eh', machine=target.for_machine)) if eh == 'a': ET.SubElement(clconf, 'ExceptionHandling').text = 'Async' elif eh == 's': diff --git a/mesonbuild/build.py b/mesonbuild/build.py index d688af892fee..471deb927b46 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -1051,7 +1051,7 @@ def process_compilers_late(self) -> None: # In the case of cython it's possible that we have an # implementation detail language - if self.uses_cython() and lang == self.environment.coredata.get_option_for_target(self, 'cython_language'): + if self.uses_cython() and lang == self.environment.coredata.optstore.get_option_for_target(self, 'cython_language'): self.compilers[lang] = self.environment.coredata.compilers[self.for_machine][lang] is_error = False @@ -1186,7 +1186,7 @@ def process_compilers(self) -> T.List[Language]: if 'vala' in self.compilers and 'c' not in self.compilers: self.compilers['c'] = self.all_compilers['c'] if 'cython' in self.compilers: - _value = self.environment.coredata.get_option_for_target(self, 'cython_language') + _value = self.environment.coredata.optstore.get_option_for_target(self, 'cython_language') assert isinstance(_value, str), 'for mypy' value = T.cast('Language', _value) try: @@ -1449,7 +1449,7 @@ def _extract_pic_pie(self, kwargs: T.Union[StaticLibraryKeywordArguments, Execut if kwargs.get(arg) is not None: return kwargs[arg] elif k in self.environment.coredata.optstore: - val = self.environment.coredata.get_option_for_target(self, k) + val = self.environment.coredata.optstore.get_option_for_target(self, k) assert isinstance(val, bool), 'for mypy' return val return False @@ -2384,7 +2384,7 @@ def post_init(self) -> None: self.outputs[0] = self.filename def determine_default_prefix_and_suffix(self) -> T.Tuple[str, str]: - scheme = self.environment.coredata.get_option_for_target(self, 'namingscheme') + scheme = self.environment.coredata.optstore.get_option_for_target(self, 'namingscheme') assert isinstance(scheme, str), 'for mypy' if scheme == 'platform': schemename = self.get_platform_scheme_name() @@ -2417,7 +2417,7 @@ def determine_default_prefix_and_suffix(self) -> T.Tuple[str, str]: suffix = 'a' if 'c' in self.compilers and self.compilers['c'].get_id() == 'tasking' and not self.prelink: key = OptionKey('b_lto', self.subproject, self.for_machine) - v = self.environment.coredata.get_option_for_target(self, key) + v = self.environment.coredata.optstore.get_option_for_target(self, key) assert isinstance(v, bool), 'for mypy' if v: suffix = 'ma' @@ -2567,7 +2567,7 @@ def get_default_install_dir(self) -> T.Tuple[str, str]: return self.environment.get_shared_lib_dir(), '{libdir_shared}' def determine_naming_info(self) -> T.Tuple[str, str, str, str, bool]: - scheme = self.environment.coredata.get_option_for_target(self, 'namingscheme') + scheme = self.environment.coredata.optstore.get_option_for_target(self, 'namingscheme') assert isinstance(scheme, str), 'for mypy' if scheme == 'platform': schemename = self.get_platform_scheme_name() diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 9c6aec5c96eb..63d4b9b3eca5 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -248,7 +248,7 @@ def option_enabled(boptions: T.Set[OptionKey], try: if option not in boptions: return False - ret = env.coredata.get_option_for_target(target, option) + ret = env.coredata.optstore.get_option_for_target(target, option) assert isinstance(ret, bool), 'must return bool' # could also be str return ret except KeyError: @@ -258,7 +258,7 @@ def option_enabled(boptions: T.Set[OptionKey], def get_option_value_for_target(env: 'Environment', target: 'BuildTarget', opt: OptionKey, fallback: '_T') -> '_T': """Get the value of an option, or the fallback value.""" try: - v = env.coredata.get_option_for_target(target, opt) + v = env.coredata.optstore.get_option_for_target(target, opt) except (KeyError, AttributeError): return fallback @@ -274,9 +274,9 @@ def are_asserts_disabled(target: 'BuildTarget', env: 'Environment') -> bool: :param env: the environment :return: whether to disable assertions or not """ - return (env.coredata.get_option_for_target(target, 'b_ndebug') == 'true' or - (env.coredata.get_option_for_target(target, 'b_ndebug') == 'if-release' and - env.coredata.get_option_for_target(target, 'buildtype') in {'release', 'plain'})) + return (env.coredata.optstore.get_option_for_target(target, 'b_ndebug') == 'true' or + (env.coredata.optstore.get_option_for_target(target, 'b_ndebug') == 'if-release' and + env.coredata.optstore.get_option_for_target(target, 'buildtype') in {'release', 'plain'})) def are_asserts_disabled_for_subproject(subproject: str, env: 'Environment') -> bool: @@ -290,7 +290,7 @@ def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Env args: T.List[str] = [] lto = False try: - if env.coredata.get_option_for_target(target, 'b_lto'): + if env.coredata.optstore.get_option_for_target(target, 'b_lto'): num_threads = get_option_value_for_target(env, target, OptionKey('b_lto_threads'), 0) ltomode = get_option_value_for_target(env, target, OptionKey('b_lto_mode'), 'default') args.extend(compiler.get_lto_compile_args( @@ -301,13 +301,13 @@ def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Env except (KeyError, AttributeError): pass try: - clrout = env.coredata.get_option_for_target(target, 'b_colorout') + clrout = env.coredata.optstore.get_option_for_target(target, 'b_colorout') assert isinstance(clrout, str) args += compiler.get_colorout_args(clrout) except KeyError: pass try: - sanitize = env.coredata.get_option_for_target(target, 'b_sanitize') + sanitize = env.coredata.optstore.get_option_for_target(target, 'b_sanitize') assert isinstance(sanitize, list) if sanitize == ['none']: sanitize = [] @@ -321,7 +321,7 @@ def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Env except KeyError: pass try: - pgo_val = env.coredata.get_option_for_target(target, 'b_pgo') + pgo_val = env.coredata.optstore.get_option_for_target(target, 'b_pgo') if pgo_val == 'generate': args.extend(compiler.get_profile_generate_args()) elif pgo_val == 'use': @@ -329,7 +329,7 @@ def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Env except (KeyError, AttributeError): pass try: - if env.coredata.get_option_for_target(target, 'b_coverage'): + if env.coredata.optstore.get_option_for_target(target, 'b_coverage'): args += compiler.get_coverage_args() except (KeyError, AttributeError): pass @@ -341,7 +341,7 @@ def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Env bitcode = option_enabled(compiler.base_options, target, env, 'b_bitcode') args.extend(compiler.get_embed_bitcode_args(bitcode, lto)) try: - crt_val = env.coredata.get_option_for_target(target, 'b_vscrt') + crt_val = env.coredata.optstore.get_option_for_target(target, 'b_vscrt') assert isinstance(crt_val, str) try: args += compiler.get_crt_compile_args(crt_val) @@ -357,8 +357,8 @@ def get_base_link_args(target: 'BuildTarget', args: T.List[str] = [] build_dir = env.get_build_dir() try: - if env.coredata.get_option_for_target(target, 'b_lto'): - if env.coredata.get_option_for_target(target, 'werror'): + if env.coredata.optstore.get_option_for_target(target, 'b_lto'): + if env.coredata.optstore.get_option_for_target(target, 'werror'): args.extend(linker.get_werror_args()) thinlto_cache_dir = None @@ -380,7 +380,7 @@ def get_base_link_args(target: 'BuildTarget', except (KeyError, AttributeError): pass try: - sanitizer = env.coredata.get_option_for_target(target, 'b_sanitize') + sanitizer = env.coredata.optstore.get_option_for_target(target, 'b_sanitize') assert isinstance(sanitizer, list) if sanitizer == ['none']: sanitizer = [] @@ -394,7 +394,7 @@ def get_base_link_args(target: 'BuildTarget', except KeyError: pass try: - pgo_val = env.coredata.get_option_for_target(target, 'b_pgo') + pgo_val = env.coredata.optstore.get_option_for_target(target, 'b_pgo') if pgo_val == 'generate': args.extend(linker.get_profile_generate_args()) elif pgo_val == 'use': @@ -402,7 +402,7 @@ def get_base_link_args(target: 'BuildTarget', except (KeyError, AttributeError): pass try: - if env.coredata.get_option_for_target(target, 'b_coverage'): + if env.coredata.optstore.get_option_for_target(target, 'b_coverage'): args += linker.get_coverage_link_args() except (KeyError, AttributeError): pass @@ -429,7 +429,7 @@ def get_base_link_args(target: 'BuildTarget', args.extend(linker.get_allow_undefined_link_args()) try: - crt_val = env.coredata.get_option_for_target(target, 'b_vscrt') + crt_val = env.coredata.optstore.get_option_for_target(target, 'b_vscrt') assert isinstance(crt_val, str) try: crtargs = linker.get_crt_link_args(crt_val) @@ -1606,7 +1606,7 @@ def get_compileropt_value(self, if isinstance(key, str): key = self.form_compileropt_key(key) if target: - return self.environment.coredata.get_option_for_target(target, key) + return self.environment.coredata.optstore.get_option_for_target(target, key) else: return self.environment.coredata.optstore.get_value_for(key.evolve(subproject=subproject)) diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 5d319f9939eb..3a7f2bf562a3 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -791,7 +791,7 @@ def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str # need a typeddict for this key = self.form_compileropt_key('winlibs').evolve(subproject=subproject) if target: - value = self.environment.coredata.get_option_for_target(target, key) + value = self.environment.coredata.optstore.get_option_for_target(target, key) else: value = self.environment.coredata.optstore.get_value_for(key) return T.cast('T.List[str]', value)[:] @@ -881,7 +881,7 @@ def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = # if one is using anything before that point, one cannot set the standard. stdkey = self.form_compileropt_key('std').evolve(subproject=subproject) if target is not None: - std = self.environment.coredata.get_option_for_target(target, stdkey) + std = self.environment.coredata.optstore.get_option_for_target(target, stdkey) else: std = self.environment.coredata.optstore.get_value_for(stdkey) if std in {'vc++11', 'c++11'}: diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py index 73a73331602c..3c905bd2601b 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -750,7 +750,7 @@ def _get_ccbin_args(self, target: 'T.Optional[BuildTarget]', subproject: T.Optional[str] = None) -> T.List[str]: key = self.form_compileropt_key('ccbindir').evolve(subproject=subproject) if target: - ccbindir = self.environment.coredata.get_option_for_target(target, key) + ccbindir = self.environment.coredata.optstore.get_option_for_target(target, key) else: ccbindir = self.environment.coredata.optstore.get_value_for(key) if isinstance(ccbindir, str) and ccbindir != '': diff --git a/mesonbuild/compilers/mixins/elbrus.py b/mesonbuild/compilers/mixins/elbrus.py index e020123891f0..6c0490720fe1 100644 --- a/mesonbuild/compilers/mixins/elbrus.py +++ b/mesonbuild/compilers/mixins/elbrus.py @@ -86,7 +86,7 @@ def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = args: T.List[str] = [] key = OptionKey(f'{self.language}_std', subproject=subproject, machine=self.for_machine) if target: - std = self.environment.coredata.get_option_for_target(target, key) + std = self.environment.coredata.optstore.get_option_for_target(target, key) else: std = self.environment.coredata.optstore.get_value_for(key) assert isinstance(std, str) diff --git a/mesonbuild/compilers/objc.py b/mesonbuild/compilers/objc.py index 7b196ccb9bb7..c6ae626ae96b 100644 --- a/mesonbuild/compilers/objc.py +++ b/mesonbuild/compilers/objc.py @@ -78,7 +78,7 @@ def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = args: T.List[str] = [] key = OptionKey('c_std', subproject=subproject, machine=self.for_machine) if target: - std = self.environment.coredata.get_option_for_target(target, key) + std = self.environment.coredata.optstore.get_option_for_target(target, key) else: std = self.environment.coredata.optstore.get_value_for(key) assert isinstance(std, str) diff --git a/mesonbuild/compilers/objcpp.py b/mesonbuild/compilers/objcpp.py index ad047d78626b..aa1ff6bc5771 100644 --- a/mesonbuild/compilers/objcpp.py +++ b/mesonbuild/compilers/objcpp.py @@ -82,7 +82,7 @@ def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = args: T.List[str] = [] key = OptionKey('cpp_std', subproject=subproject, machine=self.for_machine) if target: - std = self.environment.coredata.get_option_for_target(target, key) + std = self.environment.coredata.optstore.get_option_for_target(target, key) else: std = self.environment.coredata.optstore.get_value_for(key) assert isinstance(std, str) diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py index 20b3cff1f37f..7f0af3858a67 100644 --- a/mesonbuild/compilers/rust.py +++ b/mesonbuild/compilers/rust.py @@ -269,7 +269,7 @@ def get_nightly(self, target: T.Optional[BuildTarget]) -> bool: if not target: return self.allow_nightly key = self.form_compileropt_key('nightly') - nightly_opt = self.environment.coredata.get_option_for_target(target, key) + nightly_opt = self.environment.coredata.optstore.get_option_for_target(target, key) if nightly_opt == 'enabled' and not self.is_nightly: raise EnvironmentException(f'Rust compiler {self.name_string()} is not a nightly compiler as required by the "nightly" option.') return nightly_opt != 'disabled' and self.is_nightly diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 16cbea020f78..0aa0bd0071a8 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -31,8 +31,7 @@ from .mesonlib import FileOrString from .cmake.traceparser import CMakeCacheEntry from .interpreterbase import SubProject - from .options import ElementaryOptionValues, MutableKeyedOptionDictType - from .build import BuildTarget + from .options import MutableKeyedOptionDictType from .cmdline import SharedCMDOptions OptionDictType = T.Dict[str, options.AnyOptionType] @@ -340,9 +339,6 @@ def init_backend_options(self, backend_name: str) -> None: 'Default project to execute in Visual Studio', '')) - def get_option_for_target(self, target: 'BuildTarget', key: T.Union[str, OptionKey]) -> ElementaryOptionValues: - return self.optstore.get_option_for_target(target, key) - def set_from_configure_command(self, options: SharedCMDOptions) -> bool: return self.optstore.set_from_configure_command(options.cmd_line_options) diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py index 2399fba0f179..ca935cb2d9b4 100644 --- a/mesonbuild/interpreter/interpreterobjects.py +++ b/mesonbuild/interpreter/interpreterobjects.py @@ -1034,7 +1034,7 @@ def extract_objects_method(self, args: T.Tuple[T.List[T.Union[mesonlib.FileOrStr if self.subproject != self.held_object.subproject: raise InterpreterException('Tried to extract objects from a different subproject.') tobj = self._target_object - unity_value = self.interpreter.coredata.get_option_for_target(tobj, "unity") + unity_value = self.interpreter.coredata.optstore.get_option_for_target(tobj, "unity") is_unity = (unity_value == 'on' or (unity_value == 'subprojects' and tobj.subproject != '')) return tobj.extract_objects(args[0], is_unity) From 1926548c51406886bbb9fd406409bea98145f442 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 11 Mar 2026 10:25:46 -0700 Subject: [PATCH 05/22] coredata: use Language for get_language_args and _link_args --- mesonbuild/coredata.py | 4 ++-- mesonbuild/modules/gnome.py | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 0aa0bd0071a8..c8a05156e6b0 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -379,13 +379,13 @@ def get_nondefault_buildtype_args(self) -> T.List[T.Union[T.Tuple[str, str, str] result.append(('debug', actual_debug, debug)) return result - def get_external_args(self, for_machine: MachineChoice, lang: str) -> T.List[str]: + def get_external_args(self, for_machine: MachineChoice, lang: Language) -> T.List[str]: # mypy cannot analyze type of OptionKey key = OptionKey(f'{lang}_args', machine=for_machine) return T.cast('T.List[str]', self.optstore.get_value_for(key)) @lru_cache(maxsize=None) - def get_external_link_args(self, for_machine: MachineChoice, lang: str) -> T.List[str]: + def get_external_link_args(self, for_machine: MachineChoice, lang: Language) -> T.List[str]: # mypy cannot analyze type of OptionKey linkkey = OptionKey(f'{lang}_link_args', machine=for_machine) return T.cast('T.List[str]', self.optstore.get_value_for(linkkey)) diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index b4ac147f534b..def693473ef0 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -41,7 +41,7 @@ from . import ModuleState from ..build import BuildTarget - from ..compilers import Compiler + from ..compilers.compilers import Compiler, Language from ..interpreter import Interpreter from ..interpreterbase import TYPE_var, TYPE_kwargs from ..mesonlib import EnvironmentVariables, FileOrString @@ -836,7 +836,7 @@ def _scan_include(state: 'ModuleState', includes: T.List[T.Union[str, GirTarget] return ret, gir_inc_dirs, depends @staticmethod - def _scan_langs(state: 'ModuleState', langs: T.Iterable[str]) -> T.List[str]: + def _scan_langs(state: 'ModuleState', langs: T.Iterable[Language]) -> T.List[str]: ret: T.List[str] = [] for lang in langs: @@ -882,8 +882,8 @@ def _scan_gir_targets(state: 'ModuleState', girtargets: T.Sequence[build.BuildTa return ret @staticmethod - def _get_girtargets_langs_compilers(girtargets: T.Sequence[build.BuildTarget]) -> T.List[T.Tuple[str, 'Compiler']]: - ret: T.List[T.Tuple[str, 'Compiler']] = [] + def _get_girtargets_langs_compilers(girtargets: T.Sequence[build.BuildTarget]) -> T.List[T.Tuple[Language, 'Compiler']]: + ret: T.List[T.Tuple[Language, 'Compiler']] = [] for girtarget in girtargets: for lang, compiler in girtarget.compilers.items(): # XXX: Can you use g-i with any other language? @@ -910,7 +910,7 @@ def _get_gir_targets_inc_dirs(girtargets: T.Sequence[build.BuildTarget]) -> Orde return ret @staticmethod - def _get_langs_compilers_flags(state: 'ModuleState', langs_compilers: T.List[T.Tuple[str, 'Compiler']] + def _get_langs_compilers_flags(state: 'ModuleState', langs_compilers: T.List[T.Tuple[Language, 'Compiler']] ) -> T.Tuple[T.List[str], T.List[str], T.List[str]]: cflags: T.List[str] = [] internal_ldflags: T.List[str] = [] @@ -1094,7 +1094,7 @@ def _gather_typelib_includes_and_update_depends( return typelib_includes, new_depends @staticmethod - def _get_external_args_for_langs(state: 'ModuleState', langs: T.List[str]) -> T.List[str]: + def _get_external_args_for_langs(state: 'ModuleState', langs: T.List[Language]) -> T.List[str]: ret: T.List[str] = [] for lang in langs: ret += mesonlib.listify(state.environment.coredata.get_external_args(MachineChoice.HOST, lang)) From aeaf31c611c4df593e29e0b9816f90cdf7acfe13 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 11 Mar 2026 10:27:16 -0700 Subject: [PATCH 06/22] options: move get_external_args and _link_args to Options Leaves a wrapper in place that will be removed later --- mesonbuild/coredata.py | 10 ++-------- mesonbuild/options.py | 12 ++++++++++++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index c8a05156e6b0..14a6535daeae 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -9,7 +9,6 @@ from . import mlog, options import pickle, os, uuid import sys -from functools import lru_cache from collections import OrderedDict import textwrap @@ -380,15 +379,10 @@ def get_nondefault_buildtype_args(self) -> T.List[T.Union[T.Tuple[str, str, str] return result def get_external_args(self, for_machine: MachineChoice, lang: Language) -> T.List[str]: - # mypy cannot analyze type of OptionKey - key = OptionKey(f'{lang}_args', machine=for_machine) - return T.cast('T.List[str]', self.optstore.get_value_for(key)) + return self.optstore.get_external_args(for_machine, lang) - @lru_cache(maxsize=None) def get_external_link_args(self, for_machine: MachineChoice, lang: Language) -> T.List[str]: - # mypy cannot analyze type of OptionKey - linkkey = OptionKey(f'{lang}_link_args', machine=for_machine) - return T.cast('T.List[str]', self.optstore.get_value_for(linkkey)) + return self.optstore.get_external_link_args(for_machine, lang) def is_cross_build(self, when_building_for: MachineChoice = MachineChoice.HOST) -> bool: if when_building_for == MachineChoice.BUILD: diff --git a/mesonbuild/options.py b/mesonbuild/options.py index f7dd9647c503..a96aa9514ac8 100644 --- a/mesonbuild/options.py +++ b/mesonbuild/options.py @@ -4,6 +4,7 @@ from __future__ import annotations from collections import OrderedDict +from functools import lru_cache from itertools import chain import copy import dataclasses @@ -906,6 +907,17 @@ def get_option_for_target(self, target: 'BuildTarget', key: T.Union[str, OptionK raise MesonException(f'In override_options for {target}: {e!s}') return value + def get_external_args(self, for_machine: MachineChoice, lang: Language) -> T.List[str]: + # mypy cannot analyze type of OptionKey + key = OptionKey(f'{lang}_args', machine=for_machine) + return T.cast('T.List[str]', self.get_value_for(key)) + + @lru_cache(maxsize=None) + def get_external_link_args(self, for_machine: MachineChoice, lang: Language) -> T.List[str]: + # mypy cannot analyze type of OptionKey + linkkey = OptionKey(f'{lang}_link_args', machine=for_machine) + return T.cast('T.List[str]', self.get_value_for(linkkey)) + def add_system_option(self, key: T.Union[OptionKey, str], valobj: AnyOptionType) -> None: key = self.ensure_and_validate_key(key) if '.' in key.name: From fd1280c2b52eb4fda784535cbad7c63c0929a4d4 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 11 Mar 2026 10:28:19 -0700 Subject: [PATCH 07/22] Use OptionStore.get_external_args --- mesonbuild/backend/backends.py | 2 +- mesonbuild/cargo/interpreter.py | 2 +- mesonbuild/compilers/compilers.py | 2 +- mesonbuild/compilers/fortran.py | 2 +- mesonbuild/compilers/mixins/clike.py | 4 ++-- mesonbuild/compilers/vala.py | 4 ++-- mesonbuild/coredata.py | 3 --- mesonbuild/modules/external_project.py | 2 +- mesonbuild/modules/gnome.py | 4 ++-- 9 files changed, 11 insertions(+), 14 deletions(-) diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 1d7ab5b98107..d0ff3929489b 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -967,7 +967,7 @@ def generate_basic_compiler_args(self, target: build.BuildTarget, compiler: 'Com # Compile args added from the env: CFLAGS/CXXFLAGS, etc, or the cross # file. We want these to override all the defaults, but not the # per-target compile args. - commands += self.environment.coredata.get_external_args(target.for_machine, compiler.get_language()) + commands += self.environment.coredata.optstore.get_external_args(target.for_machine, compiler.get_language()) # Using both /Z7 or /ZI and /Zi at the same times produces a compiler warning. # We do not add /Z7 or /ZI by default. If it is being used it is because the user has explicitly enabled it. # /Zi needs to be removed in that case to avoid cl's warning to that effect (D9025 : overriding '/Zi' with '/ZI') diff --git a/mesonbuild/cargo/interpreter.py b/mesonbuild/cargo/interpreter.py index 6ffae639bf14..b9e86d4ca435 100644 --- a/mesonbuild/cargo/interpreter.py +++ b/mesonbuild/cargo/interpreter.py @@ -671,7 +671,7 @@ def _get_cfgs(self, machine: MachineChoice) -> T.Dict[str, str]: machine = MachineChoice.HOST rustc = T.cast('RustCompiler', self.environment.coredata.compilers[machine]['rust']) cfgs = rustc.get_cfgs().copy() - rustflags = self.environment.coredata.get_external_args(machine, 'rust') + rustflags = self.environment.coredata.optstore.get_external_args(machine, 'rust') rustflags_i = iter(rustflags) for i in rustflags_i: if i == '--cfg': diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 63d4b9b3eca5..cbb062a9c475 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1508,7 +1508,7 @@ def build_wrapper_args(self, if mode is CompileCheckMode.COMPILE: # Add DFLAGS from the env - args += self.environment.coredata.get_external_args(self.for_machine, self.language) + args += self.environment.coredata.optstore.get_external_args(self.for_machine, self.language) elif mode is CompileCheckMode.LINK: # Add LDFLAGS from the env args += self.environment.coredata.get_external_link_args(self.for_machine, self.language) diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py index d468bd547bb7..b65085c63995 100644 --- a/mesonbuild/compilers/fortran.py +++ b/mesonbuild/compilers/fortran.py @@ -56,7 +56,7 @@ def has_function(self, funcname: str, prefix: str, *, 'that example is to see if the compiler has Fortran 2008 Block element.') def _get_basic_compiler_args(self, mode: CompileCheckMode) -> T.Tuple[T.List[str], T.List[str]]: - cargs = self.environment.coredata.get_external_args(self.for_machine, self.language) + cargs = self.environment.coredata.optstore.get_external_args(self.for_machine, self.language) largs = self.environment.coredata.get_external_link_args(self.for_machine, self.language) return cargs, largs diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index e54ad7538162..4c07185bc83e 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -339,7 +339,7 @@ def _get_basic_compiler_args(self, mode: CompileCheckMode) -> T.Tuple[T.List[str pass # Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS and CPPFLAGS from the env - sys_args = self.environment.coredata.get_external_args(self.for_machine, self.language) + sys_args = self.environment.coredata.optstore.get_external_args(self.for_machine, self.language) if isinstance(sys_args, str): sys_args = [sys_args] # Apparently it is a thing to inject linker flags both @@ -1192,7 +1192,7 @@ def find_framework_paths(self) -> T.List[str]: commands = self.get_exelist(ccache=False) + ['-v', '-E', '-'] commands += self.get_always_args() # Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS from the env - commands += self.environment.coredata.get_external_args(self.for_machine, self.language) + commands += self.environment.coredata.optstore.get_external_args(self.for_machine, self.language) mlog.debug('Finding framework path by running: ', ' '.join(commands), '\n') os_env = os.environ.copy() os_env['LC_ALL'] = 'C' diff --git a/mesonbuild/compilers/vala.py b/mesonbuild/compilers/vala.py index be5c1b0b44a5..235c0b2a7fd8 100644 --- a/mesonbuild/compilers/vala.py +++ b/mesonbuild/compilers/vala.py @@ -153,7 +153,7 @@ def find_library(self, libname: str, extra_dirs: T.List[str], libtype: LibType = if not extra_dirs: code = 'class MesonFindLibrary : Object { }' args: T.List[str] = [] - args += self.environment.coredata.get_external_args(self.for_machine, self.language) + args += self.environment.coredata.optstore.get_external_args(self.for_machine, self.language) vapi_args = ['--pkg', libname] args += vapi_args with self.cached_compile(code, extra_args=args, mode=CompileCheckMode.COMPILE) as p: @@ -212,7 +212,7 @@ def build_wrapper_args(self, if mode is CompileCheckMode.COMPILE: # Add DFLAGS from the env - args += self.environment.coredata.get_external_args(self.for_machine, self.language) + args += self.environment.coredata.optstore.get_external_args(self.for_machine, self.language) elif mode is CompileCheckMode.LINK: # Add LDFLAGS from the env args += self.environment.coredata.get_external_link_args(self.for_machine, self.language) diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 14a6535daeae..c47f3dd278a9 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -378,9 +378,6 @@ def get_nondefault_buildtype_args(self) -> T.List[T.Union[T.Tuple[str, str, str] result.append(('debug', actual_debug, debug)) return result - def get_external_args(self, for_machine: MachineChoice, lang: Language) -> T.List[str]: - return self.optstore.get_external_args(for_machine, lang) - def get_external_link_args(self, for_machine: MachineChoice, lang: Language) -> T.List[str]: return self.optstore.get_external_link_args(for_machine, lang) diff --git a/mesonbuild/modules/external_project.py b/mesonbuild/modules/external_project.py index e8d48ceea0a3..1cc9c0cae7eb 100644 --- a/mesonbuild/modules/external_project.py +++ b/mesonbuild/modules/external_project.py @@ -156,7 +156,7 @@ def _configure(self, state: 'ModuleState') -> None: for lang, compiler in self.env.coredata.compilers[MachineChoice.HOST].items(): if any(lang not in i for i in (ENV_VAR_PROG_MAP, CFLAGS_MAPPING)): continue - cargs = self.env.coredata.get_external_args(MachineChoice.HOST, lang) + cargs = self.env.coredata.optstore.get_external_args(MachineChoice.HOST, lang) assert isinstance(cargs, list), 'for mypy' self.run_env[ENV_VAR_PROG_MAP[lang][0]] = self._quote_and_join(compiler.get_exelist()) self.run_env[CFLAGS_MAPPING[lang]] = self._quote_and_join(cargs) diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index def693473ef0..a51cb3db4277 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -1097,7 +1097,7 @@ def _gather_typelib_includes_and_update_depends( def _get_external_args_for_langs(state: 'ModuleState', langs: T.List[Language]) -> T.List[str]: ret: T.List[str] = [] for lang in langs: - ret += mesonlib.listify(state.environment.coredata.get_external_args(MachineChoice.HOST, lang)) + ret += mesonlib.listify(state.environment.coredata.optstore.get_external_args(MachineChoice.HOST, lang)) return ret @staticmethod @@ -1599,7 +1599,7 @@ def _get_build_args(self, c_args: T.List[str], inc_dirs: T.List[T.Union[str, bui ldflags.extend(internal_ldflags) ldflags.extend(external_ldflags) - cflags.extend(state.environment.coredata.get_external_args(MachineChoice.HOST, 'c')) + cflags.extend(state.environment.coredata.optstore.get_external_args(MachineChoice.HOST, 'c')) ldflags.extend(state.environment.coredata.get_external_link_args(MachineChoice.HOST, 'c')) compiler = state.environment.coredata.compilers[MachineChoice.HOST]['c'] From a8178ac91945d04c35e68b9a39dcbd4043de59ac Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 11 Mar 2026 10:29:46 -0700 Subject: [PATCH 08/22] Use OptionStore.get_external_link_args --- mesonbuild/build.py | 2 +- mesonbuild/compilers/compilers.py | 4 ++-- mesonbuild/compilers/fortran.py | 2 +- mesonbuild/compilers/mixins/clike.py | 2 +- mesonbuild/compilers/swift.py | 2 +- mesonbuild/compilers/vala.py | 2 +- mesonbuild/coredata.py | 3 --- mesonbuild/linkers/detect.py | 4 ++-- mesonbuild/modules/external_project.py | 2 +- mesonbuild/modules/gnome.py | 6 +++--- unittests/allplatformstests.py | 4 ++-- 11 files changed, 15 insertions(+), 18 deletions(-) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 471deb927b46..628a3a153cd9 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -1942,7 +1942,7 @@ def get_external_rpath_dirs(self) -> T.Set[str]: args: T.List[str] = [] for lang in LANGUAGES_USING_LDFLAGS: try: - args += self.environment.coredata.get_external_link_args(self.for_machine, lang) + args += self.environment.coredata.optstore.get_external_link_args(self.for_machine, lang) except KeyError: pass return self.get_rpath_dirs_from_link_args(args) diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index cbb062a9c475..995bf4593c2c 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1123,7 +1123,7 @@ def get_build_link_args(self, target: BuildTarget, build: build.Build) -> T.List # override all the defaults but not the per-target link args. return build.get_project_link_args(self, target) \ + build.get_global_link_args(self, self.for_machine) \ - + self.environment.coredata.get_external_link_args(self.for_machine, self.get_language()) + + self.environment.coredata.optstore.get_external_link_args(self.for_machine, self.get_language()) def get_target_link_args(self, target: 'BuildTarget') -> T.List[str]: return target.link_args @@ -1511,7 +1511,7 @@ def build_wrapper_args(self, args += self.environment.coredata.optstore.get_external_args(self.for_machine, self.language) elif mode is CompileCheckMode.LINK: # Add LDFLAGS from the env - args += self.environment.coredata.get_external_link_args(self.for_machine, self.language) + args += self.environment.coredata.optstore.get_external_link_args(self.for_machine, self.language) # extra_args must override all other arguments, so we add them last args += extra_args return args diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py index b65085c63995..24d4a6c03a2e 100644 --- a/mesonbuild/compilers/fortran.py +++ b/mesonbuild/compilers/fortran.py @@ -57,7 +57,7 @@ def has_function(self, funcname: str, prefix: str, *, def _get_basic_compiler_args(self, mode: CompileCheckMode) -> T.Tuple[T.List[str], T.List[str]]: cargs = self.environment.coredata.optstore.get_external_args(self.for_machine, self.language) - largs = self.environment.coredata.get_external_link_args(self.for_machine, self.language) + largs = self.environment.coredata.optstore.get_external_link_args(self.for_machine, self.language) return cargs, largs def _sanity_check_source_code(self) -> str: diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index 4c07185bc83e..bfce8f47b62b 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -355,7 +355,7 @@ def _get_basic_compiler_args(self, mode: CompileCheckMode) -> T.Tuple[T.List[str largs += self.use_linker_args(ld_value[0], self.version) # Add LDFLAGS from the env - sys_ld_args = self.environment.coredata.get_external_link_args(self.for_machine, self.language) + sys_ld_args = self.environment.coredata.optstore.get_external_link_args(self.for_machine, self.language) # CFLAGS and CXXFLAGS go to both linking and compiling, but we want them # to only appear on the command line once. Remove dupes. largs += [x for x in sys_ld_args if x not in cleaned_sys_args] diff --git a/mesonbuild/compilers/swift.py b/mesonbuild/compilers/swift.py index feaa009e0cd1..6bc90ffd41e4 100644 --- a/mesonbuild/compilers/swift.py +++ b/mesonbuild/compilers/swift.py @@ -184,7 +184,7 @@ def _sanity_check_compile_args(self, sourcename: str, binname: str if self.is_cross: args.extend(self.get_compile_only_args()) else: - largs.extend(self.environment.coredata.get_external_link_args(self.for_machine, self.language)) + largs.extend(self.environment.coredata.optstore.get_external_link_args(self.for_machine, self.language)) args.extend(self.get_output_args(binname)) args.append(sourcename) diff --git a/mesonbuild/compilers/vala.py b/mesonbuild/compilers/vala.py index 235c0b2a7fd8..f2c14f46940e 100644 --- a/mesonbuild/compilers/vala.py +++ b/mesonbuild/compilers/vala.py @@ -215,7 +215,7 @@ def build_wrapper_args(self, args += self.environment.coredata.optstore.get_external_args(self.for_machine, self.language) elif mode is CompileCheckMode.LINK: # Add LDFLAGS from the env - args += self.environment.coredata.get_external_link_args(self.for_machine, self.language) + args += self.environment.coredata.optstore.get_external_link_args(self.for_machine, self.language) # extra_args must override all other arguments, so we add them last args += extra_args return args diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index c47f3dd278a9..0194ca800de0 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -378,9 +378,6 @@ def get_nondefault_buildtype_args(self) -> T.List[T.Union[T.Tuple[str, str, str] result.append(('debug', actual_debug, debug)) return result - def get_external_link_args(self, for_machine: MachineChoice, lang: Language) -> T.List[str]: - return self.optstore.get_external_link_args(for_machine, lang) - def is_cross_build(self, when_building_for: MachineChoice = MachineChoice.HOST) -> bool: if when_building_for == MachineChoice.BUILD: return False diff --git a/mesonbuild/linkers/detect.py b/mesonbuild/linkers/detect.py index cf6803a19418..10c7695d384d 100644 --- a/mesonbuild/linkers/detect.py +++ b/mesonbuild/linkers/detect.py @@ -55,7 +55,7 @@ def guess_win_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty else: # list check_args = comp_class.LINKER_PREFIX + ['/logo'] + comp_class.LINKER_PREFIX + ['--version'] - check_args += env.coredata.get_external_link_args(for_machine, comp_class.language) + check_args += env.coredata.optstore.get_external_link_args(for_machine, comp_class.language) override: T.List[str] = [] value = env.lookup_binary_entry(for_machine, comp_class.language + '_ld') @@ -130,7 +130,7 @@ def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty extra_args = extra_args or [] system = env.machines[for_machine].system - ldflags = env.coredata.get_external_link_args(for_machine, comp_class.language) + ldflags = env.coredata.optstore.get_external_link_args(for_machine, comp_class.language) extra_args += comp_class._unix_args_to_native(ldflags, env.machines[for_machine]) if isinstance(comp_class.LINKER_PREFIX, str): diff --git a/mesonbuild/modules/external_project.py b/mesonbuild/modules/external_project.py index 1cc9c0cae7eb..ed6ead5ae650 100644 --- a/mesonbuild/modules/external_project.py +++ b/mesonbuild/modules/external_project.py @@ -162,7 +162,7 @@ def _configure(self, state: 'ModuleState') -> None: self.run_env[CFLAGS_MAPPING[lang]] = self._quote_and_join(cargs) if not link_exelist: link_exelist = compiler.get_linker_exelist() - _l = self.env.coredata.get_external_link_args(MachineChoice.HOST, lang) + _l = self.env.coredata.optstore.get_external_link_args(MachineChoice.HOST, lang) assert isinstance(_l, list), 'for mypy' link_args = _l if link_exelist: diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index a51cb3db4277..36386c9ccdc9 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -840,7 +840,7 @@ def _scan_langs(state: 'ModuleState', langs: T.Iterable[Language]) -> T.List[str ret: T.List[str] = [] for lang in langs: - link_args = state.environment.coredata.get_external_link_args(MachineChoice.HOST, lang) + link_args = state.environment.coredata.optstore.get_external_link_args(MachineChoice.HOST, lang) for link_arg in link_args: if link_arg.startswith('-L'): ret.append(link_arg) @@ -1186,7 +1186,7 @@ def generate_gir(self, state: 'ModuleState', args: T.Tuple[T.List[T.Union[Execut scan_cflags += list(self._get_scanner_cflags(self._get_external_args_for_langs(state, [lc[0] for lc in langs_compilers]))) scan_internal_ldflags = [] scan_external_ldflags = [] - scan_env_ldflags = state.environment.coredata.get_external_link_args(MachineChoice.HOST, 'c') + scan_env_ldflags = state.environment.coredata.optstore.get_external_link_args(MachineChoice.HOST, 'c') for cli_flags, env_flags in (self._get_scanner_ldflags(internal_ldflags), self._get_scanner_ldflags(dep_internal_ldflags)): scan_internal_ldflags += cli_flags scan_env_ldflags += env_flags @@ -1600,7 +1600,7 @@ def _get_build_args(self, c_args: T.List[str], inc_dirs: T.List[T.Union[str, bui ldflags.extend(external_ldflags) cflags.extend(state.environment.coredata.optstore.get_external_args(MachineChoice.HOST, 'c')) - ldflags.extend(state.environment.coredata.get_external_link_args(MachineChoice.HOST, 'c')) + ldflags.extend(state.environment.coredata.optstore.get_external_link_args(MachineChoice.HOST, 'c')) compiler = state.environment.coredata.compilers[MachineChoice.HOST]['c'] compiler_flags = self._get_langs_compilers_flags(state, [('c', compiler)]) diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py index 8026d9d95562..6cd197041139 100644 --- a/unittests/allplatformstests.py +++ b/unittests/allplatformstests.py @@ -4806,10 +4806,10 @@ def test_env_flags_to_linker(self) -> None: # C does have a separate linking step. It can be done through the compiler # driver or not; act accordingly. if cc.USED_FOR_SEPARATE_LINKING_STEP: - link_args = env.coredata.get_external_link_args(cc.for_machine, cc.language) + link_args = env.coredata.optstore.get_external_link_args(cc.for_machine, cc.language) self.assertEqual(sorted(link_args), sorted(['-DCFLAG', '-flto'])) else: - link_args = env.coredata.get_external_link_args(cc.for_machine, cc.language) + link_args = env.coredata.optstore.get_external_link_args(cc.for_machine, cc.language) self.assertEqual(sorted(link_args), sorted(['-flto'])) def test_install_tag(self) -> None: From ca3a11c19446ae4fc1a69b3fcfc9653096ce18d0 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 11 Mar 2026 10:34:59 -0700 Subject: [PATCH 09/22] options: Rename option getters to _untyped These provide unconstrained ElementryOptionValues variants. The next patches will provide typed versions using the normal name, that do automatic type validation --- mesonbuild/ast/introspection.py | 2 +- mesonbuild/backend/backends.py | 10 +- mesonbuild/backend/ninjabackend.py | 20 +-- mesonbuild/backend/vs2010backend.py | 24 +-- mesonbuild/backend/xcodebackend.py | 4 +- mesonbuild/build.py | 26 ++-- mesonbuild/cmake/common.py | 8 +- mesonbuild/cmake/executor.py | 2 +- mesonbuild/cmake/interpreter.py | 6 +- mesonbuild/compilers/asm.py | 2 +- mesonbuild/compilers/compilers.py | 46 +++--- mesonbuild/compilers/cpp.py | 8 +- mesonbuild/compilers/cuda.py | 4 +- mesonbuild/compilers/detect.py | 2 +- mesonbuild/compilers/mixins/clike.py | 2 +- mesonbuild/compilers/mixins/elbrus.py | 4 +- mesonbuild/compilers/mixins/emscripten.py | 2 +- mesonbuild/compilers/mixins/gnu.py | 2 +- mesonbuild/compilers/objc.py | 4 +- mesonbuild/compilers/objcpp.py | 4 +- mesonbuild/compilers/rust.py | 2 +- mesonbuild/coredata.py | 12 +- mesonbuild/dependencies/base.py | 2 +- mesonbuild/dependencies/boost.py | 4 +- mesonbuild/dependencies/dub.py | 2 +- mesonbuild/dependencies/misc.py | 2 +- mesonbuild/dependencies/mpi.py | 2 +- mesonbuild/dependencies/pkgconfig.py | 4 +- mesonbuild/dependencies/python.py | 6 +- mesonbuild/dependencies/qt.py | 6 +- mesonbuild/dependencies/scalapack.py | 2 +- mesonbuild/environment.py | 14 +- mesonbuild/interpreter/compiler.py | 2 +- mesonbuild/interpreter/dependencyfallbacks.py | 4 +- mesonbuild/interpreter/interpreter.py | 26 ++-- mesonbuild/interpreter/interpreterobjects.py | 2 +- mesonbuild/interpreter/mesonmain.py | 4 +- mesonbuild/linkers/detect.py | 2 +- mesonbuild/mcompile.py | 4 +- mesonbuild/mdevenv.py | 6 +- mesonbuild/mdist.py | 2 +- mesonbuild/minit.py | 2 +- mesonbuild/minstall.py | 4 +- mesonbuild/mintro.py | 2 +- mesonbuild/modules/__init__.py | 2 +- mesonbuild/modules/cmake.py | 6 +- mesonbuild/modules/external_project.py | 8 +- mesonbuild/modules/gnome.py | 10 +- mesonbuild/modules/hotdoc.py | 2 +- mesonbuild/modules/i18n.py | 2 +- mesonbuild/modules/pkgconfig.py | 10 +- mesonbuild/modules/python.py | 12 +- mesonbuild/modules/rust.py | 2 +- mesonbuild/msetup.py | 4 +- mesonbuild/mtest.py | 4 +- mesonbuild/munstable_coredata.py | 2 +- mesonbuild/options.py | 18 +-- mesonbuild/scripts/regen_checker.py | 2 +- unittests/allplatformstests.py | 60 ++++---- unittests/datatests.py | 6 +- unittests/linuxliketests.py | 2 +- unittests/optiontests.py | 144 +++++++++--------- 62 files changed, 298 insertions(+), 298 deletions(-) diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py index 3d2211677056..c6066476eb31 100644 --- a/mesonbuild/ast/introspection.py +++ b/mesonbuild/ast/introspection.py @@ -283,7 +283,7 @@ def build_target(self, node: BaseNode, args: T.List[TYPE_var], kwargs_raw: T.Dic return new_target def build_library(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> T.Union[IntrospectionBuildTarget, UnknownValue]: - default_library = self.coredata.optstore.get_value_for(OptionKey('default_library', subproject=self.subproject)) + default_library = self.coredata.optstore.get_value_for_untyped(OptionKey('default_library', subproject=self.subproject)) if default_library == 'shared': return self.build_target(node, args, kwargs, SharedLibrary) elif default_library == 'static': diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index d0ff3929489b..65ad6ca913d9 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -379,7 +379,7 @@ def get_target_dir(self, target: build.AnyTargetType) -> str: if isinstance(target, build.RunTarget): # this produces no output, only a dummy top-level name dirname = '' - elif self.environment.coredata.optstore.get_value_for(OptionKey('layout')) == 'mirror': + elif self.environment.coredata.optstore.get_value_for_untyped(OptionKey('layout')) == 'mirror': dirname = target.get_builddir() else: dirname = 'meson-out' @@ -1298,7 +1298,7 @@ def construct_target_rel_paths(self, t: build.AnyTargetType, workdir: T.Optional def generate_depmf_install(self, d: InstallData) -> None: depmf_path = self.build.dep_manifest_name if depmf_path is None: - option_dir = self.environment.coredata.optstore.get_value_for(OptionKey('licensedir')) + option_dir = self.environment.coredata.optstore.get_value_for_untyped(OptionKey('licensedir')) assert isinstance(option_dir, str), 'for mypy' if option_dir: depmf_path = os.path.join(option_dir, 'depmf.json') @@ -1649,7 +1649,7 @@ def create_install_data(self) -> InstallData: # TODO go through all candidates, like others strip_bin = [detect.defaults['strip'][0]] - umask = self.environment.coredata.optstore.get_value_for(OptionKey('install_umask')) + umask = self.environment.coredata.optstore.get_value_for_untyped(OptionKey('install_umask')) assert isinstance(umask, (str, int)), 'for mypy' d = InstallData(self.environment.get_source_dir(), @@ -1681,7 +1681,7 @@ def guess_install_tag(self, fname: str, outdir: T.Optional[str] = None) -> T.Opt bindir = Path(prefix, self.environment.get_bindir()) libdir = Path(prefix, self.environment.get_libdir()) incdir = Path(prefix, self.environment.get_includedir()) - _ldir = self.environment.coredata.optstore.get_value_for(OptionKey('localedir')) + _ldir = self.environment.coredata.optstore.get_value_for_untyped(OptionKey('localedir')) assert isinstance(_ldir, str), 'for mypy' localedir = Path(prefix, _ldir) dest_path = Path(prefix, outdir, Path(fname).name) if outdir else Path(prefix, fname) @@ -2098,4 +2098,4 @@ def get_target_option(self, target: build.BuildTarget, name: T.Union[str, Option key = name else: raise MesonBugException('Internal error: invalid option type.') - return self.environment.coredata.optstore.get_option_for_target(target, key) + return self.environment.coredata.optstore.get_option_for_target_untyped(target, key) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 63f794846214..aa95625c3bc0 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -612,7 +612,7 @@ def generate(self, capture: bool = False, vslite_ctx: T.Optional[T.Dict] = None) self.allow_thin_archives[for_machine] = False ninja = tooldetect.detect_ninja_command_and_version(log=True) - if self.environment.coredata.optstore.get_value_for(OptionKey('vsenv')): + if self.environment.coredata.optstore.get_value_for_untyped(OptionKey('vsenv')): builddir = Path(self.environment.get_build_dir()) try: # For prettier printing, reduce to a relative path. If @@ -637,7 +637,7 @@ def generate(self, capture: bool = False, vslite_ctx: T.Optional[T.Dict] = None) outfile.write('# Do not edit by hand.\n\n') outfile.write('ninja_required_version = 1.8.2\n\n') - num_pools = self.environment.coredata.optstore.get_value_for('backend_max_links') + num_pools = self.environment.coredata.optstore.get_value_for_untyped('backend_max_links') if num_pools > 0: outfile.write(f'''pool link_pool depth = {num_pools} @@ -671,7 +671,7 @@ def generate(self, capture: bool = False, vslite_ctx: T.Optional[T.Dict] = None) mlog.log_timestamp("Dist generated") key = OptionKey('b_coverage') if key in self.environment.coredata.optstore and\ - self.environment.coredata.optstore.get_value_for('b_coverage'): + self.environment.coredata.optstore.get_value_for_untyped('b_coverage'): gcovr_exe, gcovr_version, lcov_exe, lcov_version, genhtml_exe, llvm_cov_exe = tooldetect.find_coverage_tools(self.environment.coredata) mlog.debug(f'Using {gcovr_exe} ({gcovr_version}), {lcov_exe} and {llvm_cov_exe} for code coverage') if gcovr_exe or (lcov_exe and genhtml_exe): @@ -1375,9 +1375,9 @@ def generate_install(self) -> None: def generate_tests(self) -> None: self.serialize_tests() cmd = self.environment.get_build_command(True) + ['test', '--no-rebuild'] - if not self.environment.coredata.optstore.get_value_for(OptionKey('stdsplit')): + if not self.environment.coredata.optstore.get_value_for_untyped(OptionKey('stdsplit')): cmd += ['--no-stdsplit'] - if self.environment.coredata.optstore.get_value_for(OptionKey('errorlogs')): + if self.environment.coredata.optstore.get_value_for_untyped(OptionKey('errorlogs')): cmd += ['--print-errorlogs'] elem = self.create_phony_target('test', 'CUSTOM_COMMAND', ['all', 'meson-test-prereq', 'PHONY']) elem.add_item('COMMAND', cmd) @@ -2438,7 +2438,7 @@ def _rsp_options(self, tool: T.Union['Compiler', 'StaticLinker', 'DynamicLinker' return options def generate_static_link_rules(self) -> None: - num_pools = self.environment.coredata.optstore.get_value_for('backend_max_links') + num_pools = self.environment.coredata.optstore.get_value_for_untyped('backend_max_links') if 'java' in self.environment.coredata.compilers.host: self.generate_java_link() for for_machine in MachineChoice: @@ -2486,7 +2486,7 @@ def generate_static_link_rules(self) -> None: self.add_rule(NinjaRule(rule, cmdlist, args, description, **options, extra=pool)) def generate_dynamic_link_rules(self) -> None: - num_pools = self.environment.coredata.optstore.get_value_for('backend_max_links') + num_pools = self.environment.coredata.optstore.get_value_for_untyped('backend_max_links') for for_machine in MachineChoice: complist = self.environment.coredata.compilers[for_machine] for langname, compiler in complist.items(): @@ -3342,7 +3342,7 @@ def target_uses_import_std(self, target: build.BuildTarget) -> bool: if 'cpp' not in target.compilers: return False try: - if self.environment.coredata.optstore.get_option_for_target(target, 'cpp_importstd') == 'true': + if self.environment.coredata.optstore.get_option_for_target_untyped(target, 'cpp_importstd') == 'true': return True except KeyError: return False @@ -4012,7 +4012,7 @@ def generate_clangtool(self, name: str, extra_arg: T.Optional[str] = None, need_ if extra_arg: target_name += f'-{extra_arg}' extra_args.append(f'--{extra_arg}') - colorout = self.environment.coredata.optstore.get_value_for('b_colorout') \ + colorout = self.environment.coredata.optstore.get_value_for_untyped('b_colorout') \ if OptionKey('b_colorout') in self.environment.coredata.optstore else 'always' assert isinstance(colorout, str), 'for mypy' extra_args.extend(['--color', colorout]) @@ -4121,7 +4121,7 @@ def generate_ending(self) -> None: elem.add_dep(self.generate_custom_target_clean(ctlist)) if OptionKey('b_coverage') in self.environment.coredata.optstore and \ - self.environment.coredata.optstore.get_value_for('b_coverage'): + self.environment.coredata.optstore.get_value_for_untyped('b_coverage'): self.generate_gcov_clean() elem.add_dep('clean-gcda') elem.add_dep('clean-gcno') diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index ce1937a9ea32..71e9b43b42a0 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -275,11 +275,11 @@ def generate(self, else: raise MesonException('Unsupported Visual Studio platform: ' + build_machine) - self.buildtype = self.environment.coredata.optstore.get_value_for(OptionKey('buildtype')) - self.optimization = self.environment.coredata.optstore.get_value_for(OptionKey('optimization')) - self.debug = self.environment.coredata.optstore.get_value_for(OptionKey('debug')) + self.buildtype = self.environment.coredata.optstore.get_value_for_untyped(OptionKey('buildtype')) + self.optimization = self.environment.coredata.optstore.get_value_for_untyped(OptionKey('optimization')) + self.debug = self.environment.coredata.optstore.get_value_for_untyped(OptionKey('debug')) try: - self.sanitize = self.environment.coredata.optstore.get_value_for(OptionKey('b_sanitize')) + self.sanitize = self.environment.coredata.optstore.get_value_for_untyped(OptionKey('b_sanitize')) except KeyError: self.sanitize = [] sln_filename = os.path.join(self.environment.get_build_dir(), self.build.project_name + '.sln') @@ -428,7 +428,7 @@ def generate_solution(self, sln_filename: str, projlist: T.List[Project]) -> Non ofile.write('# Visual Studio %s\n' % self.sln_version_comment) prj_templ = 'Project("{%s}") = "%s", "%s", "{%s}"\n' for prj in projlist: - if self.environment.coredata.optstore.get_value_for(OptionKey('layout')) == 'mirror': + if self.environment.coredata.optstore.get_value_for_untyped(OptionKey('layout')) == 'mirror': self.generate_solution_dirs(ofile, prj[1].parents) target = self.build.targets[prj[0]] lang = 'default' @@ -540,7 +540,7 @@ def generate_solution(self, sln_filename: str, projlist: T.List[Project]) -> Non replace_if_different(sln_filename, sln_filename_tmp) def generate_projects(self, vslite_ctx: dict = None) -> T.List[Project]: - startup_project = self.environment.coredata.optstore.get_value_for('backend_startup_project') + startup_project = self.environment.coredata.optstore.get_value_for_untyped('backend_startup_project') projlist: T.List[Project] = [] startup_idx = 0 for (i, (name, target)) in enumerate(self.build.targets.items()): @@ -1386,7 +1386,7 @@ def add_non_makefile_vcxproj_elements( # Exception handling has to be set in the xml in addition to the "AdditionalOptions" because otherwise # cl will give warning D9025: overriding '/Ehs' with cpp_eh value if 'cpp' in target.compilers: - eh = self.environment.coredata.optstore.get_option_for_target(target, OptionKey('cpp_eh', machine=target.for_machine)) + eh = self.environment.coredata.optstore.get_option_for_target_untyped(target, OptionKey('cpp_eh', machine=target.for_machine)) if eh == 'a': ET.SubElement(clconf, 'ExceptionHandling').text = 'Async' elif eh == 's': @@ -1848,7 +1848,7 @@ def path_normalize_add(path, lis): # build system as possible. self.add_target_deps(root, target) self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname) - if self.environment.coredata.optstore.get_value_for(OptionKey('layout')) == 'mirror': + if self.environment.coredata.optstore.get_value_for_untyped(OptionKey('layout')) == 'mirror': self.gen_vcxproj_filters(target, ofname) return True @@ -2017,9 +2017,9 @@ def gen_testproj(self): meson_build_dir_for_buildtype = build_dir_tail[:-2] + buildtype # Get the buildtype suffixed 'builddir_[debug/release/etc]' from 'builddir_vs', for example. proj_to_build_dir_for_buildtype = str(os.path.join(proj_to_multiconfigured_builds_parent_dir, meson_build_dir_for_buildtype)) test_cmd = f'{nmake_base_meson_command} test -C "{proj_to_build_dir_for_buildtype}" --no-rebuild' - if not self.environment.coredata.optstore.get_value_for(OptionKey('stdsplit')): + if not self.environment.coredata.optstore.get_value_for_untyped(OptionKey('stdsplit')): test_cmd += ' --no-stdsplit' - if self.environment.coredata.optstore.get_value_for(OptionKey('errorlogs')): + if self.environment.coredata.optstore.get_value_for_untyped(OptionKey('errorlogs')): test_cmd += ' --print-errorlogs' condition = f'\'$(Configuration)|$(Platform)\'==\'{buildtype}|{self.platform}\'' prop_group = ET.SubElement(root, 'PropertyGroup', Condition=condition) @@ -2041,9 +2041,9 @@ def gen_testproj(self): ET.SubElement(midl, 'ProxyFileName').text = '%(Filename)_p.c' # FIXME: No benchmarks? test_command = self.environment.get_build_command() + ['test', '--no-rebuild'] - if not self.environment.coredata.optstore.get_value_for(OptionKey('stdsplit')): + if not self.environment.coredata.optstore.get_value_for_untyped(OptionKey('stdsplit')): test_command += ['--no-stdsplit'] - if self.environment.coredata.optstore.get_value_for(OptionKey('errorlogs')): + if self.environment.coredata.optstore.get_value_for_untyped(OptionKey('errorlogs')): test_command += ['--print-errorlogs'] self.serialize_tests() self.add_custom_build(root, 'run_tests', '"%s"' % ('" "'.join(test_command))) diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py index dae1f9b99011..21178fb1babf 100644 --- a/mesonbuild/backend/xcodebackend.py +++ b/mesonbuild/backend/xcodebackend.py @@ -239,7 +239,7 @@ class XCodeBackend(backends.Backend): def __init__(self, build: T.Optional[build.Build]): super().__init__(build) self.project_uid = self.environment.coredata.lang_guids['default'].replace('-', '')[:24] - self.buildtype = T.cast('str', self.environment.coredata.optstore.get_value_for(OptionKey('buildtype'))) + self.buildtype = T.cast('str', self.environment.coredata.optstore.get_value_for_untyped(OptionKey('buildtype'))) self.project_conflist = self.gen_id() self.maingroup_id = self.gen_id() self.all_id = self.gen_id() @@ -281,7 +281,7 @@ def gen_id(self) -> str: @functools.lru_cache(maxsize=None) def get_target_dir(self, target: build.AnyTargetType) -> str: - dirname = os.path.join(target.get_subdir(), T.cast('str', self.environment.coredata.optstore.get_value_for(OptionKey('buildtype')))) + dirname = os.path.join(target.get_subdir(), T.cast('str', self.environment.coredata.optstore.get_value_for_untyped(OptionKey('buildtype')))) #os.makedirs(os.path.join(self.environment.get_build_dir(), dirname), exist_ok=True) return dirname diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 628a3a153cd9..3f3345fe471e 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -1051,7 +1051,7 @@ def process_compilers_late(self) -> None: # In the case of cython it's possible that we have an # implementation detail language - if self.uses_cython() and lang == self.environment.coredata.optstore.get_option_for_target(self, 'cython_language'): + if self.uses_cython() and lang == self.environment.coredata.optstore.get_option_for_target_untyped(self, 'cython_language'): self.compilers[lang] = self.environment.coredata.compilers[self.for_machine][lang] is_error = False @@ -1186,7 +1186,7 @@ def process_compilers(self) -> T.List[Language]: if 'vala' in self.compilers and 'c' not in self.compilers: self.compilers['c'] = self.all_compilers['c'] if 'cython' in self.compilers: - _value = self.environment.coredata.optstore.get_option_for_target(self, 'cython_language') + _value = self.environment.coredata.optstore.get_option_for_target_untyped(self, 'cython_language') assert isinstance(_value, str), 'for mypy' value = T.cast('Language', _value) try: @@ -1449,7 +1449,7 @@ def _extract_pic_pie(self, kwargs: T.Union[StaticLibraryKeywordArguments, Execut if kwargs.get(arg) is not None: return kwargs[arg] elif k in self.environment.coredata.optstore: - val = self.environment.coredata.optstore.get_option_for_target(self, k) + val = self.environment.coredata.optstore.get_option_for_target_untyped(self, k) assert isinstance(val, bool), 'for mypy' return val return False @@ -1851,7 +1851,7 @@ def process_vs_module_defs_kw(self, kwargs: ExecutableKeywordArguments) -> None: self.process_link_depends([path]) def extract_targets_as_list(self, kwargs: BuildTargetKeywordArguments, key: T.Literal['link_with', 'link_whole']) -> T.List[LibTypes]: - bl_type = self.environment.coredata.optstore.get_value_for(OptionKey('default_both_libraries')) + bl_type = self.environment.coredata.optstore.get_value_for_untyped(OptionKey('default_both_libraries')) if bl_type == 'auto': if isinstance(self, StaticLibrary): bl_type = 'static' @@ -1874,7 +1874,7 @@ def get(self, lib_type: T.Literal['static', 'shared']) -> LibTypes: def determine_rpath_dirs(self) -> T.Tuple[str, ...]: result: OrderedSet[str] - if self.environment.coredata.optstore.get_value_for(OptionKey('layout')) == 'mirror': + if self.environment.coredata.optstore.get_value_for_untyped(OptionKey('layout')) == 'mirror': # Need a copy here result = OrderedSet(self.get_link_dep_subdirs()) else: @@ -2281,7 +2281,7 @@ def post_init(self) -> None: machine.is_windows() and ('cs' in self.compilers or self.uses_rust() or self.get_using_msvc()) # .pdb file is created only when debug symbols are enabled - and self.environment.coredata.optstore.get_value_for(OptionKey("debug")) + and self.environment.coredata.optstore.get_value_for_untyped(OptionKey("debug")) ) if create_debug_file: # If the target is has a standard exe extension (i.e. 'foo.exe'), @@ -2384,7 +2384,7 @@ def post_init(self) -> None: self.outputs[0] = self.filename def determine_default_prefix_and_suffix(self) -> T.Tuple[str, str]: - scheme = self.environment.coredata.optstore.get_option_for_target(self, 'namingscheme') + scheme = self.environment.coredata.optstore.get_option_for_target_untyped(self, 'namingscheme') assert isinstance(scheme, str), 'for mypy' if scheme == 'platform': schemename = self.get_platform_scheme_name() @@ -2411,13 +2411,13 @@ def determine_default_prefix_and_suffix(self) -> T.Tuple[str, str]: suffix = 'rlib' elif self.rust_crate_type == 'staticlib': suffix = 'a' - elif self.environment.machines[self.for_machine].is_os2() and self.environment.coredata.optstore.get_value_for(OptionKey('os2_emxomf')): + elif self.environment.machines[self.for_machine].is_os2() and self.environment.coredata.optstore.get_value_for_untyped(OptionKey('os2_emxomf')): suffix = 'lib' else: suffix = 'a' if 'c' in self.compilers and self.compilers['c'].get_id() == 'tasking' and not self.prelink: key = OptionKey('b_lto', self.subproject, self.for_machine) - v = self.environment.coredata.optstore.get_option_for_target(self, key) + v = self.environment.coredata.optstore.get_option_for_target_untyped(self, key) assert isinstance(v, bool), 'for mypy' if v: suffix = 'ma' @@ -2567,7 +2567,7 @@ def get_default_install_dir(self) -> T.Tuple[str, str]: return self.environment.get_shared_lib_dir(), '{libdir_shared}' def determine_naming_info(self) -> T.Tuple[str, str, str, str, bool]: - scheme = self.environment.coredata.optstore.get_option_for_target(self, 'namingscheme') + scheme = self.environment.coredata.optstore.get_option_for_target_untyped(self, 'namingscheme') assert isinstance(scheme, str), 'for mypy' if scheme == 'platform': schemename = self.get_platform_scheme_name() @@ -2599,7 +2599,7 @@ def determine_naming_info(self) -> T.Tuple[str, str, str, str, bool]: # Import library is called foo.dll.lib import_filename_tpl = '{0.prefix}{0.name}.dll.lib' # .pdb file is only created when debug symbols are enabled - create_debug_file = self.environment.coredata.optstore.get_value_for(OptionKey("debug")) + create_debug_file = self.environment.coredata.optstore.get_value_for_untyped(OptionKey("debug")) elif self.get_using_msvc(): # Shared library is of the form foo.dll prefix = prefix if prefix is not None else '' @@ -2607,7 +2607,7 @@ def determine_naming_info(self) -> T.Tuple[str, str, str, str, bool]: import_suffix = import_suffix if import_suffix is not None else 'lib' import_filename_tpl = '{0.prefix}{0.name}.' + import_suffix # .pdb file is only created when debug symbols are enabled - create_debug_file = self.environment.coredata.optstore.get_value_for(OptionKey("debug")) + create_debug_file = self.environment.coredata.optstore.get_value_for_untyped(OptionKey("debug")) # Assume GCC-compatible naming else: # Shared library is of the form libfoo.dll @@ -2654,7 +2654,7 @@ def determine_naming_info(self) -> T.Tuple[str, str, str, str, bool]: suffix = suffix if suffix is not None else 'dll' # Import library is called foo_dll.a or foo_dll.lib if import_suffix is None: - import_suffix = '_dll.lib' if self.environment.coredata.optstore.get_value_for(OptionKey('os2_emxomf')) else '_dll.a' + import_suffix = '_dll.lib' if self.environment.coredata.optstore.get_value_for_untyped(OptionKey('os2_emxomf')) else '_dll.a' import_filename_tpl = '{0.prefix}{0.name}' + import_suffix filename_tpl = '{0.shortname}' if self.shortname else '{0.prefix}{0.name}' if self.soversion: diff --git a/mesonbuild/cmake/common.py b/mesonbuild/cmake/common.py index 3fd20a31972d..f945c9999338 100644 --- a/mesonbuild/cmake/common.py +++ b/mesonbuild/cmake/common.py @@ -56,13 +56,13 @@ def cmake_is_debug(env: 'Environment') -> bool: if 'b_vscrt' in env.coredata.optstore: - is_debug = env.coredata.optstore.get_value_for('buildtype') == 'debug' - if env.coredata.optstore.get_value_for('b_vscrt') in {'mdd', 'mtd'}: + is_debug = env.coredata.optstore.get_value_for_untyped('buildtype') == 'debug' + if env.coredata.optstore.get_value_for_untyped('b_vscrt') in {'mdd', 'mtd'}: is_debug = True return is_debug else: # Don't directly assign to is_debug to make mypy happy - debug_opt = env.coredata.optstore.get_value_for('debug') + debug_opt = env.coredata.optstore.get_value_for_untyped('debug') assert isinstance(debug_opt, bool) return debug_opt @@ -108,7 +108,7 @@ def _flags_to_list(raw: str) -> T.List[str]: return res def cmake_get_generator_args(env: 'Environment') -> T.List[str]: - backend_name = env.coredata.optstore.get_value_for(OptionKey('backend')) + backend_name = env.coredata.optstore.get_value_for_untyped(OptionKey('backend')) assert isinstance(backend_name, str) assert backend_name in backend_generator_map return ['-G', backend_generator_map[backend_name]] diff --git a/mesonbuild/cmake/executor.py b/mesonbuild/cmake/executor.py index a174bc7eb6de..849dfb261b6c 100644 --- a/mesonbuild/cmake/executor.py +++ b/mesonbuild/cmake/executor.py @@ -52,7 +52,7 @@ def __init__(self, environment: 'Environment', version: str, for_machine: Machin self.cmakebin = None return - prefpath = self.environment.coredata.optstore.get_value_for( + prefpath = self.environment.coredata.optstore.get_value_for_untyped( OptionKey(name='cmake_prefix_path', machine=for_machine)) assert isinstance(prefpath, list) self.prefix_paths = prefpath diff --git a/mesonbuild/cmake/interpreter.py b/mesonbuild/cmake/interpreter.py index f369d7b38c6f..6a189c793a05 100644 --- a/mesonbuild/cmake/interpreter.py +++ b/mesonbuild/cmake/interpreter.py @@ -801,7 +801,7 @@ def __init__(self, subdir: Path, env: 'Environment', backend: 'Backend'): self.src_dir = Path(env.get_source_dir(), subdir) self.build_dir_rel = subdir / '__CMake_build' self.build_dir = Path(env.get_build_dir()) / self.build_dir_rel - self.install_prefix = Path(T.cast('str', env.coredata.optstore.get_value_for(OptionKey('prefix')))) + self.install_prefix = Path(T.cast('str', env.coredata.optstore.get_value_for_untyped(OptionKey('prefix')))) self.env = env self.for_machine = MachineChoice.HOST # TODO make parameter self.backend_name = backend.name @@ -851,12 +851,12 @@ def configure(self, extra_cmake_options: T.List[str]) -> CMakeExecutor: cmake_args = [] cmake_args += cmake_get_generator_args(self.env) cmake_args += [f'-DCMAKE_INSTALL_PREFIX={self.install_prefix}'] - libdir = self.env.coredata.optstore.get_value_for(OptionKey('libdir')) + libdir = self.env.coredata.optstore.get_value_for_untyped(OptionKey('libdir')) cmake_args += [f'-DCMAKE_INSTALL_LIBDIR={libdir}'] cmake_args += extra_cmake_options if not any(arg.startswith('-DCMAKE_BUILD_TYPE=') for arg in cmake_args): # Our build type is favored over any CMAKE_BUILD_TYPE environment variable - buildtype = T.cast('str', self.env.coredata.optstore.get_value_for(OptionKey('buildtype'))) + buildtype = T.cast('str', self.env.coredata.optstore.get_value_for_untyped(OptionKey('buildtype'))) if buildtype in BUILDTYPE_MAP: cmake_args += [f'-DCMAKE_BUILD_TYPE={BUILDTYPE_MAP[buildtype]}'] trace_args = self.trace.trace_args() diff --git a/mesonbuild/compilers/asm.py b/mesonbuild/compilers/asm.py index 6902652e8509..7460826044f5 100644 --- a/mesonbuild/compilers/asm.py +++ b/mesonbuild/compilers/asm.py @@ -91,7 +91,7 @@ def get_always_args(self) -> T.List[str]: define = 'MACHO' elif self.info.is_os2(): cpu = '' - if self.environment.coredata.optstore.get_value_for(OptionKey('os2_emxomf')): + if self.environment.coredata.optstore.get_value_for_untyped(OptionKey('os2_emxomf')): plat = 'obj2' define = 'OBJ2' else: diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 995bf4593c2c..47d5d0021c10 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -248,7 +248,7 @@ def option_enabled(boptions: T.Set[OptionKey], try: if option not in boptions: return False - ret = env.coredata.optstore.get_option_for_target(target, option) + ret = env.coredata.optstore.get_option_for_target_untyped(target, option) assert isinstance(ret, bool), 'must return bool' # could also be str return ret except KeyError: @@ -258,7 +258,7 @@ def option_enabled(boptions: T.Set[OptionKey], def get_option_value_for_target(env: 'Environment', target: 'BuildTarget', opt: OptionKey, fallback: '_T') -> '_T': """Get the value of an option, or the fallback value.""" try: - v = env.coredata.optstore.get_option_for_target(target, opt) + v = env.coredata.optstore.get_option_for_target_untyped(target, opt) except (KeyError, AttributeError): return fallback @@ -274,23 +274,23 @@ def are_asserts_disabled(target: 'BuildTarget', env: 'Environment') -> bool: :param env: the environment :return: whether to disable assertions or not """ - return (env.coredata.optstore.get_option_for_target(target, 'b_ndebug') == 'true' or - (env.coredata.optstore.get_option_for_target(target, 'b_ndebug') == 'if-release' and - env.coredata.optstore.get_option_for_target(target, 'buildtype') in {'release', 'plain'})) + return (env.coredata.optstore.get_option_for_target_untyped(target, 'b_ndebug') == 'true' or + (env.coredata.optstore.get_option_for_target_untyped(target, 'b_ndebug') == 'if-release' and + env.coredata.optstore.get_option_for_target_untyped(target, 'buildtype') in {'release', 'plain'})) def are_asserts_disabled_for_subproject(subproject: str, env: 'Environment') -> bool: key = OptionKey('b_ndebug', subproject) - return (env.coredata.optstore.get_value_for(key) == 'true' or - (env.coredata.optstore.get_value_for(key) == 'if-release' and - env.coredata.optstore.get_value_for(key.evolve(name='buildtype')) in {'release', 'plain'})) + return (env.coredata.optstore.get_value_for_untyped(key) == 'true' or + (env.coredata.optstore.get_value_for_untyped(key) == 'if-release' and + env.coredata.optstore.get_value_for_untyped(key.evolve(name='buildtype')) in {'release', 'plain'})) def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Environment') -> T.List[str]: args: T.List[str] = [] lto = False try: - if env.coredata.optstore.get_option_for_target(target, 'b_lto'): + if env.coredata.optstore.get_option_for_target_untyped(target, 'b_lto'): num_threads = get_option_value_for_target(env, target, OptionKey('b_lto_threads'), 0) ltomode = get_option_value_for_target(env, target, OptionKey('b_lto_mode'), 'default') args.extend(compiler.get_lto_compile_args( @@ -301,13 +301,13 @@ def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Env except (KeyError, AttributeError): pass try: - clrout = env.coredata.optstore.get_option_for_target(target, 'b_colorout') + clrout = env.coredata.optstore.get_option_for_target_untyped(target, 'b_colorout') assert isinstance(clrout, str) args += compiler.get_colorout_args(clrout) except KeyError: pass try: - sanitize = env.coredata.optstore.get_option_for_target(target, 'b_sanitize') + sanitize = env.coredata.optstore.get_option_for_target_untyped(target, 'b_sanitize') assert isinstance(sanitize, list) if sanitize == ['none']: sanitize = [] @@ -321,7 +321,7 @@ def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Env except KeyError: pass try: - pgo_val = env.coredata.optstore.get_option_for_target(target, 'b_pgo') + pgo_val = env.coredata.optstore.get_option_for_target_untyped(target, 'b_pgo') if pgo_val == 'generate': args.extend(compiler.get_profile_generate_args()) elif pgo_val == 'use': @@ -329,7 +329,7 @@ def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Env except (KeyError, AttributeError): pass try: - if env.coredata.optstore.get_option_for_target(target, 'b_coverage'): + if env.coredata.optstore.get_option_for_target_untyped(target, 'b_coverage'): args += compiler.get_coverage_args() except (KeyError, AttributeError): pass @@ -341,7 +341,7 @@ def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Env bitcode = option_enabled(compiler.base_options, target, env, 'b_bitcode') args.extend(compiler.get_embed_bitcode_args(bitcode, lto)) try: - crt_val = env.coredata.optstore.get_option_for_target(target, 'b_vscrt') + crt_val = env.coredata.optstore.get_option_for_target_untyped(target, 'b_vscrt') assert isinstance(crt_val, str) try: args += compiler.get_crt_compile_args(crt_val) @@ -357,8 +357,8 @@ def get_base_link_args(target: 'BuildTarget', args: T.List[str] = [] build_dir = env.get_build_dir() try: - if env.coredata.optstore.get_option_for_target(target, 'b_lto'): - if env.coredata.optstore.get_option_for_target(target, 'werror'): + if env.coredata.optstore.get_option_for_target_untyped(target, 'b_lto'): + if env.coredata.optstore.get_option_for_target_untyped(target, 'werror'): args.extend(linker.get_werror_args()) thinlto_cache_dir = None @@ -380,7 +380,7 @@ def get_base_link_args(target: 'BuildTarget', except (KeyError, AttributeError): pass try: - sanitizer = env.coredata.optstore.get_option_for_target(target, 'b_sanitize') + sanitizer = env.coredata.optstore.get_option_for_target_untyped(target, 'b_sanitize') assert isinstance(sanitizer, list) if sanitizer == ['none']: sanitizer = [] @@ -394,7 +394,7 @@ def get_base_link_args(target: 'BuildTarget', except KeyError: pass try: - pgo_val = env.coredata.optstore.get_option_for_target(target, 'b_pgo') + pgo_val = env.coredata.optstore.get_option_for_target_untyped(target, 'b_pgo') if pgo_val == 'generate': args.extend(linker.get_profile_generate_args()) elif pgo_val == 'use': @@ -402,7 +402,7 @@ def get_base_link_args(target: 'BuildTarget', except (KeyError, AttributeError): pass try: - if env.coredata.optstore.get_option_for_target(target, 'b_coverage'): + if env.coredata.optstore.get_option_for_target_untyped(target, 'b_coverage'): args += linker.get_coverage_link_args() except (KeyError, AttributeError): pass @@ -429,7 +429,7 @@ def get_base_link_args(target: 'BuildTarget', args.extend(linker.get_allow_undefined_link_args()) try: - crt_val = env.coredata.optstore.get_option_for_target(target, 'b_vscrt') + crt_val = env.coredata.optstore.get_option_for_target_untyped(target, 'b_vscrt') assert isinstance(crt_val, str) try: crtargs = linker.get_crt_link_args(crt_val) @@ -1172,7 +1172,7 @@ def get_crt_val(self, crt_val: str) -> str: rel = 'mt' # Match what build type flags used to do. - buildtype = self.environment.coredata.optstore.get_value_for('buildtype') + buildtype = env.coredata.optstore.get_value_for_untyped('buildtype') assert isinstance(buildtype, str), 'for mypy' if buildtype == 'plain': return 'none' @@ -1606,9 +1606,9 @@ def get_compileropt_value(self, if isinstance(key, str): key = self.form_compileropt_key(key) if target: - return self.environment.coredata.optstore.get_option_for_target(target, key) + return self.environment.coredata.optstore.get_option_for_target_untyped(target, key) else: - return self.environment.coredata.optstore.get_value_for(key.evolve(subproject=subproject)) + return self.environment.coredata.optstore.get_value_for_untyped(key.evolve(subproject=subproject)) def _update_language_stds(self, opts: MutableKeyedOptionDictType, value: T.List[str]) -> None: key = self.form_compileropt_key('std') diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 3a7f2bf562a3..c7386325488d 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -791,9 +791,9 @@ def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str # need a typeddict for this key = self.form_compileropt_key('winlibs').evolve(subproject=subproject) if target: - value = self.environment.coredata.optstore.get_option_for_target(target, key) + value = self.environment.coredata.optstore.get_option_for_target_untyped(target, key) else: - value = self.environment.coredata.optstore.get_value_for(key) + value = self.environment.coredata.optstore.get_value_for_untyped(key) return T.cast('T.List[str]', value)[:] def _get_options_impl(self, opts: 'MutableKeyedOptionDictType', cpp_stds: T.List[str]) -> 'MutableKeyedOptionDictType': @@ -881,9 +881,9 @@ def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = # if one is using anything before that point, one cannot set the standard. stdkey = self.form_compileropt_key('std').evolve(subproject=subproject) if target is not None: - std = self.environment.coredata.optstore.get_option_for_target(target, stdkey) + std = self.environment.coredata.optstore.get_option_for_target_untyped(target, stdkey) else: - std = self.environment.coredata.optstore.get_value_for(stdkey) + std = self.environment.coredata.optstore.get_value_for_untyped(stdkey) if std in {'vc++11', 'c++11'}: mlog.warning(self.id, 'does not support C++11;', 'attempting best effort; setting the standard to C++14', diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py index 3c905bd2601b..ba5ccbbe283c 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -750,9 +750,9 @@ def _get_ccbin_args(self, target: 'T.Optional[BuildTarget]', subproject: T.Optional[str] = None) -> T.List[str]: key = self.form_compileropt_key('ccbindir').evolve(subproject=subproject) if target: - ccbindir = self.environment.coredata.optstore.get_option_for_target(target, key) + ccbindir = self.environment.coredata.optstore.get_option_for_target_untyped(target, key) else: - ccbindir = self.environment.coredata.optstore.get_value_for(key) + ccbindir = self.environment.coredata.optstore.get_value_for_untyped(key) if isinstance(ccbindir, str) and ccbindir != '': return [self._shield_nvcc_list_arg('-ccbin='+ccbindir, False)] else: diff --git a/mesonbuild/compilers/detect.py b/mesonbuild/compilers/detect.py index bc2bc90565aa..3704e4fffd4a 100644 --- a/mesonbuild/compilers/detect.py +++ b/mesonbuild/compilers/detect.py @@ -172,7 +172,7 @@ def detect_static_linker(env: 'Environment', compiler: Compiler) -> StaticLinker trials = [defaults['cuda_static_linker']] + default_linkers elif compiler.get_argument_syntax() == 'msvc': trials = [defaults['vs_static_linker'], defaults['clang_cl_static_linker']] - elif env.machines[compiler.for_machine].is_os2() and env.coredata.optstore.get_value_for(OptionKey('os2_emxomf')): + elif env.machines[compiler.for_machine].is_os2() and env.coredata.optstore.get_value_for_untyped(OptionKey('os2_emxomf')): trials = [defaults['emxomf_static_linker']] + default_linkers elif compiler.id == 'gcc': # Use gcc-ar if available; needed for LTO diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index bfce8f47b62b..01e84463ce47 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -331,7 +331,7 @@ def _get_basic_compiler_args(self, mode: CompileCheckMode) -> T.Tuple[T.List[str # linking with static libraries since MSVC won't select a CRT for # us in that case and will error out asking us to pick one. try: - crt_val = self.environment.coredata.optstore.get_value_for('b_vscrt') + crt_val = self.environment.coredata.optstore.get_value_for_untyped('b_vscrt') assert isinstance(crt_val, str), 'for mypy' cargs += self.get_crt_compile_args(crt_val) largs += self.get_crt_link_args(crt_val) diff --git a/mesonbuild/compilers/mixins/elbrus.py b/mesonbuild/compilers/mixins/elbrus.py index 6c0490720fe1..e3c67034b32d 100644 --- a/mesonbuild/compilers/mixins/elbrus.py +++ b/mesonbuild/compilers/mixins/elbrus.py @@ -86,9 +86,9 @@ def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = args: T.List[str] = [] key = OptionKey(f'{self.language}_std', subproject=subproject, machine=self.for_machine) if target: - std = self.environment.coredata.optstore.get_option_for_target(target, key) + std = self.environment.coredata.optstore.get_option_for_target_untyped(target, key) else: - std = self.environment.coredata.optstore.get_value_for(key) + std = self.environment.coredata.optstore.get_value_for_untyped(key) assert isinstance(std, str) if std != 'none': args.append('-std=' + std) diff --git a/mesonbuild/compilers/mixins/emscripten.py b/mesonbuild/compilers/mixins/emscripten.py index 3dd65b2c1052..057f87f3b1e1 100644 --- a/mesonbuild/compilers/mixins/emscripten.py +++ b/mesonbuild/compilers/mixins/emscripten.py @@ -49,7 +49,7 @@ def _get_compile_output(self, dirname: str, mode: CompileCheckMode) -> str: def thread_link_flags(self) -> T.List[str]: args = ['-pthread'] - count = self.environment.coredata.optstore.get_value_for(OptionKey(f'{self.language}_thread_count', machine=self.for_machine)) + count = self.environment.coredata.optstore.get_value_for_untyped(OptionKey(f'{self.language}_thread_count', machine=self.for_machine)) assert isinstance(count, int) if count: args.append(f'-sPTHREAD_POOL_SIZE={count}') diff --git a/mesonbuild/compilers/mixins/gnu.py b/mesonbuild/compilers/mixins/gnu.py index 776f9eda1626..98cd77912380 100644 --- a/mesonbuild/compilers/mixins/gnu.py +++ b/mesonbuild/compilers/mixins/gnu.py @@ -658,7 +658,7 @@ def get_profile_use_args(self) -> T.List[str]: def get_always_args(self) -> T.List[str]: args: T.List[str] = [] - if self.info.is_os2() and self.environment.coredata.optstore.get_value_for(OptionKey('os2_emxomf')): + if self.info.is_os2() and self.environment.coredata.optstore.get_value_for_untyped(OptionKey('os2_emxomf')): args += ['-Zomf'] return super().get_always_args() + args diff --git a/mesonbuild/compilers/objc.py b/mesonbuild/compilers/objc.py index c6ae626ae96b..2d69fd693092 100644 --- a/mesonbuild/compilers/objc.py +++ b/mesonbuild/compilers/objc.py @@ -78,9 +78,9 @@ def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = args: T.List[str] = [] key = OptionKey('c_std', subproject=subproject, machine=self.for_machine) if target: - std = self.environment.coredata.optstore.get_option_for_target(target, key) + std = self.environment.coredata.optstore.get_option_for_target_untyped(target, key) else: - std = self.environment.coredata.optstore.get_value_for(key) + std = self.environment.coredata.optstore.get_value_for_untyped(key) assert isinstance(std, str) if std != 'none': args.append('-std=' + std) diff --git a/mesonbuild/compilers/objcpp.py b/mesonbuild/compilers/objcpp.py index aa1ff6bc5771..90fb304a7412 100644 --- a/mesonbuild/compilers/objcpp.py +++ b/mesonbuild/compilers/objcpp.py @@ -82,9 +82,9 @@ def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = args: T.List[str] = [] key = OptionKey('cpp_std', subproject=subproject, machine=self.for_machine) if target: - std = self.environment.coredata.optstore.get_option_for_target(target, key) + std = self.environment.coredata.optstore.get_option_for_target_untyped(target, key) else: - std = self.environment.coredata.optstore.get_value_for(key) + std = self.environment.coredata.optstore.get_value_for_untyped(key) assert isinstance(std, str) if std != 'none': args.append('-std=' + std) diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py index 7f0af3858a67..cef1d3f3591e 100644 --- a/mesonbuild/compilers/rust.py +++ b/mesonbuild/compilers/rust.py @@ -269,7 +269,7 @@ def get_nightly(self, target: T.Optional[BuildTarget]) -> bool: if not target: return self.allow_nightly key = self.form_compileropt_key('nightly') - nightly_opt = self.environment.coredata.optstore.get_option_for_target(target, key) + nightly_opt = self.environment.coredata.optstore.get_option_for_target_untyped(target, key) if nightly_opt == 'enabled' and not self.is_nightly: raise EnvironmentException(f'Rust compiler {self.name_string()} is not a nightly compiler as required by the "nightly" option.') return nightly_opt != 'disabled' and self.is_nightly diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index 0194ca800de0..f6a48f88c45b 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -122,8 +122,8 @@ def __init__(self, builtins: options.OptionStore, for_machine: MachineChoice): def __calculate_subkey(self, type_: DependencyCacheType) -> T.Tuple[str, ...]: data: T.Dict[DependencyCacheType, T.List[str]] = { - DependencyCacheType.PKG_CONFIG: T.cast('T.List[str]', self.__builtins.get_value_for(self.__pkg_conf_key)), - DependencyCacheType.CMAKE: T.cast('T.List[str]', self.__builtins.get_value_for(self.__cmake_key)), + DependencyCacheType.PKG_CONFIG: T.cast('T.List[str]', self.__builtins.get_value_for_untyped(self.__pkg_conf_key)), + DependencyCacheType.CMAKE: T.cast('T.List[str]', self.__builtins.get_value_for_untyped(self.__cmake_key)), DependencyCacheType.OTHER: [], } assert type_ in data, 'Someone forgot to update subkey calculations for a new type' @@ -349,7 +349,7 @@ def clear_cache(self) -> None: def get_nondefault_buildtype_args(self) -> T.List[T.Union[T.Tuple[str, str, str], T.Tuple[str, bool, bool]]]: result: T.List[T.Union[T.Tuple[str, str, str], T.Tuple[str, bool, bool]]] = [] - value = self.optstore.get_value_for('buildtype') + value = self.optstore.get_value_for_untyped('buildtype') if value == 'plain': opt = 'plain' debug = False @@ -368,8 +368,8 @@ def get_nondefault_buildtype_args(self) -> T.List[T.Union[T.Tuple[str, str, str] else: assert value == 'custom' return [] - actual_opt = self.optstore.get_value_for('optimization') - actual_debug = self.optstore.get_value_for('debug') + actual_opt = self.optstore.get_value_for_untyped('optimization') + actual_debug = self.optstore.get_value_for_untyped('debug') assert isinstance(actual_opt, str) # for mypy assert isinstance(actual_debug, bool) # for mypy if actual_opt != opt: @@ -424,7 +424,7 @@ def process_compiler_options(self, lang: Language, comp: Compiler, subproject: s def emit_base_options_warnings(self) -> None: bcodekey = OptionKey('b_bitcode') - if bcodekey in self.optstore and self.optstore.get_value_for(bcodekey): + if bcodekey in self.optstore and self.optstore.get_value_for_untyped(bcodekey): msg = textwrap.dedent('''Base option 'b_bitcode' is enabled, which is incompatible with many linker options. Incompatible options such as \'b_asneeded\' have been disabled.' Please see https://mesonbuild.com/Builtin-options.html#Notes_about_Apple_Bitcode_support for more details.''') diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py index 30aa4a43135d..85c8ae0fc247 100644 --- a/mesonbuild/dependencies/base.py +++ b/mesonbuild/dependencies/base.py @@ -431,7 +431,7 @@ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObje self.silent = kwargs.get('silent', False) static = kwargs.get('static') if static is None: - static = T.cast('bool', self.env.coredata.optstore.get_value_for(OptionKey('prefer_static'))) + static = T.cast('bool', self.env.coredata.optstore.get_value_for_untyped(OptionKey('prefer_static'))) self.static = static self.libtype = LibType.STATIC if self.static else LibType.PREFER_SHARED # Is this dependency to be run on the build platform? diff --git a/mesonbuild/dependencies/boost.py b/mesonbuild/dependencies/boost.py index fe3fade03a2c..e48c662dc7a5 100644 --- a/mesonbuild/dependencies/boost.py +++ b/mesonbuild/dependencies/boost.py @@ -343,7 +343,7 @@ class BoostDependency(SystemDependency): def __init__(self, name: str, environment: Environment, kwargs: DependencyObjectKWs) -> None: kwargs['language'] = 'cpp' super().__init__(name, environment, kwargs) - buildtype = environment.coredata.optstore.get_value_for(OptionKey('buildtype')) + buildtype = environment.coredata.optstore.get_value_for_untyped(OptionKey('buildtype')) assert isinstance(buildtype, str) self.debug = buildtype.startswith('debug') self.multithreading = kwargs.get('threading', 'multi') == 'multi' @@ -604,7 +604,7 @@ def filter_libraries(self, libs: T.List[BoostLibraryFile], lib_vers: str) -> T.L # MSVC is very picky with the library tags vscrt = '' try: - crt_val = self.env.coredata.optstore.get_value_for('b_vscrt') + crt_val = self.env.coredata.optstore.get_value_for_untyped('b_vscrt') assert isinstance(crt_val, str) vscrt = self.clib_compiler.get_crt_compile_args(crt_val)[0] except (KeyError, IndexError, AttributeError): diff --git a/mesonbuild/dependencies/dub.py b/mesonbuild/dependencies/dub.py index 7b4daf37c26d..99a652a4075d 100644 --- a/mesonbuild/dependencies/dub.py +++ b/mesonbuild/dependencies/dub.py @@ -124,7 +124,7 @@ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObje dub_arch = self.compiler.arch # we need to know the build type as well - dub_buildtype = str(environment.coredata.optstore.get_value_for(OptionKey('buildtype'))) + dub_buildtype = str(environment.coredata.optstore.get_value_for_untyped(OptionKey('buildtype'))) # MESON types: choices=['plain', 'debug', 'debugoptimized', 'release', 'minsize', 'custom'])), # DUB types: debug (default), plain, release, release-debug, release-nobounds, unittest, profile, profile-gc, # docs, ddox, cov, unittest-cov, syntax and custom diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index 1f9f06e97241..82f650ca3ff1 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -578,7 +578,7 @@ def shaderc_factory(env: 'Environment', static = kwargs.get('static') if static is None: - static = T.cast('bool', env.coredata.optstore.get_value_for(OptionKey('prefer_static'))) + static = T.cast('bool', env.coredata.optstore.get_value_for_untyped(OptionKey('prefer_static'))) if static: c = [DependencyCandidate.from_dependency(name, PkgConfigDependency, (env, kwargs)) for name in static_libs + shared_libs] diff --git a/mesonbuild/dependencies/mpi.py b/mesonbuild/dependencies/mpi.py index 3258e1e03390..fb654afdb5c8 100644 --- a/mesonbuild/dependencies/mpi.py +++ b/mesonbuild/dependencies/mpi.py @@ -283,7 +283,7 @@ def __init__(self, name: str, env: Environment, kwargs: DependencyObjectKWs): incdir = os.path.join(rootdir, 'include') libdir = os.path.join(rootdir, 'lib') - debug = env.coredata.optstore.get_value_for('debug') + debug = env.coredata.optstore.get_value_for_untyped('debug') assert isinstance(debug, bool) libdir_post = 'debug' if debug else 'release' for subdirs in (['mpi', libdir_post], [libdir_post]): diff --git a/mesonbuild/dependencies/pkgconfig.py b/mesonbuild/dependencies/pkgconfig.py index 91f783da2fdd..3e7c0d1d20f3 100644 --- a/mesonbuild/dependencies/pkgconfig.py +++ b/mesonbuild/dependencies/pkgconfig.py @@ -268,7 +268,7 @@ def _check_pkgconfig(self, pkgbin: ExternalProgram) -> T.Optional[str]: def _get_env(self, uninstalled: bool = False) -> EnvironmentVariables: env = EnvironmentVariables() key = OptionKey('pkg_config_path', machine=self.for_machine) - pathlist = self.env.coredata.optstore.get_value_for(key) + pathlist = self.env.coredata.optstore.get_value_for_untyped(key) assert isinstance(pathlist, list) extra_paths: T.List[str] = pathlist + self.extra_paths if uninstalled: @@ -435,7 +435,7 @@ def _search_libs(self, libs_in: ImmutableListProtocol[str], raw_libs_in: Immutab # # Only prefix_libpaths are reordered here because there should not be # too many system_libpaths to cause library version issues. - pkg_config_path: T.List[str] = self.env.coredata.optstore.get_value_for(OptionKey('pkg_config_path', machine=self.for_machine)) # type: ignore[assignment] + pkg_config_path: T.List[str] = self.env.coredata.optstore.get_value_for_untyped(OptionKey('pkg_config_path', machine=self.for_machine)) # type: ignore[assignment] pkg_config_path = self._convert_mingw_paths(pkg_config_path) prefix_libpaths = OrderedSet(sort_libpaths(list(prefix_libpaths), pkg_config_path)) system_libpaths: OrderedSet[str] = OrderedSet() diff --git a/mesonbuild/dependencies/python.py b/mesonbuild/dependencies/python.py index 3b02bad663f9..8eb9f6cb32e6 100644 --- a/mesonbuild/dependencies/python.py +++ b/mesonbuild/dependencies/python.py @@ -396,14 +396,14 @@ def get_windows_link_args(self, limited_api: bool, environment: 'Environment') - # Python itself (except with pybind11, which has an ugly # hack to work around this) - so emit a warning to explain # the cause of the expected link error. - buildtype = self.env.coredata.optstore.get_value_for(OptionKey('buildtype')) + buildtype = self.env.coredata.optstore.get_value_for_untyped(OptionKey('buildtype')) assert isinstance(buildtype, str) - debug = self.env.coredata.optstore.get_value_for(OptionKey('debug')) + debug = self.env.coredata.optstore.get_value_for_untyped(OptionKey('debug')) # `debugoptimized` buildtype may not set debug=True currently, see gh-11645 is_debug_build = debug or buildtype == 'debug' vscrt_debug = False if OptionKey('b_vscrt') in self.env.coredata.optstore: - vscrt = self.env.coredata.optstore.get_value_for('b_vscrt') + vscrt = self.env.coredata.optstore.get_value_for_untyped('b_vscrt') if vscrt in {'mdd', 'mtd', 'from_buildtype', 'static_from_buildtype'}: vscrt_debug = True if is_debug_build and vscrt_debug and not self.variables.get('Py_DEBUG'): diff --git a/mesonbuild/dependencies/qt.py b/mesonbuild/dependencies/qt.py index aa321e92cdd7..793edb3a89fb 100644 --- a/mesonbuild/dependencies/qt.py +++ b/mesonbuild/dependencies/qt.py @@ -168,7 +168,7 @@ def log_details(self) -> str: return f'modules: {", ".join(sorted(self.requested_modules))}' def _get_common_defines(self) -> T.List[str]: - is_debug = self.env.coredata.optstore.get_value_for('debug') + is_debug = self.env.coredata.optstore.get_value_for_untyped('debug') return ['-DQT_DEBUG' if is_debug else '-DQT_NO_DEBUG'] class QtPkgConfigDependency(_QtBase, PkgConfigDependency, metaclass=abc.ABCMeta): @@ -305,9 +305,9 @@ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs): # Use the buildtype by default, but look at the b_vscrt option if the # compiler supports it. - is_debug = self.env.coredata.optstore.get_value_for('buildtype') == 'debug' + is_debug = self.env.coredata.optstore.get_value_for_untyped('buildtype') == 'debug' if 'b_vscrt' in self.env.coredata.optstore: - if self.env.coredata.optstore.get_value_for('b_vscrt') in {'mdd', 'mtd'}: + if self.env.coredata.optstore.get_value_for_untyped('b_vscrt') in {'mdd', 'mtd'}: is_debug = True modules_lib_suffix = _get_modules_lib_suffix(self.version, self.env.machines[self.for_machine], is_debug) diff --git a/mesonbuild/dependencies/scalapack.py b/mesonbuild/dependencies/scalapack.py index 92276ce68b6d..c1678b3eaaba 100644 --- a/mesonbuild/dependencies/scalapack.py +++ b/mesonbuild/dependencies/scalapack.py @@ -27,7 +27,7 @@ def scalapack_factory(env: 'Environment', candidates: T.List['DependencyGenerator'] = [] if DependencyMethods.PKGCONFIG in methods: - static_opt = kwargs['static'] if kwargs.get('static') is not None else env.coredata.optstore.get_value_for(OptionKey('prefer_static')) + static_opt = kwargs['static'] if kwargs.get('static') is not None else env.coredata.optstore.get_value_for_untyped(OptionKey('prefer_static')) mkl = 'mkl-static-lp64-iomp' if static_opt else 'mkl-dynamic-lp64-iomp' candidates.append(DependencyCandidate.from_dependency( mkl, MKLPkgConfigDependency, (env, kwargs))) diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index de5daa48b4fb..c20866083e81 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -488,25 +488,25 @@ def get_static_lib_dir(self) -> str: return self.get_libdir() def get_prefix(self) -> str: - return _as_str(self.coredata.optstore.get_value_for(OptionKey('prefix'))) + return _as_str(self.coredata.optstore.get_value_for_untyped(OptionKey('prefix'))) def get_libdir(self) -> str: - return _as_str(self.coredata.optstore.get_value_for(OptionKey('libdir'))) + return _as_str(self.coredata.optstore.get_value_for_untyped(OptionKey('libdir'))) def get_libexecdir(self) -> str: - return _as_str(self.coredata.optstore.get_value_for(OptionKey('libexecdir'))) + return _as_str(self.coredata.optstore.get_value_for_untyped(OptionKey('libexecdir'))) def get_bindir(self) -> str: - return _as_str(self.coredata.optstore.get_value_for(OptionKey('bindir'))) + return _as_str(self.coredata.optstore.get_value_for_untyped(OptionKey('bindir'))) def get_includedir(self) -> str: - return _as_str(self.coredata.optstore.get_value_for(OptionKey('includedir'))) + return _as_str(self.coredata.optstore.get_value_for_untyped(OptionKey('includedir'))) def get_mandir(self) -> str: - return _as_str(self.coredata.optstore.get_value_for(OptionKey('mandir'))) + return _as_str(self.coredata.optstore.get_value_for_untyped(OptionKey('mandir'))) def get_datadir(self) -> str: - return _as_str(self.coredata.optstore.get_value_for(OptionKey('datadir'))) + return _as_str(self.coredata.optstore.get_value_for_untyped(OptionKey('datadir'))) def get_compiler_system_lib_dirs(self, for_machine: MachineChoice) -> T.List[str]: for comp in self.coredata.compilers[for_machine].values(): diff --git a/mesonbuild/interpreter/compiler.py b/mesonbuild/interpreter/compiler.py index b0224db1fe9b..bd9a95b95211 100644 --- a/mesonbuild/interpreter/compiler.py +++ b/mesonbuild/interpreter/compiler.py @@ -699,7 +699,7 @@ def find_library_method(self, args: T.Tuple[str], kwargs: 'FindLibraryKW') -> 'd search_dirs = extract_search_dirs(kwargs) - prefer_static = self.environment.coredata.optstore.get_value_for(OptionKey('prefer_static')) + prefer_static = self.environment.coredata.optstore.get_value_for_untyped(OptionKey('prefer_static')) if kwargs['static'] is True: libtype = mesonlib.LibType.STATIC elif kwargs['static'] is False: diff --git a/mesonbuild/interpreter/dependencyfallbacks.py b/mesonbuild/interpreter/dependencyfallbacks.py index 1685cc9de70a..7a72ad82efb5 100644 --- a/mesonbuild/interpreter/dependencyfallbacks.py +++ b/mesonbuild/interpreter/dependencyfallbacks.py @@ -322,10 +322,10 @@ def lookup(self, kwargs: DependencyObjectKWs, force_fallback: bool = False) -> D required = kwargs.get('required', True) # Check if usage of the subproject fallback is forced - _wm = self.coredata.optstore.get_value_for(OptionKey('wrap_mode')) + _wm = self.coredata.optstore.get_value_for_untyped(OptionKey('wrap_mode')) assert isinstance(_wm, str), 'for mypy' wrap_mode = WrapMode.from_string(_wm) - force_fallback_for = self.coredata.optstore.get_value_for(OptionKey('force_fallback_for')) + force_fallback_for = self.coredata.optstore.get_value_for_untyped(OptionKey('force_fallback_for')) assert isinstance(force_fallback_for, list), 'for mypy' self.nofallback = wrap_mode == WrapMode.nofallback self.forcefallback = (force_fallback or diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index a69b50a7d157..289ff48fb366 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -1086,7 +1086,7 @@ def func_get_option(self, node: mparser.BaseNode, args: T.Tuple[str], try: optkey = options.OptionKey.from_string(optname).evolve(subproject=self.subproject) - option_object, value = self.coredata.optstore.get_option_and_value_for(optkey) + option_object, value = self.coredata.optstore.get_option_and_value_for_untyped(optkey) except KeyError: if self.coredata.optstore.is_base_option(optkey): # Due to backwards compatibility return the default @@ -1138,10 +1138,10 @@ def set_backend(self) -> None: if OptionKey('genvslite') in self.user_defined_options.cmd_line_options: # Use of the '--genvslite vsxxxx' option ultimately overrides any '--backend xxx' # option the user may specify. - backend_name = self.coredata.optstore.get_value_for(OptionKey('genvslite')) + backend_name = self.coredata.optstore.get_value_for_untyped(OptionKey('genvslite')) self.backend = backends.get_genvslite_backend(backend_name, self.build) else: - backend_name = self.coredata.optstore.get_value_for(OptionKey('backend')) + backend_name = self.coredata.optstore.get_value_for_untyped(OptionKey('backend')) self.backend = backends.get_backend_from_name(backend_name, self.build) if self.backend is None: @@ -1227,9 +1227,9 @@ def func_project(self, node: mparser.FunctionNode, args: T.Tuple[str, T.List[str # self.set_backend() otherwise it wouldn't be able to detect which # vs backend version we need. But after setting default_options in case # the project sets vs backend by default. - backend = self.coredata.optstore.get_value_for(OptionKey('backend')) + backend = self.coredata.optstore.get_value_for_untyped(OptionKey('backend')) assert backend is None or isinstance(backend, str), 'for mypy' - vsenv = self.coredata.optstore.get_value_for(OptionKey('vsenv')) + vsenv = self.coredata.optstore.get_value_for_untyped(OptionKey('vsenv')) assert isinstance(vsenv, bool), 'for mypy' force_vsenv = vsenv or backend.startswith('vs') mesonlib.setup_vsenv(force_vsenv) @@ -1295,7 +1295,7 @@ def func_project(self, node: mparser.FunctionNode, args: T.Tuple[str, T.List[str # Load wrap files from this (sub)project. subprojects_dir = os.path.join(self.subdir, spdirname) if not self.is_subproject(): - wrap_mode = WrapMode.from_string(self.coredata.optstore.get_value_for(OptionKey('wrap_mode'))) + wrap_mode = WrapMode.from_string(self.coredata.optstore.get_value_for_untyped(OptionKey('wrap_mode'))) self.environment.wrap_resolver = wrap.Resolver(self.environment.get_source_dir(), subprojects_dir, self.subproject, wrap_mode) else: assert self.environment.wrap_resolver is not None, 'for mypy' @@ -1720,7 +1720,7 @@ def program_lookup(self, args: T.List[mesonlib.FileOrString], for_machine: Machi return ExternalProgram('meson', self.environment.get_build_command(), silent=True) fallback = None - wrap_mode = WrapMode.from_string(self.coredata.optstore.get_value_for(OptionKey('wrap_mode'))) + wrap_mode = WrapMode.from_string(self.coredata.optstore.get_value_for_untyped(OptionKey('wrap_mode'))) if wrap_mode != WrapMode.nofallback and self.environment.wrap_resolver: fallback = self.environment.wrap_resolver.find_program_provider(args) if fallback and wrap_mode == WrapMode.forcefallback: @@ -3137,9 +3137,9 @@ def check_clang_asan_lundef(self) -> None: return if OptionKey('b_sanitize') not in self.coredata.optstore: return - if (self.coredata.optstore.get_value_for('b_lundef') and - self.coredata.optstore.get_value_for('b_sanitize')): - value = self.coredata.optstore.get_value_for('b_sanitize') + if (self.coredata.optstore.get_value_for_untyped('b_lundef') and + self.coredata.optstore.get_value_for_untyped('b_sanitize')): + value = self.coredata.optstore.get_value_for_untyped('b_sanitize') mlog.warning(textwrap.dedent(f'''\ Trying to use {value} sanitizer on Clang with b_lundef. This will probably not work. @@ -3325,9 +3325,9 @@ def add_target(self, name: str, tobj: build.Target) -> None: def build_both_libraries(self, node: mparser.BaseNode, args: T.Tuple[str, SourcesVarargsType], kwargs: kwtypes.Library) -> build.BothLibraries: shared_lib = self.build_target(node, args, kwargs, build.SharedLibrary, shared_library_only=False) static_lib = self.build_target(node, args, kwargs, build.StaticLibrary) - preferred_library = self.coredata.optstore.get_value_for(OptionKey('default_both_libraries', subproject=self.subproject)) + preferred_library = self.coredata.optstore.get_value_for_untyped(OptionKey('default_both_libraries', subproject=self.subproject)) if preferred_library == 'auto': - preferred_library = self.coredata.optstore.get_value_for(OptionKey('default_library', subproject=self.subproject)) + preferred_library = self.coredata.optstore.get_value_for_untyped(OptionKey('default_library', subproject=self.subproject)) if preferred_library == 'both': preferred_library = 'shared' @@ -3368,7 +3368,7 @@ def build_both_libraries(self, node: mparser.BaseNode, args: T.Tuple[str, Source return build.BothLibraries(shared_lib, static_lib, preferred_library) def build_library(self, node: mparser.BaseNode, args: T.Tuple[str, SourcesVarargsType], kwargs: kwtypes.Library): - default_library = self.coredata.optstore.get_value_for(OptionKey('default_library', subproject=self.subproject)) + default_library = self.coredata.optstore.get_value_for_untyped(OptionKey('default_library', subproject=self.subproject)) assert isinstance(default_library, str), 'for mypy' if default_library == 'shared': return self.build_target(node, args, T.cast('kwtypes.SharedLibrary', kwargs), build.SharedLibrary) diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py index ca935cb2d9b4..9e5205a95d47 100644 --- a/mesonbuild/interpreter/interpreterobjects.py +++ b/mesonbuild/interpreter/interpreterobjects.py @@ -1034,7 +1034,7 @@ def extract_objects_method(self, args: T.Tuple[T.List[T.Union[mesonlib.FileOrStr if self.subproject != self.held_object.subproject: raise InterpreterException('Tried to extract objects from a different subproject.') tobj = self._target_object - unity_value = self.interpreter.coredata.optstore.get_option_for_target(tobj, "unity") + unity_value = self.interpreter.coredata.optstore.get_option_for_target_untyped(tobj, "unity") is_unity = (unity_value == 'on' or (unity_value == 'subprojects' and tobj.subproject != '')) return tobj.extract_objects(args[0], is_unity) diff --git a/mesonbuild/interpreter/mesonmain.py b/mesonbuild/interpreter/mesonmain.py index dafabcbcbca5..4da19ce9f7ed 100644 --- a/mesonbuild/interpreter/mesonmain.py +++ b/mesonbuild/interpreter/mesonmain.py @@ -307,7 +307,7 @@ def get_compiler_method(self, args: T.Tuple[str], kwargs: 'NativeKW') -> 'Compil @noKwargs @InterpreterObject.method('is_unity') def is_unity_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> bool: - optval = self.interpreter.environment.coredata.optstore.get_value_for(OptionKey('unity')) + optval = self.interpreter.environment.coredata.optstore.get_value_for_untyped(OptionKey('unity')) return optval == 'on' or (optval == 'subprojects' and self.interpreter.is_subproject()) @noPosargs @@ -363,7 +363,7 @@ def override_dependency_method(self, args: T.Tuple[str, dependencies.Dependency] dep.name = name optkey = OptionKey('default_library', subproject=self.interpreter.subproject) - default_library = self.interpreter.coredata.optstore.get_value_for(optkey) + default_library = self.interpreter.coredata.optstore.get_value_for_untyped(optkey) assert isinstance(default_library, str), 'for mypy' static = kwargs['static'] if static is None: diff --git a/mesonbuild/linkers/detect.py b/mesonbuild/linkers/detect.py index 10c7695d384d..b6407f6e2f8d 100644 --- a/mesonbuild/linkers/detect.py +++ b/mesonbuild/linkers/detect.py @@ -144,7 +144,7 @@ def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty override = comp_class.use_linker_args(value[0], comp_version) check_args += override - if env.machines[for_machine].is_os2() and env.coredata.optstore.get_value_for(OptionKey('os2_emxomf')): + if env.machines[for_machine].is_os2() and env.coredata.optstore.get_value_for_untyped(OptionKey('os2_emxomf')): check_args += ['-Zomf'] mlog.debug('-----') diff --git a/mesonbuild/mcompile.py b/mesonbuild/mcompile.py index 72219588ceed..a304130708e0 100644 --- a/mesonbuild/mcompile.py +++ b/mesonbuild/mcompile.py @@ -355,14 +355,14 @@ def run(options: 'argparse.Namespace') -> int: b = build.load(options.wd) cdata = b.environment.coredata - need_vsenv = T.cast('bool', cdata.optstore.get_value_for(OptionKey('vsenv'))) + need_vsenv = T.cast('bool', cdata.optstore.get_value_for_untyped(OptionKey('vsenv'))) if setup_vsenv(need_vsenv): mlog.log(mlog.green('INFO:'), 'automatically activated MSVC compiler environment') cmd: T.List[str] = [] env: T.Optional[T.Dict[str, str]] = None - backend = cdata.optstore.get_value_for(OptionKey('backend')) + backend = cdata.optstore.get_value_for_untyped(OptionKey('backend')) assert isinstance(backend, str) mlog.log(mlog.green('INFO:'), 'autodetecting backend as', backend) if backend == 'ninja': diff --git a/mesonbuild/mdevenv.py b/mesonbuild/mdevenv.py index bd1ed134a529..04bd9ee5c32f 100644 --- a/mesonbuild/mdevenv.py +++ b/mesonbuild/mdevenv.py @@ -98,9 +98,9 @@ def bash_completion_files(b: build.Build, install_data: 'InstallData') -> T.List dep = PkgConfigDependency('bash-completion', b.environment, {'required': False, 'silent': True, 'version': ['>=2.10'], 'native': MachineChoice.HOST}) if dep.found(): - prefix = b.environment.coredata.optstore.get_value_for(OptionKey('prefix')) + prefix = b.environment.coredata.optstore.get_value_for_untyped(OptionKey('prefix')) assert isinstance(prefix, str), 'for mypy' - datadir = b.environment.coredata.optstore.get_value_for(OptionKey('datadir')) + datadir = b.environment.coredata.optstore.get_value_for_untyped(OptionKey('datadir')) assert isinstance(datadir, str), 'for mypy' datadir_abs = os.path.join(prefix, datadir) completionsdir = dep.get_variable(pkgconfig='completionsdir', pkgconfig_define=(('datadir', datadir_abs),)) @@ -186,7 +186,7 @@ def run(options: argparse.Namespace) -> int: b = build.load(options.builddir) workdir = options.workdir or options.builddir - need_vsenv = T.cast('bool', b.environment.coredata.optstore.get_value_for(OptionKey('vsenv'))) + need_vsenv = T.cast('bool', b.environment.coredata.optstore.get_value_for_untyped(OptionKey('vsenv'))) setup_vsenv(need_vsenv) # Call it before get_env to get vsenv vars as well dump_fmt = options.dump_format if options.dump else None devenv, varnames = get_env(b, dump_fmt) diff --git a/mesonbuild/mdist.py b/mesonbuild/mdist.py index 9fcde5bba06a..ff2af486734f 100644 --- a/mesonbuild/mdist.py +++ b/mesonbuild/mdist.py @@ -381,7 +381,7 @@ def run(options: argparse.Namespace) -> int: if not buildfile.is_file(): raise MesonException(f'Directory {options.wd!r} does not seem to be a Meson build directory.') b = build.load(options.wd) - need_vsenv = T.cast('bool', b.environment.coredata.optstore.get_value_for(OptionKey('vsenv'))) + need_vsenv = T.cast('bool', b.environment.coredata.optstore.get_value_for_untyped(OptionKey('vsenv'))) setup_vsenv(need_vsenv) src_root = b.environment.source_dir bld_root = b.environment.build_dir diff --git a/mesonbuild/minit.py b/mesonbuild/minit.py index 7d0d051ad7d7..c0a7d0cde787 100644 --- a/mesonbuild/minit.py +++ b/mesonbuild/minit.py @@ -193,7 +193,7 @@ def run(options: Arguments) -> int: raise SystemExit b = build.load(options.builddir) - need_vsenv = T.cast('bool', b.environment.coredata.optstore.get_value_for(OptionKey('vsenv'))) + need_vsenv = T.cast('bool', b.environment.coredata.optstore.get_value_for_untyped(OptionKey('vsenv'))) vsenv_active = mesonlib.setup_vsenv(need_vsenv) if vsenv_active: mlog.log(mlog.green('INFO:'), 'automatically activated MSVC compiler environment') diff --git a/mesonbuild/minstall.py b/mesonbuild/minstall.py index e9eb9f070eef..860caf8845c1 100644 --- a/mesonbuild/minstall.py +++ b/mesonbuild/minstall.py @@ -870,9 +870,9 @@ def run(opts: 'ArgumentType') -> int: sys.exit('Install data not found. Run this command in build directory root.') if not opts.no_rebuild: b = build.load(opts.wd) - need_vsenv = T.cast('bool', b.environment.coredata.optstore.get_value_for(OptionKey('vsenv'))) + need_vsenv = T.cast('bool', b.environment.coredata.optstore.get_value_for_untyped(OptionKey('vsenv'))) setup_vsenv(need_vsenv) - backend = T.cast('str', b.environment.coredata.optstore.get_value_for(OptionKey('backend'))) + backend = T.cast('str', b.environment.coredata.optstore.get_value_for_untyped(OptionKey('backend'))) if not rebuild_all(opts.wd, backend): sys.exit(-1) os.chdir(opts.wd) diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index e3fcf217ecf6..1ea05d56d5a2 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -166,7 +166,7 @@ def list_install_plan(installdata: backends.InstallData) -> T.Dict[str, T.Dict[s return plan def get_target_dir(coredata: cdata.CoreData, subdir: str) -> str: - if coredata.optstore.get_value_for(OptionKey('layout')) == 'flat': + if coredata.optstore.get_value_for_untyped(OptionKey('layout')) == 'flat': return 'meson-out' else: return subdir diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py index 45ca2286f9d0..267ee2f4673d 100644 --- a/mesonbuild/modules/__init__.py +++ b/mesonbuild/modules/__init__.py @@ -161,7 +161,7 @@ def test(self, args: T.Tuple[str, T.Union[build.Executable, build.Jar, Program, def get_option(self, name: str, subproject: str = '', machine: MachineChoice = MachineChoice.HOST) -> ElementaryOptionValues: - return self.environment.coredata.optstore.get_value_for(OptionKey(name, subproject, machine)) + return self.environment.coredata.optstore.get_value_for_untyped(OptionKey(name, subproject, machine)) def is_user_defined_option(self, name: str, subproject: str = '', machine: MachineChoice = MachineChoice.HOST, diff --git a/mesonbuild/modules/cmake.py b/mesonbuild/modules/cmake.py index 2091499c30a3..3342f63ce2fc 100644 --- a/mesonbuild/modules/cmake.py +++ b/mesonbuild/modules/cmake.py @@ -307,7 +307,7 @@ def write_basic_package_version_file(self, state: ModuleState, args: TYPE_var, k pkgroot = pkgroot_name = kwargs['install_dir'] if pkgroot is None: - libdir = state.environment.coredata.optstore.get_value_for(OptionKey('libdir')) + libdir = state.environment.coredata.optstore.get_value_for_untyped(OptionKey('libdir')) assert isinstance(libdir, str), 'for mypy' pkgroot = os.path.join(libdir, 'cmake', name) pkgroot_name = os.path.join('{libdir}', 'cmake', name) @@ -380,7 +380,7 @@ def configure_package_config_file(self, state: ModuleState, args: TYPE_var, kwar install_dir = kwargs['install_dir'] if install_dir is None: - libdir = state.environment.coredata.optstore.get_value_for(OptionKey('libdir')) + libdir = state.environment.coredata.optstore.get_value_for_untyped(OptionKey('libdir')) assert isinstance(libdir, str), 'for mypy' install_dir = os.path.join(libdir, 'cmake', name) @@ -389,7 +389,7 @@ def configure_package_config_file(self, state: ModuleState, args: TYPE_var, kwar FeatureNew.single_use('cmake.configure_package_config_file dict as configuration', '0.62.0', state.subproject, location=state.current_node) conf = build.ConfigurationData(conf) - prefix = state.environment.coredata.optstore.get_value_for(OptionKey('prefix')) + prefix = state.environment.coredata.optstore.get_value_for_untyped(OptionKey('prefix')) assert isinstance(prefix, str), 'for mypy' abs_install_dir = install_dir if not os.path.isabs(abs_install_dir): diff --git a/mesonbuild/modules/external_project.py b/mesonbuild/modules/external_project.py index ed6ead5ae650..039e0baf5f4c 100644 --- a/mesonbuild/modules/external_project.py +++ b/mesonbuild/modules/external_project.py @@ -76,16 +76,16 @@ def __init__(self, self.src_dir = Path(self.env.get_source_dir(), self.subdir) self.build_dir = Path(self.env.get_build_dir(), self.subdir, 'build') self.install_dir = Path(self.env.get_build_dir(), self.subdir, 'dist') - _p = self.env.coredata.optstore.get_value_for(OptionKey('prefix')) + _p = self.env.coredata.optstore.get_value_for_untyped(OptionKey('prefix')) assert isinstance(_p, str), 'for mypy' self.prefix = Path(_p) - _l = self.env.coredata.optstore.get_value_for(OptionKey('libdir')) + _l = self.env.coredata.optstore.get_value_for_untyped(OptionKey('libdir')) assert isinstance(_l, str), 'for mypy' self.libdir = Path(_l) - _l = self.env.coredata.optstore.get_value_for(OptionKey('bindir')) + _l = self.env.coredata.optstore.get_value_for_untyped(OptionKey('bindir')) assert isinstance(_l, str), 'for mypy' self.bindir = Path(_l) - _i = self.env.coredata.optstore.get_value_for(OptionKey('includedir')) + _i = self.env.coredata.optstore.get_value_for_untyped(OptionKey('includedir')) assert isinstance(_i, str), 'for mypy' self.includedir = Path(_i) self.name = self.src_dir.name diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index 36386c9ccdc9..8dd37499b90d 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -525,7 +525,7 @@ def compile_resources(self, state: 'ModuleState', args: T.Tuple[str, 'FileOrStri if gresource: # Only one target for .gresource files return ModuleReturnValue(target_c, [target_c]) - install_dir = kwargs['install_dir'] or state.environment.coredata.optstore.get_value_for(OptionKey('includedir')) + install_dir = kwargs['install_dir'] or state.environment.coredata.optstore.get_value_for_untyped(OptionKey('includedir')) assert isinstance(install_dir, str), 'for mypy' target_h = GResourceHeaderTarget( f'{target_name}_h', @@ -922,7 +922,7 @@ def _get_langs_compilers_flags(state: 'ModuleState', langs_compilers: T.List[T.T if state.project_args.get(lang): cflags += state.project_args[lang] if OptionKey('b_sanitize') in compiler.base_options: - sanitize = state.environment.coredata.optstore.get_value_for('b_sanitize') + sanitize = state.environment.coredata.optstore.get_value_for_untyped('b_sanitize') assert isinstance(sanitize, list) cflags += compiler.sanitizer_compile_args(None, sanitize) # These must be first in ldflags @@ -1683,7 +1683,7 @@ def gdbus_codegen(self, state: 'ModuleState', args: T.Tuple[str, T.Optional[T.Un targets = [] install_header = kwargs['install_header'] - install_dir = kwargs['install_dir'] or state.environment.coredata.optstore.get_value_for(OptionKey('includedir')) + install_dir = kwargs['install_dir'] or state.environment.coredata.optstore.get_value_for_untyped(OptionKey('includedir')) assert isinstance(install_dir, str), 'for mypy' output = namebase + '.c' @@ -2057,7 +2057,7 @@ def _make_mkenum_impl( ) -> build.CustomTarget: real_cmd: CommandList = [self._find_tool(state, 'glib-mkenums')] real_cmd.extend(cmd) - _install_dir = install_dir or state.environment.coredata.optstore.get_value_for(OptionKey('includedir')) + _install_dir = install_dir or state.environment.coredata.optstore.get_value_for_untyped(OptionKey('includedir')) assert isinstance(_install_dir, str), 'for mypy' return CustomTarget( @@ -2269,7 +2269,7 @@ def generate_vapi(self, state: 'ModuleState', args: T.Tuple[str], kwargs: 'Gener cmd.append(gir_file) vapi_output = library + '.vapi' - datadir = state.environment.coredata.optstore.get_value_for(OptionKey('datadir')) + datadir = state.environment.coredata.optstore.get_value_for_untyped(OptionKey('datadir')) assert isinstance(datadir, str), 'for mypy' install_dir = kwargs['install_dir'] or os.path.join(datadir, 'vala', 'vapi') diff --git a/mesonbuild/modules/hotdoc.py b/mesonbuild/modules/hotdoc.py index a45fd57ecafd..5b1b44165184 100644 --- a/mesonbuild/modules/hotdoc.py +++ b/mesonbuild/modules/hotdoc.py @@ -303,7 +303,7 @@ def make_targets(self) -> T.Tuple[HotdocTarget, mesonlib.ExecutableSerialisation for path in self.include_paths: self.cmd.extend(['--include-path', path]) - if self.state.environment.coredata.optstore.get_value_for(OptionKey('werror', subproject=self.state.subproject)): + if self.state.environment.coredata.optstore.get_value_for_untyped(OptionKey('werror', subproject=self.state.subproject)): self.cmd.append('--fatal-warnings') self.generate_hotdoc_config() diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py index db728dbeaa69..a4a912096654 100644 --- a/mesonbuild/modules/i18n.py +++ b/mesonbuild/modules/i18n.py @@ -412,7 +412,7 @@ def gettext(self, state: 'ModuleState', args: T.Tuple[str], kwargs: 'Gettext') - targets.append(pottarget) install = kwargs['install'] - install_dir = kwargs['install_dir'] or state.environment.coredata.optstore.get_value_for(OptionKey('localedir')) + install_dir = kwargs['install_dir'] or state.environment.coredata.optstore.get_value_for_untyped(OptionKey('localedir')) assert isinstance(install_dir, str), 'for mypy' if not languages: languages = read_linguas(path.join(state.environment.source_dir, state.subdir)) diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py index 332ec33c214a..25f2cc780fc3 100644 --- a/mesonbuild/modules/pkgconfig.py +++ b/mesonbuild/modules/pkgconfig.py @@ -545,7 +545,7 @@ def _generate_pkgconfig_file(self, state: ModuleState, deps: DependenciesHelper, else: pure_path_class = state.environment.machines.host.pure_path_class outdir = state.environment.scratch_dir - prefix = pure_path_class(_as_str(coredata.optstore.get_value_for(OptionKey('prefix')))) + prefix = pure_path_class(_as_str(coredata.optstore.get_value_for_untyped(OptionKey('prefix')))) if pkgroot: prefix = self._get_relocatable_prefix(pkgroot, prefix, pure_path_class) # relocatable paths will never have a drive letter @@ -558,7 +558,7 @@ def _generate_pkgconfig_file(self, state: ModuleState, deps: DependenciesHelper, if optname == 'prefix': ofile.write('prefix={}\n'.format(self._escape(prefix))) else: - dirpath = PurePath(_as_str(coredata.optstore.get_value_for(OptionKey(optname)))) + dirpath = PurePath(_as_str(coredata.optstore.get_value_for_untyped(OptionKey(optname)))) ofile.write('{}={}\n'.format(optname, self._escape('${prefix}' / dirpath))) if uninstalled and not dataonly: ofile.write('srcdir={}\n'.format(self._escape(srcdir))) @@ -779,13 +779,13 @@ def parse_variable_list(vardict: T.Dict[str, str]) -> T.List[T.Tuple[str, str]]: if pkgroot is None: m = state.environment.machines.host if m.is_freebsd(): - pkgroot = os.path.join(_as_str(state.environment.coredata.optstore.get_value_for(OptionKey('prefix'))), 'libdata', 'pkgconfig') + pkgroot = os.path.join(_as_str(state.environment.coredata.optstore.get_value_for_untyped(OptionKey('prefix'))), 'libdata', 'pkgconfig') pkgroot_name = os.path.join('{prefix}', 'libdata', 'pkgconfig') elif m.is_haiku(): - pkgroot = os.path.join(_as_str(state.environment.coredata.optstore.get_value_for(OptionKey('prefix'))), 'develop', 'lib', 'pkgconfig') + pkgroot = os.path.join(_as_str(state.environment.coredata.optstore.get_value_for_untyped(OptionKey('prefix'))), 'develop', 'lib', 'pkgconfig') pkgroot_name = os.path.join('{prefix}', 'develop', 'lib', 'pkgconfig') else: - pkgroot = os.path.join(_as_str(state.environment.coredata.optstore.get_value_for(OptionKey('libdir'))), 'pkgconfig') + pkgroot = os.path.join(_as_str(state.environment.coredata.optstore.get_value_for_untyped(OptionKey('libdir'))), 'pkgconfig') pkgroot_name = os.path.join('{libdir}', 'pkgconfig') relocatable = state.get_option('pkgconfig.relocatable') self._generate_pkgconfig_file(state, deps, subdirs, name, description, url, diff --git a/mesonbuild/modules/python.py b/mesonbuild/modules/python.py index 881b54e4ca50..904dbf5b8724 100644 --- a/mesonbuild/modules/python.py +++ b/mesonbuild/modules/python.py @@ -116,7 +116,7 @@ class PythonInstallation(ProgramHolder['PythonExternalProgram']): def __init__(self, python: 'PythonExternalProgram', interpreter: 'Interpreter'): ProgramHolder.__init__(self, python, interpreter) info = python.info - prefix = self.interpreter.environment.coredata.optstore.get_value_for(OptionKey('prefix')) + prefix = self.interpreter.environment.coredata.optstore.get_value_for_untyped(OptionKey('prefix')) assert isinstance(prefix, str), 'for mypy' if python.build_config: @@ -178,7 +178,7 @@ def extension_module_method(self, args: T.Tuple[str, T.List[BuildTargetSource]], self.current_node) limited_api_version = kwargs.pop('limited_api') - allow_limited_api = self.interpreter.environment.coredata.optstore.get_value_for(OptionKey('python.allow_limited_api')) + allow_limited_api = self.interpreter.environment.coredata.optstore.get_value_for_untyped(OptionKey('python.allow_limited_api')) if limited_api_version != '' and allow_limited_api: target_suffix = self.limited_api_suffix @@ -217,7 +217,7 @@ def extension_module_method(self, args: T.Tuple[str, T.List[BuildTargetSource]], new_link_args = mesonlib.extract_as_list(kwargs, 'link_args') - is_debug = self.interpreter.environment.coredata.optstore.get_value_for('debug') + is_debug = self.interpreter.environment.coredata.optstore.get_value_for_untyped('debug') if is_debug: new_link_args.append(python_windows_debug_link_exception) else: @@ -266,7 +266,7 @@ def _dependency_method_impl(self, kwargs: DependencyObjectKWs) -> Dependency: if dep is not None: return dep - build_config = self.interpreter.environment.coredata.optstore.get_value_for(OptionKey('python.build_config')) + build_config = self.interpreter.environment.coredata.optstore.get_value_for_untyped(OptionKey('python.build_config')) new_kwargs = kwargs.copy() new_kwargs['required'] = False @@ -402,7 +402,7 @@ def __init__(self, interpreter: 'Interpreter') -> None: def _get_install_scripts(self) -> T.List[mesonlib.ExecutableSerialisation]: backend = self.interpreter.backend ret = [] - optlevel = self.interpreter.environment.coredata.optstore.get_value_for(OptionKey('python.bytecompile')) + optlevel = self.interpreter.environment.coredata.optstore.get_value_for_untyped(OptionKey('python.bytecompile')) if optlevel == -1: return ret if not any(PythonExternalProgram.run_bytecompile.values()): @@ -469,7 +469,7 @@ def _get_win_pythonpath(name_or_path: str) -> T.Optional[str]: return None def _find_installation_impl(self, state: 'ModuleState', display_name: str, name_or_path: str, required: bool) -> MaybePythonProg: - build_config = self.interpreter.environment.coredata.optstore.get_value_for(OptionKey('python.build_config')) + build_config = self.interpreter.environment.coredata.optstore.get_value_for_untyped(OptionKey('python.build_config')) if not name_or_path: python = PythonExternalProgram('python3', mesonlib.python_command, build_config_path=build_config) diff --git a/mesonbuild/modules/rust.py b/mesonbuild/modules/rust.py index 4873843c0d9c..bae404f86f1f 100644 --- a/mesonbuild/modules/rust.py +++ b/mesonbuild/modules/rust.py @@ -923,7 +923,7 @@ def bindgen(self, state: ModuleState, args: T.List, kwargs: FuncBindgen) -> Modu cmd.extend(['--rust-target', self._bindgen_rust_target]) if self._bindgen_set_std and '--rust-edition' not in cmd: try: - rust_std = state.environment.coredata.optstore.get_value_for('rust_std') + rust_std = state.environment.coredata.optstore.get_value_for_untyped('rust_std') except KeyError: rust_std = 'none' assert isinstance(rust_std, str), 'for mypy' diff --git a/mesonbuild/msetup.py b/mesonbuild/msetup.py index df06245a394c..3267376187f3 100644 --- a/mesonbuild/msetup.py +++ b/mesonbuild/msetup.py @@ -306,9 +306,9 @@ def _generate(self, env: environment.Environment, capture: bool, vslite_ctx: T.O # collect warnings about unsupported build configurations; must be done after full arg processing # by Interpreter() init, but this is most visible at the end - if env.coredata.optstore.get_value_for('backend') == 'xcode': + if env.coredata.optstore.get_value_for_untyped('backend') == 'xcode': mlog.warning('xcode backend is currently unmaintained, patches welcome') - if env.coredata.optstore.get_value_for('layout') == 'flat': + if env.coredata.optstore.get_value_for_untyped('layout') == 'flat': mlog.warning('-Dlayout=flat is unsupported and probably broken. It was a failed experiment at ' 'making Windows build artifacts runnable while uninstalled, due to PATH considerations, ' 'but was untested by CI and anyways breaks reasonable use of conflicting targets in different subdirs. ' diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py index aca4e23b41b3..89d7d71fb183 100644 --- a/mesonbuild/mtest.py +++ b/mesonbuild/mtest.py @@ -2296,11 +2296,11 @@ def run(options: argparse.Namespace) -> int: return 1 b = build.load(options.wd) - need_vsenv = T.cast('bool', b.environment.coredata.optstore.get_value_for(OptionKey('vsenv'))) + need_vsenv = T.cast('bool', b.environment.coredata.optstore.get_value_for_untyped(OptionKey('vsenv'))) setup_vsenv(need_vsenv) if not options.no_rebuild: - backend = b.environment.coredata.optstore.get_value_for(OptionKey('backend')) + backend = b.environment.coredata.optstore.get_value_for_untyped(OptionKey('backend')) if backend == 'none': # nothing to build... options.no_rebuild = True diff --git a/mesonbuild/munstable_coredata.py b/mesonbuild/munstable_coredata.py index b647dd8fcfb4..48fab0d6dc9d 100644 --- a/mesonbuild/munstable_coredata.py +++ b/mesonbuild/munstable_coredata.py @@ -53,7 +53,7 @@ def run(options): print('') coredata = cdata.load(options.builddir) - backend = coredata.optstore.get_value_for(OptionKey('backend')) + backend = coredata.optstore.get_value_for_untyped(OptionKey('backend')) for k, v in sorted(coredata.__dict__.items()): if k in {'backend_options', 'base_options', 'builtins', 'compiler_options', 'user_options'}: # use `meson configure` to view these diff --git a/mesonbuild/options.py b/mesonbuild/options.py index a96aa9514ac8..66174c3d1b5d 100644 --- a/mesonbuild/options.py +++ b/mesonbuild/options.py @@ -860,7 +860,7 @@ def resolve_option(self, key: 'T.Union[OptionKey, str]') -> AnyOptionType: return self.options[parent_key] return potential - def get_option_and_value_for(self, key: OptionKey) -> T.Tuple[AnyOptionType, ElementaryOptionValues]: + def get_option_and_value_for_untyped(self, key: OptionKey) -> T.Tuple[AnyOptionType, ElementaryOptionValues]: assert isinstance(key, OptionKey) key = self.ensure_and_validate_key(key) option_object = self.resolve_option(key) @@ -873,19 +873,19 @@ def get_option_and_value_for(self, key: OptionKey) -> T.Tuple[AnyOptionType, Ele return (option_object, computed_value) def option_has_value(self, key: OptionKey, value: ElementaryOptionValues) -> bool: - option_object, current_value = self.get_option_and_value_for(key) + option_object, current_value = self.get_option_and_value_for_untyped(key) return option_object.validate_value(value) == current_value - def get_value_for(self, name: 'T.Union[OptionKey, str]', subproject: T.Optional[str] = None) -> ElementaryOptionValues: + def get_value_for_untyped(self, name: 'T.Union[OptionKey, str]', subproject: T.Optional[str] = None) -> ElementaryOptionValues: if isinstance(name, str): key = OptionKey(name, subproject) else: assert subproject is None key = name - _, resolved_value = self.get_option_and_value_for(key) + _, resolved_value = self.get_option_and_value_for_untyped(key) return resolved_value - def get_option_for_target(self, target: 'BuildTarget', key: T.Union[str, OptionKey]) -> ElementaryOptionValues: + def get_option_for_target_untyped(self, target: 'BuildTarget', key: T.Union[str, OptionKey]) -> ElementaryOptionValues: if isinstance(key, str): assert ':' not in key newkey = OptionKey(key, target.subproject) @@ -898,7 +898,7 @@ def get_option_for_target(self, target: 'BuildTarget', key: T.Union[str, OptionK newkey = newkey.evolve(subproject=target.subproject) if self.is_cross: newkey = newkey.evolve(machine=target.for_machine) - option_object, value = self.get_option_and_value_for(newkey) + option_object, value = self.get_option_and_value_for_untyped(newkey) override = target.get_override(newkey.name) if override is not None: try: @@ -910,13 +910,13 @@ def get_option_for_target(self, target: 'BuildTarget', key: T.Union[str, OptionK def get_external_args(self, for_machine: MachineChoice, lang: Language) -> T.List[str]: # mypy cannot analyze type of OptionKey key = OptionKey(f'{lang}_args', machine=for_machine) - return T.cast('T.List[str]', self.get_value_for(key)) + return T.cast('T.List[str]', self.get_value_for_untyped(key)) @lru_cache(maxsize=None) def get_external_link_args(self, for_machine: MachineChoice, lang: Language) -> T.List[str]: # mypy cannot analyze type of OptionKey linkkey = OptionKey(f'{lang}_link_args', machine=for_machine) - return T.cast('T.List[str]', self.get_value_for(linkkey)) + return T.cast('T.List[str]', self.get_value_for_untyped(linkkey)) def add_system_option(self, key: T.Union[OptionKey, str], valobj: AnyOptionType) -> None: key = self.ensure_and_validate_key(key) @@ -1058,7 +1058,7 @@ def set_option(self, key: OptionKey, new_value: ElementaryOptionValues, first_in assert isinstance(new_value, str), 'for mypy' new_value = self.sanitize_prefix(new_value) elif self.is_builtin_option(key): - prefix = self.get_value_for('prefix') + prefix = self.get_value_for_untyped('prefix') assert isinstance(prefix, str), 'for mypy' new_value = self.sanitize_dir_option_value(prefix, key, new_value) diff --git a/mesonbuild/scripts/regen_checker.py b/mesonbuild/scripts/regen_checker.py index 9874607334e6..adbb442f568c 100644 --- a/mesonbuild/scripts/regen_checker.py +++ b/mesonbuild/scripts/regen_checker.py @@ -44,7 +44,7 @@ def run(args: T.List[str]) -> int: with open(coredata_file, 'rb') as f: coredata = pickle.load(f) assert isinstance(coredata, CoreData) - backend = coredata.optstore.get_value_for(OptionKey('backend')) + backend = coredata.optstore.get_value_for_untyped(OptionKey('backend')) assert isinstance(backend, str) regen_timestamp = os.stat(dumpfile).st_mtime if need_regen(regeninfo, regen_timestamp): diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py index 6cd197041139..404316f62dbd 100644 --- a/unittests/allplatformstests.py +++ b/unittests/allplatformstests.py @@ -2781,35 +2781,35 @@ def test_command_line(self): out = self.init(testdir, extra_args=['--profile-self', '--fatal-meson-warnings']) self.assertNotIn('[default: true]', out) obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for('default_library'), 'static') - self.assertEqual(obj.optstore.get_value_for('warning_level'), '1') - self.assertEqual(obj.optstore.get_value_for(OptionKey('set_sub_opt', '')), True) - self.assertEqual(obj.optstore.get_value_for(OptionKey('subp_opt', 'subp')), 'default3') + self.assertEqual(obj.optstore.get_value_for_untyped('default_library'), 'static') + self.assertEqual(obj.optstore.get_value_for_untyped('warning_level'), '1') + self.assertEqual(obj.optstore.get_value_for_untyped(OptionKey('set_sub_opt', '')), True) + self.assertEqual(obj.optstore.get_value_for_untyped(OptionKey('subp_opt', 'subp')), 'default3') self.wipe() # warning_level is special, it's --warnlevel instead of --warning-level # for historical reasons self.init(testdir, extra_args=['--warnlevel=2', '--fatal-meson-warnings']) obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for('warning_level'), '2') + self.assertEqual(obj.optstore.get_value_for_untyped('warning_level'), '2') self.setconf('--warnlevel=3') obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for('warning_level'), '3') + self.assertEqual(obj.optstore.get_value_for_untyped('warning_level'), '3') self.setconf('--warnlevel=everything') obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for('warning_level'), 'everything') + self.assertEqual(obj.optstore.get_value_for_untyped('warning_level'), 'everything') self.wipe() # But when using -D syntax, it should be 'warning_level' self.init(testdir, extra_args=['-Dwarning_level=2', '--fatal-meson-warnings']) obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for('warning_level'), '2') + self.assertEqual(obj.optstore.get_value_for_untyped('warning_level'), '2') self.setconf('-Dwarning_level=3') obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for('warning_level'), '3') + self.assertEqual(obj.optstore.get_value_for_untyped('warning_level'), '3') self.setconf('-Dwarning_level=everything') obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for('warning_level'), 'everything') + self.assertEqual(obj.optstore.get_value_for_untyped('warning_level'), 'everything') self.wipe() # Mixing --option and -Doption is forbidden @@ -2833,15 +2833,15 @@ def test_command_line(self): # --default-library should override default value from project() self.init(testdir, extra_args=['--default-library=both', '--fatal-meson-warnings']) obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for('default_library'), 'both') + self.assertEqual(obj.optstore.get_value_for_untyped('default_library'), 'both') self.setconf('--default-library=shared') obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for('default_library'), 'shared') + self.assertEqual(obj.optstore.get_value_for_untyped('default_library'), 'shared') if self.backend is Backend.ninja: # reconfigure target works only with ninja backend self.build('reconfigure') obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for('default_library'), 'shared') + self.assertEqual(obj.optstore.get_value_for_untyped('default_library'), 'shared') self.wipe() # Should fail on unknown options @@ -2878,22 +2878,22 @@ def test_command_line(self): # Test we can set subproject option self.init(testdir, extra_args=['-Dsubp:subp_opt=foo', '--fatal-meson-warnings']) obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for(OptionKey('subp_opt', 'subp')), 'foo') + self.assertEqual(obj.optstore.get_value_for_untyped(OptionKey('subp_opt', 'subp')), 'foo') self.wipe() # c_args value should be parsed with split_args self.init(testdir, extra_args=['-Dc_args=-Dfoo -Dbar "-Dthird=one two"', '--fatal-meson-warnings']) obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for(OptionKey('c_args')), ['-Dfoo', '-Dbar', '-Dthird=one two']) + self.assertEqual(obj.optstore.get_value_for_untyped(OptionKey('c_args')), ['-Dfoo', '-Dbar', '-Dthird=one two']) self.setconf('-Dc_args="foo bar" one two') obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for(OptionKey('c_args')), ['foo bar', 'one', 'two']) + self.assertEqual(obj.optstore.get_value_for_untyped(OptionKey('c_args')), ['foo bar', 'one', 'two']) self.wipe() self.init(testdir, extra_args=['-Dset_percent_opt=myoption%', '--fatal-meson-warnings']) obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for(OptionKey('set_percent_opt', '')), 'myoption%') + self.assertEqual(obj.optstore.get_value_for_untyped(OptionKey('set_percent_opt', '')), 'myoption%') self.wipe() # Setting a 2nd time the same option should override the first value @@ -2904,19 +2904,19 @@ def test_command_line(self): '-Dc_args=-Dfoo', '-Dc_args=-Dbar', '-Db_lundef=false', '--fatal-meson-warnings']) obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for('bindir'), 'bar') - self.assertEqual(obj.optstore.get_value_for('buildtype'), 'release') - self.assertEqual(obj.optstore.get_value_for('b_sanitize'), ['thread']) - self.assertEqual(obj.optstore.get_value_for(OptionKey('c_args')), ['-Dbar']) + self.assertEqual(obj.optstore.get_value_for_untyped('bindir'), 'bar') + self.assertEqual(obj.optstore.get_value_for_untyped('buildtype'), 'release') + self.assertEqual(obj.optstore.get_value_for_untyped('b_sanitize'), ['thread']) + self.assertEqual(obj.optstore.get_value_for_untyped(OptionKey('c_args')), ['-Dbar']) self.setconf(['--bindir=bar', '--bindir=foo', '-Dbuildtype=release', '-Dbuildtype=plain', '-Db_sanitize=thread', '-Db_sanitize=address', '-Dc_args=-Dbar', '-Dc_args=-Dfoo']) obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for('bindir'), 'foo') - self.assertEqual(obj.optstore.get_value_for('buildtype'), 'plain') - self.assertEqual(obj.optstore.get_value_for('b_sanitize'), ['address']) - self.assertEqual(obj.optstore.get_value_for(OptionKey('c_args')), ['-Dfoo']) + self.assertEqual(obj.optstore.get_value_for_untyped('bindir'), 'foo') + self.assertEqual(obj.optstore.get_value_for_untyped('buildtype'), 'plain') + self.assertEqual(obj.optstore.get_value_for_untyped('b_sanitize'), ['address']) + self.assertEqual(obj.optstore.get_value_for_untyped(OptionKey('c_args')), ['-Dfoo']) self.wipe() except KeyError: # Ignore KeyError, it happens on CI for compilers that does not @@ -2930,25 +2930,25 @@ def test_warning_level_0(self): # Verify default values when passing no args self.init(testdir) obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for('warning_level'), '0') + self.assertEqual(obj.optstore.get_value_for_untyped('warning_level'), '0') self.wipe() # verify we can override w/ --warnlevel self.init(testdir, extra_args=['--warnlevel=1']) obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for('warning_level'), '1') + self.assertEqual(obj.optstore.get_value_for_untyped('warning_level'), '1') self.setconf('--warnlevel=0') obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for('warning_level'), '0') + self.assertEqual(obj.optstore.get_value_for_untyped('warning_level'), '0') self.wipe() # verify we can override w/ -Dwarning_level self.init(testdir, extra_args=['-Dwarning_level=1']) obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for('warning_level'), '1') + self.assertEqual(obj.optstore.get_value_for_untyped('warning_level'), '1') self.setconf('-Dwarning_level=0') obj = mesonbuild.coredata.load(self.builddir) - self.assertEqual(obj.optstore.get_value_for('warning_level'), '0') + self.assertEqual(obj.optstore.get_value_for_untyped('warning_level'), '0') self.wipe() def test_feature_check_usage_subprojects(self): diff --git a/unittests/datatests.py b/unittests/datatests.py index e529e4e5b8fc..fc6f61ed0f89 100644 --- a/unittests/datatests.py +++ b/unittests/datatests.py @@ -168,9 +168,9 @@ def remove_module_name(key: OptionKey) -> OptionKey: else: raise RuntimeError(f'Invalid debug value {debug!r} in row:\n{m.group()}') env.coredata.optstore.set_option(OptionKey('buildtype'), buildtype) - self.assertEqual(env.coredata.optstore.get_value_for('buildtype'), buildtype) - self.assertEqual(env.coredata.optstore.get_value_for('optimization'), opt) - self.assertEqual(env.coredata.optstore.get_value_for('debug'), debug) + self.assertEqual(env.coredata.optstore.get_value_for_untyped('buildtype'), buildtype) + self.assertEqual(env.coredata.optstore.get_value_for_untyped('optimization'), opt) + self.assertEqual(env.coredata.optstore.get_value_for_untyped('debug'), debug) def test_cpu_families_documented(self): with open("docs/markdown/Reference-tables.md", encoding='utf-8') as f: diff --git a/unittests/linuxliketests.py b/unittests/linuxliketests.py index a79bd6d767ee..6e2b3c33a2d4 100644 --- a/unittests/linuxliketests.py +++ b/unittests/linuxliketests.py @@ -1179,7 +1179,7 @@ def test_pkgconfig_duplicate_path_entries(self): # option, adding the meson-uninstalled directory to it. PkgConfigInterface.setup_env({}, env, MachineChoice.HOST, uninstalled=True) - pkg_config_path = env.coredata.optstore.get_value_for('pkg_config_path') + pkg_config_path = env.coredata.optstore.get_value_for_untyped('pkg_config_path') self.assertEqual(pkg_config_path, [pkg_dir]) def test_pkgconfig_uninstalled_env_added(self): diff --git a/unittests/optiontests.py b/unittests/optiontests.py index 3af71b67c0c4..f3a9b8cae743 100644 --- a/unittests/optiontests.py +++ b/unittests/optiontests.py @@ -25,9 +25,9 @@ def test_basic(self): new_value = 'new_value' vo = UserStringOption(name, 'An option of some sort', default_value) optstore.add_system_option(name, vo) - self.assertEqual(optstore.get_value_for(name), default_value) + self.assertEqual(optstore.get_value_for_untyped(name), default_value) optstore.set_option(OptionKey.from_string(name), new_value) - self.assertEqual(optstore.get_value_for(name), new_value) + self.assertEqual(optstore.get_value_for_untyped(name), new_value) def test_toplevel_project(self): optstore = OptionStore(False) @@ -37,9 +37,9 @@ def test_toplevel_project(self): k = OptionKey(name) vo = UserStringOption(k.name, 'An option of some sort', default_value) optstore.add_system_option(k.name, vo) - self.assertEqual(optstore.get_value_for(k), default_value) + self.assertEqual(optstore.get_value_for_untyped(k), default_value) optstore.initialize_from_top_level_project_call({OptionKey('someoption'): new_value}, {}, {}) - self.assertEqual(optstore.get_value_for(k), new_value) + self.assertEqual(optstore.get_value_for_untyped(k), new_value) def test_machine_vs_project(self): optstore = OptionStore(False) @@ -52,10 +52,10 @@ def test_machine_vs_project(self): optstore.add_system_option('prefix', prefix) vo = UserStringOption(k.name, 'You know what this is', default_value) optstore.add_system_option(k.name, vo) - self.assertEqual(optstore.get_value_for(k), default_value) + self.assertEqual(optstore.get_value_for_untyped(k), default_value) optstore.initialize_from_top_level_project_call({OptionKey(name): proj_value}, {}, {OptionKey(name): mfile_value}) - self.assertEqual(optstore.get_value_for(k), mfile_value) + self.assertEqual(optstore.get_value_for_untyped(k), mfile_value) def test_subproject_system_option(self): """Test that subproject system options get their default value from the global @@ -69,7 +69,7 @@ def test_subproject_system_option(self): optstore.initialize_from_top_level_project_call({}, {}, {OptionKey(name): new_value}) vo = UserStringOption(k.name, 'An option of some sort', default_value) optstore.add_system_option(subk, vo) - self.assertEqual(optstore.get_value_for(subk), new_value) + self.assertEqual(optstore.get_value_for_untyped(subk), new_value) def test_parsing(self): with self.subTest('subproject'): @@ -96,7 +96,7 @@ def test_subproject_for_system(self): default_value = 'somevalue' vo = UserStringOption(name, 'An option of some sort', default_value) optstore.add_system_option(name, vo) - self.assertEqual(optstore.get_value_for(name, 'somesubproject'), default_value) + self.assertEqual(optstore.get_value_for_untyped(name, 'somesubproject'), default_value) def test_reset(self): optstore = OptionStore(False) @@ -105,11 +105,11 @@ def test_reset(self): reset_value = 'reset' vo = UserStringOption(name, 'An option set twice', original_value) optstore.add_system_option(name, vo) - self.assertEqual(optstore.get_value_for(name), original_value) + self.assertEqual(optstore.get_value_for_untyped(name), original_value) self.assertEqual(num_options(optstore), 1) vo2 = UserStringOption(name, 'An option set twice', reset_value) optstore.add_system_option(name, vo2) - self.assertEqual(optstore.get_value_for(name), original_value) + self.assertEqual(optstore.get_value_for_untyped(name), original_value) self.assertEqual(num_options(optstore), 1) def test_project_nonyielding(self): @@ -119,12 +119,12 @@ def test_project_nonyielding(self): sub_value = 'sub' vo = UserStringOption(name, 'A top level option', top_value, False) optstore.add_project_option(OptionKey(name, ''), vo) - self.assertEqual(optstore.get_value_for(name, ''), top_value, False) + self.assertEqual(optstore.get_value_for_untyped(name, ''), top_value, False) self.assertEqual(num_options(optstore), 1) vo2 = UserStringOption(name, 'A subproject option', sub_value) optstore.add_project_option(OptionKey(name, 'sub'), vo2) - self.assertEqual(optstore.get_value_for(name, ''), top_value) - self.assertEqual(optstore.get_value_for(name, 'sub'), sub_value) + self.assertEqual(optstore.get_value_for_untyped(name, ''), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, 'sub'), sub_value) self.assertEqual(num_options(optstore), 2) def test_toplevel_project_yielding(self): @@ -133,7 +133,7 @@ def test_toplevel_project_yielding(self): top_value = 'top' vo = UserStringOption(name, 'A top level option', top_value, True) optstore.add_project_option(OptionKey(name, ''), vo) - self.assertEqual(optstore.get_value_for(name, ''), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, ''), top_value) def test_project_yielding(self): optstore = OptionStore(False) @@ -142,12 +142,12 @@ def test_project_yielding(self): sub_value = 'sub' vo = UserStringOption(name, 'A top level option', top_value) optstore.add_project_option(OptionKey(name, ''), vo) - self.assertEqual(optstore.get_value_for(name, ''), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, ''), top_value) self.assertEqual(num_options(optstore), 1) vo2 = UserStringOption(name, 'A subproject option', sub_value, True) optstore.add_project_option(OptionKey(name, 'sub'), vo2) - self.assertEqual(optstore.get_value_for(name, ''), top_value) - self.assertEqual(optstore.get_value_for(name, 'sub'), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, ''), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, 'sub'), top_value) self.assertEqual(num_options(optstore), 2) def test_project_yielding_not_defined_in_top_project(self): @@ -158,12 +158,12 @@ def test_project_yielding_not_defined_in_top_project(self): sub_value = 'sub' vo = UserStringOption(top_name, 'A top level option', top_value) optstore.add_project_option(OptionKey(top_name, ''), vo) - self.assertEqual(optstore.get_value_for(top_name, ''), top_value) + self.assertEqual(optstore.get_value_for_untyped(top_name, ''), top_value) self.assertEqual(num_options(optstore), 1) vo2 = UserStringOption(sub_name, 'A subproject option', sub_value, True) optstore.add_project_option(OptionKey(sub_name, 'sub'), vo2) - self.assertEqual(optstore.get_value_for(top_name, ''), top_value) - self.assertEqual(optstore.get_value_for(sub_name, 'sub'), sub_value) + self.assertEqual(optstore.get_value_for_untyped(top_name, ''), top_value) + self.assertEqual(optstore.get_value_for_untyped(sub_name, 'sub'), sub_value) self.assertEqual(num_options(optstore), 2) def test_project_yielding_initialize(self): @@ -177,18 +177,18 @@ def test_project_yielding_initialize(self): vo = UserStringOption(name, 'A top level option', 'default1') optstore.add_project_option(OptionKey(name, ''), vo) optstore.initialize_from_top_level_project_call({}, cmd_line, {}) - self.assertEqual(optstore.get_value_for(name, ''), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, ''), top_value) self.assertEqual(num_options(optstore), 1) vo2 = UserStringOption(name, 'A subproject option', 'default2', True) optstore.add_project_option(OptionKey(name, 'subp'), vo2) - self.assertEqual(optstore.get_value_for(name, ''), top_value) - self.assertEqual(optstore.get_value_for(name, subp), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, ''), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, subp), top_value) self.assertEqual(num_options(optstore), 2) optstore.initialize_from_subproject_call(subp, {}, {}, cmd_line, {}) - self.assertEqual(optstore.get_value_for(name, ''), top_value) - self.assertEqual(optstore.get_value_for(name, subp), sub_value) + self.assertEqual(optstore.get_value_for_untyped(name, ''), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, subp), sub_value) def test_augments(self): optstore = OptionStore(False) @@ -203,34 +203,34 @@ def test_augments(self): top_value, choices=['c++98', 'c++11', 'c++14', 'c++17', 'c++20', 'c++23']) optstore.add_system_option(name, co) - self.assertEqual(optstore.get_value_for(name), top_value) - self.assertEqual(optstore.get_value_for(name, sub_name), top_value) - self.assertEqual(optstore.get_value_for(name, sub2_name), top_value) + self.assertEqual(optstore.get_value_for_untyped(name), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, sub_name), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, sub2_name), top_value) # First augment a subproject with self.subTest('set subproject override'): optstore.set_from_configure_command({OptionKey.from_string(f'{sub_name}:{name}'): aug_value}) - self.assertEqual(optstore.get_value_for(name), top_value) - self.assertEqual(optstore.get_value_for(name, sub_name), aug_value) - self.assertEqual(optstore.get_value_for(name, sub2_name), top_value) + self.assertEqual(optstore.get_value_for_untyped(name), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, sub_name), aug_value) + self.assertEqual(optstore.get_value_for_untyped(name, sub2_name), top_value) with self.subTest('unset subproject override'): optstore.set_from_configure_command({OptionKey.from_string(f'{sub_name}:{name}'): None}) - self.assertEqual(optstore.get_value_for(name), top_value) - self.assertEqual(optstore.get_value_for(name, sub_name), top_value) - self.assertEqual(optstore.get_value_for(name, sub2_name), top_value) + self.assertEqual(optstore.get_value_for_untyped(name), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, sub_name), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, sub2_name), top_value) # And now augment the top level option optstore.set_from_configure_command({OptionKey.from_string(f':{name}'): aug_value}) - self.assertEqual(optstore.get_value_for(name, None), top_value) - self.assertEqual(optstore.get_value_for(name, ''), aug_value) - self.assertEqual(optstore.get_value_for(name, sub_name), top_value) - self.assertEqual(optstore.get_value_for(name, sub2_name), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, None), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, ''), aug_value) + self.assertEqual(optstore.get_value_for_untyped(name, sub_name), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, sub2_name), top_value) optstore.set_from_configure_command({OptionKey.from_string(f':{name}'): None}) - self.assertEqual(optstore.get_value_for(name), top_value) - self.assertEqual(optstore.get_value_for(name, sub_name), top_value) - self.assertEqual(optstore.get_value_for(name, sub2_name), top_value) + self.assertEqual(optstore.get_value_for_untyped(name), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, sub_name), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, sub2_name), top_value) def test_augment_set_sub(self): optstore = OptionStore(False) @@ -249,8 +249,8 @@ def test_augment_set_sub(self): optstore.add_system_option(name, co) optstore.set_from_configure_command({OptionKey.from_string(f'{sub_name}:{name}'): aug_value}) optstore.set_from_configure_command({OptionKey.from_string(f'{sub_name}:{name}'): set_value}) - self.assertEqual(optstore.get_value_for(name), top_value) - self.assertEqual(optstore.get_value_for(name, sub_name), set_value) + self.assertEqual(optstore.get_value_for_untyped(name), top_value) + self.assertEqual(optstore.get_value_for_untyped(name, sub_name), set_value) def test_build_to_host(self): key = OptionKey('cpp_std') @@ -266,8 +266,8 @@ def test_build_to_host(self): cmd_line = {key: opt_value} optstore.initialize_from_top_level_project_call({}, cmd_line, {}) - self.assertEqual(optstore.get_option_and_value_for(key.as_build())[1], opt_value) - self.assertEqual(optstore.get_value_for(key.as_build()), opt_value) + self.assertEqual(optstore.get_option_and_value_for_untyped(key.as_build())[1], opt_value) + self.assertEqual(optstore.get_value_for_untyped(key.as_build()), opt_value) def test_build_to_host_subproject(self): key = OptionKey('cpp_std') @@ -285,9 +285,9 @@ def test_build_to_host_subproject(self): spcall = {key: opt_value} optstore.initialize_from_top_level_project_call({}, {}, {}) optstore.initialize_from_subproject_call(subp, spcall, {}, {}, {}) - self.assertEqual(optstore.get_option_and_value_for(key.evolve(subproject=subp, + self.assertEqual(optstore.get_option_and_value_for_untyped(key.evolve(subproject=subp, machine=MachineChoice.BUILD))[1], opt_value) - self.assertEqual(optstore.get_value_for(key.evolve(subproject=subp, + self.assertEqual(optstore.get_value_for_untyped(key.evolve(subproject=subp, machine=MachineChoice.BUILD)), opt_value) def test_build_to_host_cross(self): @@ -307,10 +307,10 @@ def test_build_to_host_cross(self): optstore.initialize_from_top_level_project_call({}, cmd_line, {}) print(optstore.options) - self.assertEqual(optstore.get_option_and_value_for(key)[1], opt_value) - self.assertEqual(optstore.get_option_and_value_for(key.as_build())[1], def_value) - self.assertEqual(optstore.get_value_for(key), opt_value) - self.assertEqual(optstore.get_value_for(key.as_build()), def_value) + self.assertEqual(optstore.get_option_and_value_for_untyped(key)[1], opt_value) + self.assertEqual(optstore.get_option_and_value_for_untyped(key.as_build())[1], def_value) + self.assertEqual(optstore.get_value_for_untyped(key), opt_value) + self.assertEqual(optstore.get_value_for_untyped(key.as_build()), def_value) def test_b_nonexistent(self): optstore = OptionStore(False) @@ -349,8 +349,8 @@ def test_subproject_proj_opt_with_same_name(self): optstore.initialize_from_top_level_project_call({}, cmd_line, {}) optstore.initialize_from_subproject_call(subp, spcall, {}, cmd_line, {}) - self.assertEqual(optstore.get_value_for(name, ''), True) - self.assertEqual(optstore.get_value_for(name, subp), False) + self.assertEqual(optstore.get_value_for_untyped(name, ''), True) + self.assertEqual(optstore.get_value_for_untyped(name, subp), False) def test_subproject_cmdline_override_global(self): name = 'optimization' @@ -369,8 +369,8 @@ def test_subproject_cmdline_override_global(self): optstore.initialize_from_top_level_project_call(toplevel_proj_default, cmd_line, {}) optstore.initialize_from_subproject_call(subp, {}, subp_proj_default, cmd_line, {}) - self.assertEqual(optstore.get_value_for(name, subp), new_value) - self.assertEqual(optstore.get_value_for(name), new_value) + self.assertEqual(optstore.get_value_for_untyped(name, subp), new_value) + self.assertEqual(optstore.get_value_for_untyped(name), new_value) def test_subproject_parent_override_subp(self): name = 'optimization' @@ -389,8 +389,8 @@ def test_subproject_parent_override_subp(self): optstore.initialize_from_top_level_project_call(toplevel_proj_default, {}, {}) optstore.initialize_from_subproject_call(subp, {}, subp_proj_default, {}, {}) - self.assertEqual(optstore.get_value_for(name, subp), subp_value) - self.assertEqual(optstore.get_value_for(name), default_value) + self.assertEqual(optstore.get_value_for_untyped(name, subp), subp_value) + self.assertEqual(optstore.get_value_for_untyped(name), default_value) def test_subproject_cmdline_override_global_and_augment(self): name = 'optimization' @@ -410,8 +410,8 @@ def test_subproject_cmdline_override_global_and_augment(self): optstore.initialize_from_top_level_project_call(toplevel_proj_default, cmd_line, {}) optstore.initialize_from_subproject_call(subp, {}, subp_proj_default, cmd_line, {}) - self.assertEqual(optstore.get_value_for(name, subp), new_value) - self.assertEqual(optstore.get_value_for(name), global_value) + self.assertEqual(optstore.get_value_for_untyped(name, subp), new_value) + self.assertEqual(optstore.get_value_for_untyped(name), global_value) def test_subproject_cmdline_override_toplevel(self): name = 'default_library' @@ -431,8 +431,8 @@ def test_subproject_cmdline_override_toplevel(self): optstore.initialize_from_top_level_project_call(toplevel_proj_default, cmd_line, {}) optstore.initialize_from_subproject_call(subp, {}, subp_proj_default, cmd_line, {}) - self.assertEqual(optstore.get_value_for(name, subp), subp_value) - self.assertEqual(optstore.get_value_for(name, ''), toplevel_value) + self.assertEqual(optstore.get_value_for_untyped(name, subp), subp_value) + self.assertEqual(optstore.get_value_for_untyped(name, ''), toplevel_value) def test_subproject_buildtype(self): subp = 'subp' @@ -456,9 +456,9 @@ def test_subproject_buildtype(self): optstore.initialize_from_top_level_project_call(mainopt, {}, {}) optstore.initialize_from_subproject_call(subp, {}, subopt, {}, {}) - self.assertEqual(optstore.get_value_for('buildtype', subp), 'debug') - self.assertEqual(optstore.get_value_for('optimization', subp), '0') - self.assertEqual(optstore.get_value_for('debug', subp), True) + self.assertEqual(optstore.get_value_for_untyped('buildtype', subp), 'debug') + self.assertEqual(optstore.get_value_for_untyped('optimization', subp), '0') + self.assertEqual(optstore.get_value_for_untyped('debug', subp), True) def test_deprecated_nonstring_value(self): # TODO: add a lot more deprecated option tests @@ -468,7 +468,7 @@ def test_deprecated_nonstring_value(self): deprecated={'true': '1'}) optstore.add_system_option(name, do) optstore.set_option(OptionKey(name), True) - value = optstore.get_value_for(name) + value = optstore.get_value_for_untyped(name) self.assertEqual(value, '1') def test_pending_augment_validation(self): @@ -485,7 +485,7 @@ def test_pending_augment_validation(self): bo = UserBooleanOption(name, 'LTO', False) key = OptionKey(name, subproject=subproject) optstore.add_system_option(key, bo) - stored_value = optstore.get_value_for(key) + stored_value = optstore.get_value_for_untyped(key) self.assertIsInstance(stored_value, bool) self.assertTrue(stored_value) @@ -513,7 +513,7 @@ def test_machine_canonicalization_cross(self): build_option_obj = UserStringArrayOption('pkg_config_path', 'Build pkg-config paths', ['/usr/lib64/pkgconfig']) optstore.add_system_option(host_pkg_config, host_option_obj) optstore.add_system_option(build_pkg_config, build_option_obj) - option, value = optstore.get_option_and_value_for(build_pkg_config) + option, value = optstore.get_option_and_value_for_untyped(build_pkg_config) self.assertEqual(value, ['/usr/lib64/pkgconfig']) # Test that non-per-machine BUILD option IS canonicalized to HOST @@ -522,7 +522,7 @@ def test_machine_canonicalization_cross(self): common_option_obj = UserComboOption('optimization', 'Optimization level', '0', choices=['plain', '0', 'g', '1', '2', '3', 's']) optstore.add_system_option(host_opt, common_option_obj) - self.assertEqual(optstore.get_value_for(build_opt), '0') + self.assertEqual(optstore.get_value_for_untyped(build_opt), '0') def test_machine_canonicalization_native(self): """Test that BUILD machine options are canonicalized to HOST when not cross compiling.""" @@ -535,12 +535,12 @@ def test_machine_canonicalization_native(self): # Add per-machine option for HOST only (BUILD will be canonicalized) optstore.add_system_option(host_pkg_config, host_option_obj) - option, value = optstore.get_option_and_value_for(build_pkg_config) + option, value = optstore.get_option_and_value_for_untyped(build_pkg_config) self.assertEqual(value, ['/mingw/lib64/pkgconfig']) # Try again adding build option too, for completeness optstore.add_system_option(build_pkg_config, build_option_obj) - option, value = optstore.get_option_and_value_for(build_pkg_config) + option, value = optstore.get_option_and_value_for_untyped(build_pkg_config) self.assertEqual(value, ['/mingw/lib64/pkgconfig']) def test_sanitize_prefix_windows_host(self): @@ -593,7 +593,7 @@ def test_sanitize_dir_option_cross_to_windows(self): # Set libdir to absolute path inside prefix, should be relativized optstore.set_option(OptionKey('prefix'), 'C:\\Program Files\\MyProg') optstore.set_option(OptionKey('libdir'), 'C:\\Program Files\\MyProg\\lib') - self.assertEqual(optstore.get_value_for('libdir'), 'lib') + self.assertEqual(optstore.get_value_for_untyped('libdir'), 'lib') def test_sanitize_dir_option_cross_to_linux(self): """Test directory option sanitization when cross-compiling to Linux.""" @@ -603,7 +603,7 @@ def test_sanitize_dir_option_cross_to_linux(self): # Set libdir to absolute path inside prefix, should be relativized optstore.set_option(OptionKey('prefix'), '/opt/myapp') optstore.set_option(OptionKey('libdir'), '/opt/myapp/lib64') - self.assertEqual(optstore.get_value_for('libdir'), 'lib64') + self.assertEqual(optstore.get_value_for_untyped('libdir'), 'lib64') def test_sanitize_prefix_native_path(self): """Test that native paths are accepted without set_host_machine().""" From c96cef4a3594be8f865c33465e028041b1f3c36f Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 11 Mar 2026 10:49:46 -0700 Subject: [PATCH 10/22] options: Add type safe getters for option values These use a TypeVar to constrain the type, and then do a runtime check to ensure that the option is of the correct type. One has not been added for `get_option_and_value_for` because we need to further constrain the types via overloads, but I can't figure out how to make the type checker happy with it. --- mesonbuild/options.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/mesonbuild/options.py b/mesonbuild/options.py index 66174c3d1b5d..419b46200c33 100644 --- a/mesonbuild/options.py +++ b/mesonbuild/options.py @@ -47,6 +47,7 @@ 'UserIntegerOption', 'UserStdOption', 'UserStringArrayOption', 'UserStringOption', 'UserUmaskOption'] ElementaryOptionValues: TypeAlias = T.Union[str, int, bool, T.List[str]] + ElementaryOptionType = T.TypeVar('ElementaryOptionType', str, int, bool, T.List[str]) MutableKeyedOptionDictType: TypeAlias = T.Dict['OptionKey', AnyOptionType] _OptionKeyTuple: TypeAlias = T.Tuple[T.Optional[str], MachineChoice, str] @@ -885,6 +886,12 @@ def get_value_for_untyped(self, name: 'T.Union[OptionKey, str]', subproject: T.O _, resolved_value = self.get_option_and_value_for_untyped(key) return resolved_value + def get_value_for(self, key: OptionKey, type_: T.Type[ElementaryOptionType]) -> ElementaryOptionType: + val = self.get_value_for_untyped(key) + if not isinstance(val, type_): + raise MesonBugException(f'Expected {key!s} to have type {type_!s}, but had type {type(val)!s}') + return val + def get_option_for_target_untyped(self, target: 'BuildTarget', key: T.Union[str, OptionKey]) -> ElementaryOptionValues: if isinstance(key, str): assert ':' not in key @@ -907,16 +914,20 @@ def get_option_for_target_untyped(self, target: 'BuildTarget', key: T.Union[str, raise MesonException(f'In override_options for {target}: {e!s}') return value + def get_option_for_target(self, target: 'BuildTarget', key: OptionKey, type_: T.Type[ElementaryOptionType]) -> ElementaryOptionType: + val = self.get_option_for_target_untyped(target, key) + if not isinstance(val, type_): + raise MesonBugException(f'Expected {key!s} to have type {type_!s}, but had type {type(val)!s}') + return val + def get_external_args(self, for_machine: MachineChoice, lang: Language) -> T.List[str]: - # mypy cannot analyze type of OptionKey key = OptionKey(f'{lang}_args', machine=for_machine) - return T.cast('T.List[str]', self.get_value_for_untyped(key)) + return self.get_value_for(key, list) @lru_cache(maxsize=None) def get_external_link_args(self, for_machine: MachineChoice, lang: Language) -> T.List[str]: - # mypy cannot analyze type of OptionKey linkkey = OptionKey(f'{lang}_link_args', machine=for_machine) - return T.cast('T.List[str]', self.get_value_for_untyped(linkkey)) + return self.get_value_for(linkkey, list) def add_system_option(self, key: T.Union[OptionKey, str], valobj: AnyOptionType) -> None: key = self.ensure_and_validate_key(key) From 7b8b692db4db4db270c8b99d88076518e9a1add7 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 11 Mar 2026 11:18:29 -0700 Subject: [PATCH 11/22] Options: Add default value for safe getters This allows use to replace patterns like: ```python if key in opstore and opstore.get_value_for(...) ``` with ```python if opstore.get_value_for(..., default=...) ``` --- mesonbuild/options.py | 21 +++++++++++++++++---- unittests/optiontests.py | 8 ++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/mesonbuild/options.py b/mesonbuild/options.py index 419b46200c33..574cb262ef6d 100644 --- a/mesonbuild/options.py +++ b/mesonbuild/options.py @@ -886,8 +886,14 @@ def get_value_for_untyped(self, name: 'T.Union[OptionKey, str]', subproject: T.O _, resolved_value = self.get_option_and_value_for_untyped(key) return resolved_value - def get_value_for(self, key: OptionKey, type_: T.Type[ElementaryOptionType]) -> ElementaryOptionType: - val = self.get_value_for_untyped(key) + def get_value_for(self, key: OptionKey, type_: T.Type[ElementaryOptionType], + *, default: T.Optional[ElementaryOptionType] = None) -> ElementaryOptionType: + try: + val = self.get_value_for_untyped(key) + except KeyError: + if default is not None: + return default + raise if not isinstance(val, type_): raise MesonBugException(f'Expected {key!s} to have type {type_!s}, but had type {type(val)!s}') return val @@ -914,8 +920,15 @@ def get_option_for_target_untyped(self, target: 'BuildTarget', key: T.Union[str, raise MesonException(f'In override_options for {target}: {e!s}') return value - def get_option_for_target(self, target: 'BuildTarget', key: OptionKey, type_: T.Type[ElementaryOptionType]) -> ElementaryOptionType: - val = self.get_option_for_target_untyped(target, key) + def get_option_for_target(self, target: 'BuildTarget', key: OptionKey, + type_: T.Type[ElementaryOptionType], + *, default: T.Optional[ElementaryOptionType] = None) -> ElementaryOptionType: + try: + val = self.get_option_for_target_untyped(target, key) + except KeyError: + if default is not None: + return default + raise if not isinstance(val, type_): raise MesonBugException(f'Expected {key!s} to have type {type_!s}, but had type {type(val)!s}') return val diff --git a/unittests/optiontests.py b/unittests/optiontests.py index f3a9b8cae743..a1e508254601 100644 --- a/unittests/optiontests.py +++ b/unittests/optiontests.py @@ -3,7 +3,9 @@ from mesonbuild.options import * from mesonbuild.envconfig import MachineInfo +from mesonbuild.build import BuildTarget +from unittest import mock import os import unittest @@ -639,3 +641,9 @@ def test_is_host_absolute(self): optstore = OptionStore(False) self.assertTrue(optstore._is_host_absolute(os.sep + 'myprog')) self.assertTrue(optstore._is_host_absolute('/myprog')) + + def test_get_value_default(self) -> None: + optstore = OptionStore(False) + self.assertTrue(optstore.get_value_for(OptionKey('nonexistent'), bool, default=True)) + target = mock.Mock(spec=BuildTarget, subproject='') + self.assertTrue(optstore.get_option_for_target(target, OptionKey('nonexistent'), bool, default=True)) From 1d8fcc9bb14faa170fb3fcb18036526fc745df04 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 11 Mar 2026 10:54:05 -0700 Subject: [PATCH 12/22] make use of type safe get_value_for This replaces most of the uses of the unsafe get_value_for, with a couple of exceptions: - There is code in the Compiler that does some interesting BuildTarget | None checking that should be wrapped - the `install_umask` option cannot use this helper due to it's variant type - There's a wrapper in the Module code that needs to be replaced --- mesonbuild/ast/introspection.py | 2 +- mesonbuild/backend/backends.py | 10 ++--- mesonbuild/backend/ninjabackend.py | 22 +++++------ mesonbuild/backend/vs2010backend.py | 25 ++++++------- mesonbuild/backend/xcodebackend.py | 4 +- mesonbuild/build.py | 15 ++++---- mesonbuild/cmake/common.py | 13 +++---- mesonbuild/cmake/executor.py | 5 +-- mesonbuild/cmake/interpreter.py | 6 +-- mesonbuild/compilers/asm.py | 2 +- mesonbuild/compilers/compilers.py | 10 ++--- mesonbuild/compilers/detect.py | 2 +- mesonbuild/compilers/mixins/clike.py | 4 +- mesonbuild/compilers/mixins/emscripten.py | 4 +- mesonbuild/compilers/mixins/gnu.py | 2 +- mesonbuild/coredata.py | 14 +++---- mesonbuild/dependencies/base.py | 2 +- mesonbuild/dependencies/boost.py | 9 ++--- mesonbuild/dependencies/dub.py | 2 +- mesonbuild/dependencies/misc.py | 2 +- mesonbuild/dependencies/mpi.py | 4 +- mesonbuild/dependencies/pkgconfig.py | 7 ++-- mesonbuild/dependencies/python.py | 13 +++---- mesonbuild/dependencies/qt.py | 9 ++--- mesonbuild/dependencies/scalapack.py | 4 +- mesonbuild/environment.py | 19 ++++------ mesonbuild/interpreter/compiler.py | 2 +- mesonbuild/interpreter/dependencyfallbacks.py | 6 +-- mesonbuild/interpreter/interpreter.py | 37 +++++++++---------- mesonbuild/interpreter/mesonmain.py | 5 +-- mesonbuild/linkers/detect.py | 2 +- mesonbuild/mcompile.py | 5 +-- mesonbuild/mdevenv.py | 8 ++-- mesonbuild/mdist.py | 2 +- mesonbuild/minit.py | 2 +- mesonbuild/minstall.py | 4 +- mesonbuild/mintro.py | 2 +- mesonbuild/modules/__init__.py | 1 + mesonbuild/modules/cmake.py | 9 ++--- mesonbuild/modules/external_project.py | 16 ++------ mesonbuild/modules/gnome.py | 17 +++------ mesonbuild/modules/hotdoc.py | 2 +- mesonbuild/modules/i18n.py | 3 +- mesonbuild/modules/pkgconfig.py | 15 +++----- mesonbuild/modules/python.py | 13 +++---- mesonbuild/modules/rust.py | 7 +--- mesonbuild/msetup.py | 4 +- mesonbuild/mtest.py | 4 +- mesonbuild/munstable_coredata.py | 2 +- mesonbuild/options.py | 3 +- mesonbuild/scripts/regen_checker.py | 3 +- 51 files changed, 162 insertions(+), 223 deletions(-) diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py index c6066476eb31..dc231fec0190 100644 --- a/mesonbuild/ast/introspection.py +++ b/mesonbuild/ast/introspection.py @@ -283,7 +283,7 @@ def build_target(self, node: BaseNode, args: T.List[TYPE_var], kwargs_raw: T.Dic return new_target def build_library(self, node: BaseNode, args: T.List[TYPE_var], kwargs: T.Dict[str, TYPE_var]) -> T.Union[IntrospectionBuildTarget, UnknownValue]: - default_library = self.coredata.optstore.get_value_for_untyped(OptionKey('default_library', subproject=self.subproject)) + default_library = self.coredata.optstore.get_value_for(OptionKey('default_library', subproject=self.subproject), str) if default_library == 'shared': return self.build_target(node, args, kwargs, SharedLibrary) elif default_library == 'static': diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 65ad6ca913d9..d035efea2bb1 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -379,7 +379,7 @@ def get_target_dir(self, target: build.AnyTargetType) -> str: if isinstance(target, build.RunTarget): # this produces no output, only a dummy top-level name dirname = '' - elif self.environment.coredata.optstore.get_value_for_untyped(OptionKey('layout')) == 'mirror': + elif self.environment.coredata.optstore.get_value_for(OptionKey('layout'), str) == 'mirror': dirname = target.get_builddir() else: dirname = 'meson-out' @@ -1298,8 +1298,7 @@ def construct_target_rel_paths(self, t: build.AnyTargetType, workdir: T.Optional def generate_depmf_install(self, d: InstallData) -> None: depmf_path = self.build.dep_manifest_name if depmf_path is None: - option_dir = self.environment.coredata.optstore.get_value_for_untyped(OptionKey('licensedir')) - assert isinstance(option_dir, str), 'for mypy' + option_dir = self.environment.coredata.optstore.get_value_for(OptionKey('licensedir'), str) if option_dir: depmf_path = os.path.join(option_dir, 'depmf.json') else: @@ -1649,6 +1648,7 @@ def create_install_data(self) -> InstallData: # TODO go through all candidates, like others strip_bin = [detect.defaults['strip'][0]] + # Cannot used typed getter because of union type umask = self.environment.coredata.optstore.get_value_for_untyped(OptionKey('install_umask')) assert isinstance(umask, (str, int)), 'for mypy' @@ -1681,9 +1681,7 @@ def guess_install_tag(self, fname: str, outdir: T.Optional[str] = None) -> T.Opt bindir = Path(prefix, self.environment.get_bindir()) libdir = Path(prefix, self.environment.get_libdir()) incdir = Path(prefix, self.environment.get_includedir()) - _ldir = self.environment.coredata.optstore.get_value_for_untyped(OptionKey('localedir')) - assert isinstance(_ldir, str), 'for mypy' - localedir = Path(prefix, _ldir) + localedir = Path(prefix, self.environment.coredata.optstore.get_value_for(OptionKey('localedir'), str)) dest_path = Path(prefix, outdir, Path(fname).name) if outdir else Path(prefix, fname) if bindir in dest_path.parents: return 'runtime' diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index aa95625c3bc0..27d737d63af2 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -612,7 +612,7 @@ def generate(self, capture: bool = False, vslite_ctx: T.Optional[T.Dict] = None) self.allow_thin_archives[for_machine] = False ninja = tooldetect.detect_ninja_command_and_version(log=True) - if self.environment.coredata.optstore.get_value_for_untyped(OptionKey('vsenv')): + if self.environment.coredata.optstore.get_value_for(OptionKey('vsenv'), bool): builddir = Path(self.environment.get_build_dir()) try: # For prettier printing, reduce to a relative path. If @@ -637,7 +637,7 @@ def generate(self, capture: bool = False, vslite_ctx: T.Optional[T.Dict] = None) outfile.write('# Do not edit by hand.\n\n') outfile.write('ninja_required_version = 1.8.2\n\n') - num_pools = self.environment.coredata.optstore.get_value_for_untyped('backend_max_links') + num_pools = self.environment.coredata.optstore.get_value_for(OptionKey('backend_max_links'), int) if num_pools > 0: outfile.write(f'''pool link_pool depth = {num_pools} @@ -669,9 +669,7 @@ def generate(self, capture: bool = False, vslite_ctx: T.Optional[T.Dict] = None) mlog.log_timestamp("Install generated") self.generate_dist() mlog.log_timestamp("Dist generated") - key = OptionKey('b_coverage') - if key in self.environment.coredata.optstore and\ - self.environment.coredata.optstore.get_value_for_untyped('b_coverage'): + if self.environment.coredata.optstore.get_value_for(OptionKey('b_coverage'), bool, default=False): gcovr_exe, gcovr_version, lcov_exe, lcov_version, genhtml_exe, llvm_cov_exe = tooldetect.find_coverage_tools(self.environment.coredata) mlog.debug(f'Using {gcovr_exe} ({gcovr_version}), {lcov_exe} and {llvm_cov_exe} for code coverage') if gcovr_exe or (lcov_exe and genhtml_exe): @@ -1375,9 +1373,9 @@ def generate_install(self) -> None: def generate_tests(self) -> None: self.serialize_tests() cmd = self.environment.get_build_command(True) + ['test', '--no-rebuild'] - if not self.environment.coredata.optstore.get_value_for_untyped(OptionKey('stdsplit')): + if not self.environment.coredata.optstore.get_value_for(OptionKey('stdsplit'), bool): cmd += ['--no-stdsplit'] - if self.environment.coredata.optstore.get_value_for_untyped(OptionKey('errorlogs')): + if self.environment.coredata.optstore.get_value_for(OptionKey('errorlogs'), bool): cmd += ['--print-errorlogs'] elem = self.create_phony_target('test', 'CUSTOM_COMMAND', ['all', 'meson-test-prereq', 'PHONY']) elem.add_item('COMMAND', cmd) @@ -2438,7 +2436,7 @@ def _rsp_options(self, tool: T.Union['Compiler', 'StaticLinker', 'DynamicLinker' return options def generate_static_link_rules(self) -> None: - num_pools = self.environment.coredata.optstore.get_value_for_untyped('backend_max_links') + num_pools = self.environment.coredata.optstore.get_value_for(OptionKey('backend_max_links'), int) if 'java' in self.environment.coredata.compilers.host: self.generate_java_link() for for_machine in MachineChoice: @@ -2486,7 +2484,7 @@ def generate_static_link_rules(self) -> None: self.add_rule(NinjaRule(rule, cmdlist, args, description, **options, extra=pool)) def generate_dynamic_link_rules(self) -> None: - num_pools = self.environment.coredata.optstore.get_value_for_untyped('backend_max_links') + num_pools = self.environment.coredata.optstore.get_value_for(OptionKey('backend_max_links'), int) for for_machine in MachineChoice: complist = self.environment.coredata.compilers[for_machine] for langname, compiler in complist.items(): @@ -4012,8 +4010,7 @@ def generate_clangtool(self, name: str, extra_arg: T.Optional[str] = None, need_ if extra_arg: target_name += f'-{extra_arg}' extra_args.append(f'--{extra_arg}') - colorout = self.environment.coredata.optstore.get_value_for_untyped('b_colorout') \ - if OptionKey('b_colorout') in self.environment.coredata.optstore else 'always' + colorout = self.environment.coredata.optstore.get_value_for(OptionKey('b_colorout'), str, default='always') assert isinstance(colorout, str), 'for mypy' extra_args.extend(['--color', colorout]) if not os.path.exists(os.path.join(self.environment.source_dir, '.clang-' + name)) and \ @@ -4120,8 +4117,7 @@ def generate_ending(self) -> None: if ctlist: elem.add_dep(self.generate_custom_target_clean(ctlist)) - if OptionKey('b_coverage') in self.environment.coredata.optstore and \ - self.environment.coredata.optstore.get_value_for_untyped('b_coverage'): + if self.environment.coredata.optstore.get_value_for(OptionKey('b_coverage'), bool, default=False): self.generate_gcov_clean() elem.add_dep('clean-gcda') elem.add_dep('clean-gcno') diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index 71e9b43b42a0..e1216461c41c 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -275,13 +275,10 @@ def generate(self, else: raise MesonException('Unsupported Visual Studio platform: ' + build_machine) - self.buildtype = self.environment.coredata.optstore.get_value_for_untyped(OptionKey('buildtype')) - self.optimization = self.environment.coredata.optstore.get_value_for_untyped(OptionKey('optimization')) - self.debug = self.environment.coredata.optstore.get_value_for_untyped(OptionKey('debug')) - try: - self.sanitize = self.environment.coredata.optstore.get_value_for_untyped(OptionKey('b_sanitize')) - except KeyError: - self.sanitize = [] + self.buildtype = self.environment.coredata.optstore.get_value_for(OptionKey('buildtype'), str) + self.optimization = self.environment.coredata.optstore.get_value_for(OptionKey('optimization'), str) + self.debug = self.environment.coredata.optstore.get_value_for(OptionKey('debug'), bool) + self.sanitize = self.environment.coredata.optstore.get_value_for(OptionKey('b_sanitize'), list, default=[]) sln_filename = os.path.join(self.environment.get_build_dir(), self.build.project_name + '.sln') projlist = self.generate_projects(vslite_ctx) self.gen_testproj() @@ -428,7 +425,7 @@ def generate_solution(self, sln_filename: str, projlist: T.List[Project]) -> Non ofile.write('# Visual Studio %s\n' % self.sln_version_comment) prj_templ = 'Project("{%s}") = "%s", "%s", "{%s}"\n' for prj in projlist: - if self.environment.coredata.optstore.get_value_for_untyped(OptionKey('layout')) == 'mirror': + if self.environment.coredata.optstore.get_value_for(OptionKey('layout'), str) == 'mirror': self.generate_solution_dirs(ofile, prj[1].parents) target = self.build.targets[prj[0]] lang = 'default' @@ -540,7 +537,7 @@ def generate_solution(self, sln_filename: str, projlist: T.List[Project]) -> Non replace_if_different(sln_filename, sln_filename_tmp) def generate_projects(self, vslite_ctx: dict = None) -> T.List[Project]: - startup_project = self.environment.coredata.optstore.get_value_for_untyped('backend_startup_project') + startup_project = self.environment.coredata.optstore.get_value_for(OptionKey('backend_startup_project'), str) projlist: T.List[Project] = [] startup_idx = 0 for (i, (name, target)) in enumerate(self.build.targets.items()): @@ -1848,7 +1845,7 @@ def path_normalize_add(path, lis): # build system as possible. self.add_target_deps(root, target) self._prettyprint_vcxproj_xml(ET.ElementTree(root), ofname) - if self.environment.coredata.optstore.get_value_for_untyped(OptionKey('layout')) == 'mirror': + if self.environment.coredata.optstore.get_value_for(OptionKey('layout'), str) == 'mirror': self.gen_vcxproj_filters(target, ofname) return True @@ -2017,9 +2014,9 @@ def gen_testproj(self): meson_build_dir_for_buildtype = build_dir_tail[:-2] + buildtype # Get the buildtype suffixed 'builddir_[debug/release/etc]' from 'builddir_vs', for example. proj_to_build_dir_for_buildtype = str(os.path.join(proj_to_multiconfigured_builds_parent_dir, meson_build_dir_for_buildtype)) test_cmd = f'{nmake_base_meson_command} test -C "{proj_to_build_dir_for_buildtype}" --no-rebuild' - if not self.environment.coredata.optstore.get_value_for_untyped(OptionKey('stdsplit')): + if not self.environment.coredata.optstore.get_value_for(OptionKey('stdsplit'), bool): test_cmd += ' --no-stdsplit' - if self.environment.coredata.optstore.get_value_for_untyped(OptionKey('errorlogs')): + if self.environment.coredata.optstore.get_value_for(OptionKey('errorlogs'), bool): test_cmd += ' --print-errorlogs' condition = f'\'$(Configuration)|$(Platform)\'==\'{buildtype}|{self.platform}\'' prop_group = ET.SubElement(root, 'PropertyGroup', Condition=condition) @@ -2041,9 +2038,9 @@ def gen_testproj(self): ET.SubElement(midl, 'ProxyFileName').text = '%(Filename)_p.c' # FIXME: No benchmarks? test_command = self.environment.get_build_command() + ['test', '--no-rebuild'] - if not self.environment.coredata.optstore.get_value_for_untyped(OptionKey('stdsplit')): + if not self.environment.coredata.optstore.get_value_for(OptionKey('stdsplit'), bool): test_command += ['--no-stdsplit'] - if self.environment.coredata.optstore.get_value_for_untyped(OptionKey('errorlogs')): + if self.environment.coredata.optstore.get_value_for(OptionKey('errorlogs'), bool): test_command += ['--print-errorlogs'] self.serialize_tests() self.add_custom_build(root, 'run_tests', '"%s"' % ('" "'.join(test_command))) diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py index 21178fb1babf..936f5b98e9a7 100644 --- a/mesonbuild/backend/xcodebackend.py +++ b/mesonbuild/backend/xcodebackend.py @@ -239,7 +239,7 @@ class XCodeBackend(backends.Backend): def __init__(self, build: T.Optional[build.Build]): super().__init__(build) self.project_uid = self.environment.coredata.lang_guids['default'].replace('-', '')[:24] - self.buildtype = T.cast('str', self.environment.coredata.optstore.get_value_for_untyped(OptionKey('buildtype'))) + self.buildtype = self.environment.coredata.optstore.get_value_for(OptionKey('buildtype'), str) self.project_conflist = self.gen_id() self.maingroup_id = self.gen_id() self.all_id = self.gen_id() @@ -281,7 +281,7 @@ def gen_id(self) -> str: @functools.lru_cache(maxsize=None) def get_target_dir(self, target: build.AnyTargetType) -> str: - dirname = os.path.join(target.get_subdir(), T.cast('str', self.environment.coredata.optstore.get_value_for_untyped(OptionKey('buildtype')))) + dirname = os.path.join(target.get_subdir(), self.environment.coredata.optstore.get_value_for(OptionKey('buildtype'), str)) #os.makedirs(os.path.join(self.environment.get_build_dir(), dirname), exist_ok=True) return dirname diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 3f3345fe471e..1517ff06a32c 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -1851,7 +1851,8 @@ def process_vs_module_defs_kw(self, kwargs: ExecutableKeywordArguments) -> None: self.process_link_depends([path]) def extract_targets_as_list(self, kwargs: BuildTargetKeywordArguments, key: T.Literal['link_with', 'link_whole']) -> T.List[LibTypes]: - bl_type = self.environment.coredata.optstore.get_value_for_untyped(OptionKey('default_both_libraries')) + bl_type = self.environment.coredata.optstore.get_value_for( + OptionKey('default_both_libraries'), str) if bl_type == 'auto': if isinstance(self, StaticLibrary): bl_type = 'static' @@ -1874,7 +1875,7 @@ def get(self, lib_type: T.Literal['static', 'shared']) -> LibTypes: def determine_rpath_dirs(self) -> T.Tuple[str, ...]: result: OrderedSet[str] - if self.environment.coredata.optstore.get_value_for_untyped(OptionKey('layout')) == 'mirror': + if self.environment.coredata.optstore.get_value_for(OptionKey('layout'), str) == 'mirror': # Need a copy here result = OrderedSet(self.get_link_dep_subdirs()) else: @@ -2281,7 +2282,7 @@ def post_init(self) -> None: machine.is_windows() and ('cs' in self.compilers or self.uses_rust() or self.get_using_msvc()) # .pdb file is created only when debug symbols are enabled - and self.environment.coredata.optstore.get_value_for_untyped(OptionKey("debug")) + and self.environment.coredata.optstore.get_value_for(OptionKey("debug"), bool) ) if create_debug_file: # If the target is has a standard exe extension (i.e. 'foo.exe'), @@ -2411,7 +2412,7 @@ def determine_default_prefix_and_suffix(self) -> T.Tuple[str, str]: suffix = 'rlib' elif self.rust_crate_type == 'staticlib': suffix = 'a' - elif self.environment.machines[self.for_machine].is_os2() and self.environment.coredata.optstore.get_value_for_untyped(OptionKey('os2_emxomf')): + elif self.environment.machines[self.for_machine].is_os2() and self.environment.coredata.optstore.get_value_for(OptionKey('os2_emxomf'), bool): suffix = 'lib' else: suffix = 'a' @@ -2599,7 +2600,7 @@ def determine_naming_info(self) -> T.Tuple[str, str, str, str, bool]: # Import library is called foo.dll.lib import_filename_tpl = '{0.prefix}{0.name}.dll.lib' # .pdb file is only created when debug symbols are enabled - create_debug_file = self.environment.coredata.optstore.get_value_for_untyped(OptionKey("debug")) + create_debug_file = self.environment.coredata.optstore.get_value_for(OptionKey("debug"), bool) elif self.get_using_msvc(): # Shared library is of the form foo.dll prefix = prefix if prefix is not None else '' @@ -2607,7 +2608,7 @@ def determine_naming_info(self) -> T.Tuple[str, str, str, str, bool]: import_suffix = import_suffix if import_suffix is not None else 'lib' import_filename_tpl = '{0.prefix}{0.name}.' + import_suffix # .pdb file is only created when debug symbols are enabled - create_debug_file = self.environment.coredata.optstore.get_value_for_untyped(OptionKey("debug")) + create_debug_file = self.environment.coredata.optstore.get_value_for(OptionKey("debug"), bool) # Assume GCC-compatible naming else: # Shared library is of the form libfoo.dll @@ -2654,7 +2655,7 @@ def determine_naming_info(self) -> T.Tuple[str, str, str, str, bool]: suffix = suffix if suffix is not None else 'dll' # Import library is called foo_dll.a or foo_dll.lib if import_suffix is None: - import_suffix = '_dll.lib' if self.environment.coredata.optstore.get_value_for_untyped(OptionKey('os2_emxomf')) else '_dll.a' + import_suffix = '_dll.lib' if self.environment.coredata.optstore.get_value_for(OptionKey('os2_emxomf'), bool) else '_dll.a' import_filename_tpl = '{0.prefix}{0.name}' + import_suffix filename_tpl = '{0.shortname}' if self.shortname else '{0.prefix}{0.name}' if self.soversion: diff --git a/mesonbuild/cmake/common.py b/mesonbuild/cmake/common.py index f945c9999338..62ade16a9b1e 100644 --- a/mesonbuild/cmake/common.py +++ b/mesonbuild/cmake/common.py @@ -56,15 +56,13 @@ def cmake_is_debug(env: 'Environment') -> bool: if 'b_vscrt' in env.coredata.optstore: - is_debug = env.coredata.optstore.get_value_for_untyped('buildtype') == 'debug' - if env.coredata.optstore.get_value_for_untyped('b_vscrt') in {'mdd', 'mtd'}: + is_debug = env.coredata.optstore.get_value_for(OptionKey('buildtype'), str) == 'debug' + if env.coredata.optstore.get_value_for(OptionKey('b_vscrt'), str) in {'mdd', 'mtd'}: is_debug = True - return is_debug else: # Don't directly assign to is_debug to make mypy happy - debug_opt = env.coredata.optstore.get_value_for_untyped('debug') - assert isinstance(debug_opt, bool) - return debug_opt + is_debug = env.coredata.optstore.get_value_for(OptionKey('debug'), bool) + return is_debug class CMakeException(MesonException): pass @@ -108,8 +106,7 @@ def _flags_to_list(raw: str) -> T.List[str]: return res def cmake_get_generator_args(env: 'Environment') -> T.List[str]: - backend_name = env.coredata.optstore.get_value_for_untyped(OptionKey('backend')) - assert isinstance(backend_name, str) + backend_name = env.coredata.optstore.get_value_for(OptionKey('backend'), str) assert backend_name in backend_generator_map return ['-G', backend_generator_map[backend_name]] diff --git a/mesonbuild/cmake/executor.py b/mesonbuild/cmake/executor.py index 849dfb261b6c..adde396e17ff 100644 --- a/mesonbuild/cmake/executor.py +++ b/mesonbuild/cmake/executor.py @@ -52,9 +52,8 @@ def __init__(self, environment: 'Environment', version: str, for_machine: Machin self.cmakebin = None return - prefpath = self.environment.coredata.optstore.get_value_for_untyped( - OptionKey(name='cmake_prefix_path', machine=for_machine)) - assert isinstance(prefpath, list) + prefpath = self.environment.coredata.optstore.get_value_for( + OptionKey(name='cmake_prefix_path', machine=for_machine), list) self.prefix_paths = prefpath if self.prefix_paths: self.extra_cmake_args += ['-DCMAKE_PREFIX_PATH={}'.format(';'.join(self.prefix_paths))] diff --git a/mesonbuild/cmake/interpreter.py b/mesonbuild/cmake/interpreter.py index 6a189c793a05..bd8c9b5d717f 100644 --- a/mesonbuild/cmake/interpreter.py +++ b/mesonbuild/cmake/interpreter.py @@ -801,7 +801,7 @@ def __init__(self, subdir: Path, env: 'Environment', backend: 'Backend'): self.src_dir = Path(env.get_source_dir(), subdir) self.build_dir_rel = subdir / '__CMake_build' self.build_dir = Path(env.get_build_dir()) / self.build_dir_rel - self.install_prefix = Path(T.cast('str', env.coredata.optstore.get_value_for_untyped(OptionKey('prefix')))) + self.install_prefix = Path(env.coredata.optstore.get_value_for(OptionKey('prefix'), str)) self.env = env self.for_machine = MachineChoice.HOST # TODO make parameter self.backend_name = backend.name @@ -851,12 +851,12 @@ def configure(self, extra_cmake_options: T.List[str]) -> CMakeExecutor: cmake_args = [] cmake_args += cmake_get_generator_args(self.env) cmake_args += [f'-DCMAKE_INSTALL_PREFIX={self.install_prefix}'] - libdir = self.env.coredata.optstore.get_value_for_untyped(OptionKey('libdir')) + libdir = self.env.coredata.optstore.get_value_for(OptionKey('libdir'), str) cmake_args += [f'-DCMAKE_INSTALL_LIBDIR={libdir}'] cmake_args += extra_cmake_options if not any(arg.startswith('-DCMAKE_BUILD_TYPE=') for arg in cmake_args): # Our build type is favored over any CMAKE_BUILD_TYPE environment variable - buildtype = T.cast('str', self.env.coredata.optstore.get_value_for_untyped(OptionKey('buildtype'))) + buildtype = self.env.coredata.optstore.get_value_for(OptionKey('buildtype'), str) if buildtype in BUILDTYPE_MAP: cmake_args += [f'-DCMAKE_BUILD_TYPE={BUILDTYPE_MAP[buildtype]}'] trace_args = self.trace.trace_args() diff --git a/mesonbuild/compilers/asm.py b/mesonbuild/compilers/asm.py index 7460826044f5..8962e36fec7e 100644 --- a/mesonbuild/compilers/asm.py +++ b/mesonbuild/compilers/asm.py @@ -91,7 +91,7 @@ def get_always_args(self) -> T.List[str]: define = 'MACHO' elif self.info.is_os2(): cpu = '' - if self.environment.coredata.optstore.get_value_for_untyped(OptionKey('os2_emxomf')): + if self.environment.coredata.optstore.get_value_for(OptionKey('os2_emxomf'), bool): plat = 'obj2' define = 'OBJ2' else: diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 47d5d0021c10..3baaf8fb5b49 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -281,9 +281,9 @@ def are_asserts_disabled(target: 'BuildTarget', env: 'Environment') -> bool: def are_asserts_disabled_for_subproject(subproject: str, env: 'Environment') -> bool: key = OptionKey('b_ndebug', subproject) - return (env.coredata.optstore.get_value_for_untyped(key) == 'true' or - (env.coredata.optstore.get_value_for_untyped(key) == 'if-release' and - env.coredata.optstore.get_value_for_untyped(key.evolve(name='buildtype')) in {'release', 'plain'})) + return (env.coredata.optstore.get_value_for(key, str) == 'true' or + (env.coredata.optstore.get_value_for(key, str) == 'if-release' and + env.coredata.optstore.get_value_for(key.evolve(name='buildtype'), str) in {'release', 'plain'})) def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Environment') -> T.List[str]: @@ -1172,8 +1172,7 @@ def get_crt_val(self, crt_val: str) -> str: rel = 'mt' # Match what build type flags used to do. - buildtype = env.coredata.optstore.get_value_for_untyped('buildtype') - assert isinstance(buildtype, str), 'for mypy' + buildtype = self.environment.coredata.optstore.get_value_for(OptionKey('buildtype'), str) if buildtype == 'plain': return 'none' elif buildtype == 'debug': @@ -1598,6 +1597,7 @@ def get_preprocessor(self) -> Compiler: def form_compileropt_key(self, basename: str) -> OptionKey: return OptionKey(f'{self.language}_{basename}', machine=self.for_machine) + # TODO: get rid of this def get_compileropt_value(self, key: T.Union[str, OptionKey], target: T.Optional[BuildTarget], diff --git a/mesonbuild/compilers/detect.py b/mesonbuild/compilers/detect.py index 3704e4fffd4a..952a23a2ccbf 100644 --- a/mesonbuild/compilers/detect.py +++ b/mesonbuild/compilers/detect.py @@ -172,7 +172,7 @@ def detect_static_linker(env: 'Environment', compiler: Compiler) -> StaticLinker trials = [defaults['cuda_static_linker']] + default_linkers elif compiler.get_argument_syntax() == 'msvc': trials = [defaults['vs_static_linker'], defaults['clang_cl_static_linker']] - elif env.machines[compiler.for_machine].is_os2() and env.coredata.optstore.get_value_for_untyped(OptionKey('os2_emxomf')): + elif env.machines[compiler.for_machine].is_os2() and env.coredata.optstore.get_value_for(OptionKey('os2_emxomf'), bool): trials = [defaults['emxomf_static_linker']] + default_linkers elif compiler.id == 'gcc': # Use gcc-ar if available; needed for LTO diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py index 01e84463ce47..9b03d37cde2a 100644 --- a/mesonbuild/compilers/mixins/clike.py +++ b/mesonbuild/compilers/mixins/clike.py @@ -27,6 +27,7 @@ from ... import mlog from ...linkers.linkers import GnuLikeDynamicLinkerMixin, SolarisDynamicLinker, CompCertDynamicLinker from ...mesonlib import LibType +from ...options import OptionKey from .. import compilers from ..compilers import CompileCheckMode from .visualstudio import VisualStudioLikeCompiler @@ -331,8 +332,7 @@ def _get_basic_compiler_args(self, mode: CompileCheckMode) -> T.Tuple[T.List[str # linking with static libraries since MSVC won't select a CRT for # us in that case and will error out asking us to pick one. try: - crt_val = self.environment.coredata.optstore.get_value_for_untyped('b_vscrt') - assert isinstance(crt_val, str), 'for mypy' + crt_val = self.environment.coredata.optstore.get_value_for(OptionKey('b_vscrt'), str) cargs += self.get_crt_compile_args(crt_val) largs += self.get_crt_link_args(crt_val) except (KeyError, AttributeError): diff --git a/mesonbuild/compilers/mixins/emscripten.py b/mesonbuild/compilers/mixins/emscripten.py index 057f87f3b1e1..23e5817728bc 100644 --- a/mesonbuild/compilers/mixins/emscripten.py +++ b/mesonbuild/compilers/mixins/emscripten.py @@ -49,8 +49,8 @@ def _get_compile_output(self, dirname: str, mode: CompileCheckMode) -> str: def thread_link_flags(self) -> T.List[str]: args = ['-pthread'] - count = self.environment.coredata.optstore.get_value_for_untyped(OptionKey(f'{self.language}_thread_count', machine=self.for_machine)) - assert isinstance(count, int) + count = self.environment.coredata.optstore.get_value_for( + OptionKey(f'{self.language}_thread_count', machine=self.for_machine), int) if count: args.append(f'-sPTHREAD_POOL_SIZE={count}') return args diff --git a/mesonbuild/compilers/mixins/gnu.py b/mesonbuild/compilers/mixins/gnu.py index 98cd77912380..8830e60c5e9b 100644 --- a/mesonbuild/compilers/mixins/gnu.py +++ b/mesonbuild/compilers/mixins/gnu.py @@ -658,7 +658,7 @@ def get_profile_use_args(self) -> T.List[str]: def get_always_args(self) -> T.List[str]: args: T.List[str] = [] - if self.info.is_os2() and self.environment.coredata.optstore.get_value_for_untyped(OptionKey('os2_emxomf')): + if self.info.is_os2() and self.environment.coredata.optstore.get_value_for(OptionKey('os2_emxomf'), bool): args += ['-Zomf'] return super().get_always_args() + args diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py index f6a48f88c45b..c378d8e77fc5 100644 --- a/mesonbuild/coredata.py +++ b/mesonbuild/coredata.py @@ -122,8 +122,8 @@ def __init__(self, builtins: options.OptionStore, for_machine: MachineChoice): def __calculate_subkey(self, type_: DependencyCacheType) -> T.Tuple[str, ...]: data: T.Dict[DependencyCacheType, T.List[str]] = { - DependencyCacheType.PKG_CONFIG: T.cast('T.List[str]', self.__builtins.get_value_for_untyped(self.__pkg_conf_key)), - DependencyCacheType.CMAKE: T.cast('T.List[str]', self.__builtins.get_value_for_untyped(self.__cmake_key)), + DependencyCacheType.PKG_CONFIG: self.__builtins.get_value_for(self.__pkg_conf_key, list), + DependencyCacheType.CMAKE: self.__builtins.get_value_for(self.__cmake_key, list), DependencyCacheType.OTHER: [], } assert type_ in data, 'Someone forgot to update subkey calculations for a new type' @@ -349,7 +349,7 @@ def clear_cache(self) -> None: def get_nondefault_buildtype_args(self) -> T.List[T.Union[T.Tuple[str, str, str], T.Tuple[str, bool, bool]]]: result: T.List[T.Union[T.Tuple[str, str, str], T.Tuple[str, bool, bool]]] = [] - value = self.optstore.get_value_for_untyped('buildtype') + value = self.optstore.get_value_for(OptionKey('buildtype'), str) if value == 'plain': opt = 'plain' debug = False @@ -368,10 +368,8 @@ def get_nondefault_buildtype_args(self) -> T.List[T.Union[T.Tuple[str, str, str] else: assert value == 'custom' return [] - actual_opt = self.optstore.get_value_for_untyped('optimization') - actual_debug = self.optstore.get_value_for_untyped('debug') - assert isinstance(actual_opt, str) # for mypy - assert isinstance(actual_debug, bool) # for mypy + actual_opt = self.optstore.get_value_for(OptionKey('optimization'), str) + actual_debug = self.optstore.get_value_for(OptionKey('debug'), bool) if actual_opt != opt: result.append(('optimization', actual_opt, opt)) if actual_debug != debug: @@ -424,7 +422,7 @@ def process_compiler_options(self, lang: Language, comp: Compiler, subproject: s def emit_base_options_warnings(self) -> None: bcodekey = OptionKey('b_bitcode') - if bcodekey in self.optstore and self.optstore.get_value_for_untyped(bcodekey): + if bcodekey in self.optstore and self.optstore.get_value_for(bcodekey, bool): msg = textwrap.dedent('''Base option 'b_bitcode' is enabled, which is incompatible with many linker options. Incompatible options such as \'b_asneeded\' have been disabled.' Please see https://mesonbuild.com/Builtin-options.html#Notes_about_Apple_Bitcode_support for more details.''') diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py index 85c8ae0fc247..b5480a33811c 100644 --- a/mesonbuild/dependencies/base.py +++ b/mesonbuild/dependencies/base.py @@ -431,7 +431,7 @@ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObje self.silent = kwargs.get('silent', False) static = kwargs.get('static') if static is None: - static = T.cast('bool', self.env.coredata.optstore.get_value_for_untyped(OptionKey('prefer_static'))) + static = self.env.coredata.optstore.get_value_for(OptionKey('prefer_static'), bool) self.static = static self.libtype = LibType.STATIC if self.static else LibType.PREFER_SHARED # Is this dependency to be run on the build platform? diff --git a/mesonbuild/dependencies/boost.py b/mesonbuild/dependencies/boost.py index e48c662dc7a5..33a9ff7947e6 100644 --- a/mesonbuild/dependencies/boost.py +++ b/mesonbuild/dependencies/boost.py @@ -343,8 +343,7 @@ class BoostDependency(SystemDependency): def __init__(self, name: str, environment: Environment, kwargs: DependencyObjectKWs) -> None: kwargs['language'] = 'cpp' super().__init__(name, environment, kwargs) - buildtype = environment.coredata.optstore.get_value_for_untyped(OptionKey('buildtype')) - assert isinstance(buildtype, str) + buildtype = environment.coredata.optstore.get_value_for(OptionKey('buildtype'), str) self.debug = buildtype.startswith('debug') self.multithreading = kwargs.get('threading', 'multi') == 'multi' @@ -602,13 +601,11 @@ def detect_lib_dirs(self, root: Path, use_system: bool) -> T.List[Path]: def filter_libraries(self, libs: T.List[BoostLibraryFile], lib_vers: str) -> T.List[BoostLibraryFile]: # MSVC is very picky with the library tags - vscrt = '' try: - crt_val = self.env.coredata.optstore.get_value_for_untyped('b_vscrt') - assert isinstance(crt_val, str) + crt_val = self.env.coredata.optstore.get_value_for(OptionKey('b_vscrt'), str) vscrt = self.clib_compiler.get_crt_compile_args(crt_val)[0] except (KeyError, IndexError, AttributeError): - pass + vscrt = '' # mlog.debug(' - static: {}'.format(self.static)) # mlog.debug(' - not explicit static: {}'.format(not self.explicit_static)) diff --git a/mesonbuild/dependencies/dub.py b/mesonbuild/dependencies/dub.py index 99a652a4075d..b80bb503ed01 100644 --- a/mesonbuild/dependencies/dub.py +++ b/mesonbuild/dependencies/dub.py @@ -124,7 +124,7 @@ def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObje dub_arch = self.compiler.arch # we need to know the build type as well - dub_buildtype = str(environment.coredata.optstore.get_value_for_untyped(OptionKey('buildtype'))) + dub_buildtype = environment.coredata.optstore.get_value_for(OptionKey('buildtype'), str) # MESON types: choices=['plain', 'debug', 'debugoptimized', 'release', 'minsize', 'custom'])), # DUB types: debug (default), plain, release, release-debug, release-nobounds, unittest, profile, profile-gc, # docs, ddox, cov, unittest-cov, syntax and custom diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py index 82f650ca3ff1..770c5255a661 100644 --- a/mesonbuild/dependencies/misc.py +++ b/mesonbuild/dependencies/misc.py @@ -578,7 +578,7 @@ def shaderc_factory(env: 'Environment', static = kwargs.get('static') if static is None: - static = T.cast('bool', env.coredata.optstore.get_value_for_untyped(OptionKey('prefer_static'))) + static = env.coredata.optstore.get_value_for(OptionKey('prefer_static'), bool) if static: c = [DependencyCandidate.from_dependency(name, PkgConfigDependency, (env, kwargs)) for name in static_libs + shared_libs] diff --git a/mesonbuild/dependencies/mpi.py b/mesonbuild/dependencies/mpi.py index fb654afdb5c8..edf4d9d6b97b 100644 --- a/mesonbuild/dependencies/mpi.py +++ b/mesonbuild/dependencies/mpi.py @@ -14,6 +14,7 @@ from .detect import packages from .factory import factory_methods from .pkgconfig import PkgConfigDependency +from ..options import OptionKey if T.TYPE_CHECKING: from .factory import DependencyGenerator @@ -283,8 +284,7 @@ def __init__(self, name: str, env: Environment, kwargs: DependencyObjectKWs): incdir = os.path.join(rootdir, 'include') libdir = os.path.join(rootdir, 'lib') - debug = env.coredata.optstore.get_value_for_untyped('debug') - assert isinstance(debug, bool) + debug = env.coredata.optstore.get_value_for(OptionKey('debug'), bool) libdir_post = 'debug' if debug else 'release' for subdirs in (['mpi', libdir_post], [libdir_post]): libdir_buildtype = os.path.join(libdir, *subdirs) diff --git a/mesonbuild/dependencies/pkgconfig.py b/mesonbuild/dependencies/pkgconfig.py index 3e7c0d1d20f3..8d2df9b27842 100644 --- a/mesonbuild/dependencies/pkgconfig.py +++ b/mesonbuild/dependencies/pkgconfig.py @@ -268,9 +268,8 @@ def _check_pkgconfig(self, pkgbin: ExternalProgram) -> T.Optional[str]: def _get_env(self, uninstalled: bool = False) -> EnvironmentVariables: env = EnvironmentVariables() key = OptionKey('pkg_config_path', machine=self.for_machine) - pathlist = self.env.coredata.optstore.get_value_for_untyped(key) - assert isinstance(pathlist, list) - extra_paths: T.List[str] = pathlist + self.extra_paths + pathlist = self.env.coredata.optstore.get_value_for(key, list) + extra_paths = pathlist + self.extra_paths if uninstalled: bpath = self.env.get_build_dir() if bpath is not None: @@ -435,7 +434,7 @@ def _search_libs(self, libs_in: ImmutableListProtocol[str], raw_libs_in: Immutab # # Only prefix_libpaths are reordered here because there should not be # too many system_libpaths to cause library version issues. - pkg_config_path: T.List[str] = self.env.coredata.optstore.get_value_for_untyped(OptionKey('pkg_config_path', machine=self.for_machine)) # type: ignore[assignment] + pkg_config_path = self.env.coredata.optstore.get_value_for(OptionKey('pkg_config_path', machine=self.for_machine), list) pkg_config_path = self._convert_mingw_paths(pkg_config_path) prefix_libpaths = OrderedSet(sort_libpaths(list(prefix_libpaths), pkg_config_path)) system_libpaths: OrderedSet[str] = OrderedSet() diff --git a/mesonbuild/dependencies/python.py b/mesonbuild/dependencies/python.py index 8eb9f6cb32e6..1d2fa889caf5 100644 --- a/mesonbuild/dependencies/python.py +++ b/mesonbuild/dependencies/python.py @@ -396,16 +396,13 @@ def get_windows_link_args(self, limited_api: bool, environment: 'Environment') - # Python itself (except with pybind11, which has an ugly # hack to work around this) - so emit a warning to explain # the cause of the expected link error. - buildtype = self.env.coredata.optstore.get_value_for_untyped(OptionKey('buildtype')) - assert isinstance(buildtype, str) - debug = self.env.coredata.optstore.get_value_for_untyped(OptionKey('debug')) + buildtype = self.env.coredata.optstore.get_value_for(OptionKey('buildtype'), str) + debug = self.env.coredata.optstore.get_value_for(OptionKey('debug'), bool) # `debugoptimized` buildtype may not set debug=True currently, see gh-11645 is_debug_build = debug or buildtype == 'debug' - vscrt_debug = False - if OptionKey('b_vscrt') in self.env.coredata.optstore: - vscrt = self.env.coredata.optstore.get_value_for_untyped('b_vscrt') - if vscrt in {'mdd', 'mtd', 'from_buildtype', 'static_from_buildtype'}: - vscrt_debug = True + vscrt = self.env.coredata.optstore.get_value_for(OptionKey('b_vscrt'), str, default='sentinal') + vscrt_debug = vscrt in {'mdd', 'mtd', 'from_buildtype', 'static_from_buildtype'} + if is_debug_build and vscrt_debug and not self.variables.get('Py_DEBUG'): mlog.warning(textwrap.dedent('''\ Using a debug build type with MSVC or an MSVC-compatible compiler diff --git a/mesonbuild/dependencies/qt.py b/mesonbuild/dependencies/qt.py index 793edb3a89fb..0d336d9cf72f 100644 --- a/mesonbuild/dependencies/qt.py +++ b/mesonbuild/dependencies/qt.py @@ -20,6 +20,7 @@ from .factory import DependencyFactory from .. import mlog from .. import mesonlib +from ..options import OptionKey if T.TYPE_CHECKING: from ..compilers.compilers import Compiler @@ -168,7 +169,7 @@ def log_details(self) -> str: return f'modules: {", ".join(sorted(self.requested_modules))}' def _get_common_defines(self) -> T.List[str]: - is_debug = self.env.coredata.optstore.get_value_for_untyped('debug') + is_debug = self.env.coredata.optstore.get_value_for(OptionKey('debug'), bool) return ['-DQT_DEBUG' if is_debug else '-DQT_NO_DEBUG'] class QtPkgConfigDependency(_QtBase, PkgConfigDependency, metaclass=abc.ABCMeta): @@ -305,10 +306,8 @@ def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs): # Use the buildtype by default, but look at the b_vscrt option if the # compiler supports it. - is_debug = self.env.coredata.optstore.get_value_for_untyped('buildtype') == 'debug' - if 'b_vscrt' in self.env.coredata.optstore: - if self.env.coredata.optstore.get_value_for_untyped('b_vscrt') in {'mdd', 'mtd'}: - is_debug = True + is_debug = self.env.coredata.optstore.get_value_for(OptionKey('buildtype'), str) == 'debug' + is_debug |= self.env.coredata.optstore.get_value_for(OptionKey('b_vscrt'), str, default='sentinel') in {'mdd', 'mtd'} modules_lib_suffix = _get_modules_lib_suffix(self.version, self.env.machines[self.for_machine], is_debug) for module in self.requested_modules: diff --git a/mesonbuild/dependencies/scalapack.py b/mesonbuild/dependencies/scalapack.py index c1678b3eaaba..97a1f1c68e90 100644 --- a/mesonbuild/dependencies/scalapack.py +++ b/mesonbuild/dependencies/scalapack.py @@ -27,7 +27,9 @@ def scalapack_factory(env: 'Environment', candidates: T.List['DependencyGenerator'] = [] if DependencyMethods.PKGCONFIG in methods: - static_opt = kwargs['static'] if kwargs.get('static') is not None else env.coredata.optstore.get_value_for_untyped(OptionKey('prefer_static')) + static_opt = kwargs['static'] + if static_opt is None: + static_opt = env.coredata.optstore.get_value_for(OptionKey('prefer_static'), bool) mkl = 'mkl-static-lp64-iomp' if static_opt else 'mkl-dynamic-lp64-iomp' candidates.append(DependencyCandidate.from_dependency( mkl, MKLPkgConfigDependency, (env, kwargs))) diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index c20866083e81..af4f99cda79e 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -48,11 +48,6 @@ build_filename = 'meson.build' -def _as_str(val: object) -> str: - assert isinstance(val, str), 'for mypy' - return val - - def _get_env_var(for_machine: MachineChoice, is_cross: bool, var_name: str) -> T.Optional[str]: """ Returns the exact env var and the value. @@ -488,25 +483,25 @@ def get_static_lib_dir(self) -> str: return self.get_libdir() def get_prefix(self) -> str: - return _as_str(self.coredata.optstore.get_value_for_untyped(OptionKey('prefix'))) + return self.coredata.optstore.get_value_for(OptionKey('prefix'), str) def get_libdir(self) -> str: - return _as_str(self.coredata.optstore.get_value_for_untyped(OptionKey('libdir'))) + return self.coredata.optstore.get_value_for(OptionKey('libdir'), str) def get_libexecdir(self) -> str: - return _as_str(self.coredata.optstore.get_value_for_untyped(OptionKey('libexecdir'))) + return self.coredata.optstore.get_value_for(OptionKey('libexecdir'), str) def get_bindir(self) -> str: - return _as_str(self.coredata.optstore.get_value_for_untyped(OptionKey('bindir'))) + return self.coredata.optstore.get_value_for(OptionKey('bindir'), str) def get_includedir(self) -> str: - return _as_str(self.coredata.optstore.get_value_for_untyped(OptionKey('includedir'))) + return self.coredata.optstore.get_value_for(OptionKey('includedir'), str) def get_mandir(self) -> str: - return _as_str(self.coredata.optstore.get_value_for_untyped(OptionKey('mandir'))) + return self.coredata.optstore.get_value_for(OptionKey('mandir'), str) def get_datadir(self) -> str: - return _as_str(self.coredata.optstore.get_value_for_untyped(OptionKey('datadir'))) + return self.coredata.optstore.get_value_for(OptionKey('datadir'), str) def get_compiler_system_lib_dirs(self, for_machine: MachineChoice) -> T.List[str]: for comp in self.coredata.compilers[for_machine].values(): diff --git a/mesonbuild/interpreter/compiler.py b/mesonbuild/interpreter/compiler.py index bd9a95b95211..9a85794c40e6 100644 --- a/mesonbuild/interpreter/compiler.py +++ b/mesonbuild/interpreter/compiler.py @@ -699,7 +699,7 @@ def find_library_method(self, args: T.Tuple[str], kwargs: 'FindLibraryKW') -> 'd search_dirs = extract_search_dirs(kwargs) - prefer_static = self.environment.coredata.optstore.get_value_for_untyped(OptionKey('prefer_static')) + prefer_static = self.environment.coredata.optstore.get_value_for(OptionKey('prefer_static'), bool) if kwargs['static'] is True: libtype = mesonlib.LibType.STATIC elif kwargs['static'] is False: diff --git a/mesonbuild/interpreter/dependencyfallbacks.py b/mesonbuild/interpreter/dependencyfallbacks.py index 7a72ad82efb5..d098a75bc39d 100644 --- a/mesonbuild/interpreter/dependencyfallbacks.py +++ b/mesonbuild/interpreter/dependencyfallbacks.py @@ -322,11 +322,9 @@ def lookup(self, kwargs: DependencyObjectKWs, force_fallback: bool = False) -> D required = kwargs.get('required', True) # Check if usage of the subproject fallback is forced - _wm = self.coredata.optstore.get_value_for_untyped(OptionKey('wrap_mode')) - assert isinstance(_wm, str), 'for mypy' + _wm = self.coredata.optstore.get_value_for(OptionKey('wrap_mode'), str) wrap_mode = WrapMode.from_string(_wm) - force_fallback_for = self.coredata.optstore.get_value_for_untyped(OptionKey('force_fallback_for')) - assert isinstance(force_fallback_for, list), 'for mypy' + force_fallback_for = self.coredata.optstore.get_value_for(OptionKey('force_fallback_for'), list) self.nofallback = wrap_mode == WrapMode.nofallback self.forcefallback = (force_fallback or wrap_mode == WrapMode.forcefallback or diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 289ff48fb366..09a0c9d137a3 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -1138,10 +1138,10 @@ def set_backend(self) -> None: if OptionKey('genvslite') in self.user_defined_options.cmd_line_options: # Use of the '--genvslite vsxxxx' option ultimately overrides any '--backend xxx' # option the user may specify. - backend_name = self.coredata.optstore.get_value_for_untyped(OptionKey('genvslite')) + backend_name = self.coredata.optstore.get_value_for(OptionKey('genvslite'), str) self.backend = backends.get_genvslite_backend(backend_name, self.build) else: - backend_name = self.coredata.optstore.get_value_for_untyped(OptionKey('backend')) + backend_name = self.coredata.optstore.get_value_for(OptionKey('backend'), str) self.backend = backends.get_backend_from_name(backend_name, self.build) if self.backend is None: @@ -1227,10 +1227,8 @@ def func_project(self, node: mparser.FunctionNode, args: T.Tuple[str, T.List[str # self.set_backend() otherwise it wouldn't be able to detect which # vs backend version we need. But after setting default_options in case # the project sets vs backend by default. - backend = self.coredata.optstore.get_value_for_untyped(OptionKey('backend')) - assert backend is None or isinstance(backend, str), 'for mypy' - vsenv = self.coredata.optstore.get_value_for_untyped(OptionKey('vsenv')) - assert isinstance(vsenv, bool), 'for mypy' + backend = self.coredata.optstore.get_value_for(OptionKey('backend'), str) + vsenv = self.coredata.optstore.get_value_for(OptionKey('vsenv'), bool) force_vsenv = vsenv or backend.startswith('vs') mesonlib.setup_vsenv(force_vsenv) self.set_backend() @@ -1295,7 +1293,7 @@ def func_project(self, node: mparser.FunctionNode, args: T.Tuple[str, T.List[str # Load wrap files from this (sub)project. subprojects_dir = os.path.join(self.subdir, spdirname) if not self.is_subproject(): - wrap_mode = WrapMode.from_string(self.coredata.optstore.get_value_for_untyped(OptionKey('wrap_mode'))) + wrap_mode = WrapMode.from_string(self.coredata.optstore.get_value_for(OptionKey('wrap_mode'), str)) self.environment.wrap_resolver = wrap.Resolver(self.environment.get_source_dir(), subprojects_dir, self.subproject, wrap_mode) else: assert self.environment.wrap_resolver is not None, 'for mypy' @@ -1720,7 +1718,7 @@ def program_lookup(self, args: T.List[mesonlib.FileOrString], for_machine: Machi return ExternalProgram('meson', self.environment.get_build_command(), silent=True) fallback = None - wrap_mode = WrapMode.from_string(self.coredata.optstore.get_value_for_untyped(OptionKey('wrap_mode'))) + wrap_mode = WrapMode.from_string(self.coredata.optstore.get_value_for(OptionKey('wrap_mode'), str)) if wrap_mode != WrapMode.nofallback and self.environment.wrap_resolver: fallback = self.environment.wrap_resolver.find_program_provider(args) if fallback and wrap_mode == WrapMode.forcefallback: @@ -3137,14 +3135,14 @@ def check_clang_asan_lundef(self) -> None: return if OptionKey('b_sanitize') not in self.coredata.optstore: return - if (self.coredata.optstore.get_value_for_untyped('b_lundef') and - self.coredata.optstore.get_value_for_untyped('b_sanitize')): - value = self.coredata.optstore.get_value_for_untyped('b_sanitize') - mlog.warning(textwrap.dedent(f'''\ - Trying to use {value} sanitizer on Clang with b_lundef. - This will probably not work. - Try setting b_lundef to false instead.'''), - location=self.current_node) # noqa: E128 + if self.coredata.optstore.get_value_for(OptionKey('b_lundef'), bool): + value = self.coredata.optstore.get_value_for(OptionKey('b_sanitize'), list) + if value: + mlog.warning(textwrap.dedent(f'''\ + Trying to use {value} sanitizer on Clang with b_lundef. + This will probably not work. + Try setting b_lundef to false instead.'''), + location=self.current_node) # noqa: E128 # Check that the indicated file is within the same subproject # as we currently are. This is to stop people doing @@ -3325,9 +3323,9 @@ def add_target(self, name: str, tobj: build.Target) -> None: def build_both_libraries(self, node: mparser.BaseNode, args: T.Tuple[str, SourcesVarargsType], kwargs: kwtypes.Library) -> build.BothLibraries: shared_lib = self.build_target(node, args, kwargs, build.SharedLibrary, shared_library_only=False) static_lib = self.build_target(node, args, kwargs, build.StaticLibrary) - preferred_library = self.coredata.optstore.get_value_for_untyped(OptionKey('default_both_libraries', subproject=self.subproject)) + preferred_library = self.coredata.optstore.get_value_for(OptionKey('default_both_libraries', subproject=self.subproject), str) if preferred_library == 'auto': - preferred_library = self.coredata.optstore.get_value_for_untyped(OptionKey('default_library', subproject=self.subproject)) + preferred_library = self.coredata.optstore.get_value_for(OptionKey('default_library', subproject=self.subproject), str) if preferred_library == 'both': preferred_library = 'shared' @@ -3368,8 +3366,7 @@ def build_both_libraries(self, node: mparser.BaseNode, args: T.Tuple[str, Source return build.BothLibraries(shared_lib, static_lib, preferred_library) def build_library(self, node: mparser.BaseNode, args: T.Tuple[str, SourcesVarargsType], kwargs: kwtypes.Library): - default_library = self.coredata.optstore.get_value_for_untyped(OptionKey('default_library', subproject=self.subproject)) - assert isinstance(default_library, str), 'for mypy' + default_library = self.coredata.optstore.get_value_for(OptionKey('default_library', subproject=self.subproject), str) if default_library == 'shared': return self.build_target(node, args, T.cast('kwtypes.SharedLibrary', kwargs), build.SharedLibrary) elif default_library == 'static': diff --git a/mesonbuild/interpreter/mesonmain.py b/mesonbuild/interpreter/mesonmain.py index 4da19ce9f7ed..5eac73e81a44 100644 --- a/mesonbuild/interpreter/mesonmain.py +++ b/mesonbuild/interpreter/mesonmain.py @@ -307,7 +307,7 @@ def get_compiler_method(self, args: T.Tuple[str], kwargs: 'NativeKW') -> 'Compil @noKwargs @InterpreterObject.method('is_unity') def is_unity_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> bool: - optval = self.interpreter.environment.coredata.optstore.get_value_for_untyped(OptionKey('unity')) + optval = self.interpreter.environment.coredata.optstore.get_value_for(OptionKey('unity'), str) return optval == 'on' or (optval == 'subprojects' and self.interpreter.is_subproject()) @noPosargs @@ -363,8 +363,7 @@ def override_dependency_method(self, args: T.Tuple[str, dependencies.Dependency] dep.name = name optkey = OptionKey('default_library', subproject=self.interpreter.subproject) - default_library = self.interpreter.coredata.optstore.get_value_for_untyped(optkey) - assert isinstance(default_library, str), 'for mypy' + default_library = self.interpreter.coredata.optstore.get_value_for(optkey, str) static = kwargs['static'] if static is None: # We don't know if dep represents a static or shared library, could diff --git a/mesonbuild/linkers/detect.py b/mesonbuild/linkers/detect.py index b6407f6e2f8d..9e22ba22da34 100644 --- a/mesonbuild/linkers/detect.py +++ b/mesonbuild/linkers/detect.py @@ -144,7 +144,7 @@ def guess_nix_linker(env: 'Environment', compiler: T.List[str], comp_class: T.Ty override = comp_class.use_linker_args(value[0], comp_version) check_args += override - if env.machines[for_machine].is_os2() and env.coredata.optstore.get_value_for_untyped(OptionKey('os2_emxomf')): + if env.machines[for_machine].is_os2() and env.coredata.optstore.get_value_for(OptionKey('os2_emxomf'), bool): check_args += ['-Zomf'] mlog.debug('-----') diff --git a/mesonbuild/mcompile.py b/mesonbuild/mcompile.py index a304130708e0..2ef4bdceb1f5 100644 --- a/mesonbuild/mcompile.py +++ b/mesonbuild/mcompile.py @@ -355,15 +355,14 @@ def run(options: 'argparse.Namespace') -> int: b = build.load(options.wd) cdata = b.environment.coredata - need_vsenv = T.cast('bool', cdata.optstore.get_value_for_untyped(OptionKey('vsenv'))) + need_vsenv = cdata.optstore.get_value_for(OptionKey('vsenv'), bool) if setup_vsenv(need_vsenv): mlog.log(mlog.green('INFO:'), 'automatically activated MSVC compiler environment') cmd: T.List[str] = [] env: T.Optional[T.Dict[str, str]] = None - backend = cdata.optstore.get_value_for_untyped(OptionKey('backend')) - assert isinstance(backend, str) + backend = cdata.optstore.get_value_for(OptionKey('backend'), str) mlog.log(mlog.green('INFO:'), 'autodetecting backend as', backend) if backend == 'ninja': cmd, env = get_parsed_args_ninja(options, bdir) diff --git a/mesonbuild/mdevenv.py b/mesonbuild/mdevenv.py index 04bd9ee5c32f..71af361e85b6 100644 --- a/mesonbuild/mdevenv.py +++ b/mesonbuild/mdevenv.py @@ -98,10 +98,8 @@ def bash_completion_files(b: build.Build, install_data: 'InstallData') -> T.List dep = PkgConfigDependency('bash-completion', b.environment, {'required': False, 'silent': True, 'version': ['>=2.10'], 'native': MachineChoice.HOST}) if dep.found(): - prefix = b.environment.coredata.optstore.get_value_for_untyped(OptionKey('prefix')) - assert isinstance(prefix, str), 'for mypy' - datadir = b.environment.coredata.optstore.get_value_for_untyped(OptionKey('datadir')) - assert isinstance(datadir, str), 'for mypy' + prefix = b.environment.coredata.optstore.get_value_for(OptionKey('prefix'), str) + datadir = b.environment.coredata.optstore.get_value_for(OptionKey('datadir'), str) datadir_abs = os.path.join(prefix, datadir) completionsdir = dep.get_variable(pkgconfig='completionsdir', pkgconfig_define=(('datadir', datadir_abs),)) assert isinstance(completionsdir, str), 'for mypy' @@ -186,7 +184,7 @@ def run(options: argparse.Namespace) -> int: b = build.load(options.builddir) workdir = options.workdir or options.builddir - need_vsenv = T.cast('bool', b.environment.coredata.optstore.get_value_for_untyped(OptionKey('vsenv'))) + need_vsenv = b.environment.coredata.optstore.get_value_for(OptionKey('vsenv'), bool) setup_vsenv(need_vsenv) # Call it before get_env to get vsenv vars as well dump_fmt = options.dump_format if options.dump else None devenv, varnames = get_env(b, dump_fmt) diff --git a/mesonbuild/mdist.py b/mesonbuild/mdist.py index ff2af486734f..7006c4d13e4e 100644 --- a/mesonbuild/mdist.py +++ b/mesonbuild/mdist.py @@ -381,7 +381,7 @@ def run(options: argparse.Namespace) -> int: if not buildfile.is_file(): raise MesonException(f'Directory {options.wd!r} does not seem to be a Meson build directory.') b = build.load(options.wd) - need_vsenv = T.cast('bool', b.environment.coredata.optstore.get_value_for_untyped(OptionKey('vsenv'))) + need_vsenv = b.environment.coredata.optstore.get_value_for(OptionKey('vsenv'), bool) setup_vsenv(need_vsenv) src_root = b.environment.source_dir bld_root = b.environment.build_dir diff --git a/mesonbuild/minit.py b/mesonbuild/minit.py index c0a7d0cde787..b57b264e0be9 100644 --- a/mesonbuild/minit.py +++ b/mesonbuild/minit.py @@ -193,7 +193,7 @@ def run(options: Arguments) -> int: raise SystemExit b = build.load(options.builddir) - need_vsenv = T.cast('bool', b.environment.coredata.optstore.get_value_for_untyped(OptionKey('vsenv'))) + need_vsenv = b.environment.coredata.optstore.get_value_for(OptionKey('vsenv'), bool) vsenv_active = mesonlib.setup_vsenv(need_vsenv) if vsenv_active: mlog.log(mlog.green('INFO:'), 'automatically activated MSVC compiler environment') diff --git a/mesonbuild/minstall.py b/mesonbuild/minstall.py index 860caf8845c1..4316a08fcdb1 100644 --- a/mesonbuild/minstall.py +++ b/mesonbuild/minstall.py @@ -870,9 +870,9 @@ def run(opts: 'ArgumentType') -> int: sys.exit('Install data not found. Run this command in build directory root.') if not opts.no_rebuild: b = build.load(opts.wd) - need_vsenv = T.cast('bool', b.environment.coredata.optstore.get_value_for_untyped(OptionKey('vsenv'))) + need_vsenv = b.environment.coredata.optstore.get_value_for(OptionKey('vsenv'), bool) setup_vsenv(need_vsenv) - backend = T.cast('str', b.environment.coredata.optstore.get_value_for_untyped(OptionKey('backend'))) + backend = b.environment.coredata.optstore.get_value_for(OptionKey('backend'), str) if not rebuild_all(opts.wd, backend): sys.exit(-1) os.chdir(opts.wd) diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index 1ea05d56d5a2..d569a78c2444 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -166,7 +166,7 @@ def list_install_plan(installdata: backends.InstallData) -> T.Dict[str, T.Dict[s return plan def get_target_dir(coredata: cdata.CoreData, subdir: str) -> str: - if coredata.optstore.get_value_for_untyped(OptionKey('layout')) == 'flat': + if coredata.optstore.get_value_for(OptionKey('layout'), str) == 'flat': return 'meson-out' else: return subdir diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py index 267ee2f4673d..fbdf379c30a9 100644 --- a/mesonbuild/modules/__init__.py +++ b/mesonbuild/modules/__init__.py @@ -159,6 +159,7 @@ def test(self, args: T.Tuple[str, T.Union[build.Executable, build.Jar, Program, # TODO: Use interpreter internal API, but we need to go through @typed_kwargs self._interpreter.func_test(self.current_node, real_args, kwargs) + # TODO: get rid of this def get_option(self, name: str, subproject: str = '', machine: MachineChoice = MachineChoice.HOST) -> ElementaryOptionValues: return self.environment.coredata.optstore.get_value_for_untyped(OptionKey(name, subproject, machine)) diff --git a/mesonbuild/modules/cmake.py b/mesonbuild/modules/cmake.py index 3342f63ce2fc..5769a51d08ff 100644 --- a/mesonbuild/modules/cmake.py +++ b/mesonbuild/modules/cmake.py @@ -307,8 +307,7 @@ def write_basic_package_version_file(self, state: ModuleState, args: TYPE_var, k pkgroot = pkgroot_name = kwargs['install_dir'] if pkgroot is None: - libdir = state.environment.coredata.optstore.get_value_for_untyped(OptionKey('libdir')) - assert isinstance(libdir, str), 'for mypy' + libdir = state.environment.coredata.optstore.get_value_for(OptionKey('libdir'), str) pkgroot = os.path.join(libdir, 'cmake', name) pkgroot_name = os.path.join('{libdir}', 'cmake', name) @@ -380,8 +379,7 @@ def configure_package_config_file(self, state: ModuleState, args: TYPE_var, kwar install_dir = kwargs['install_dir'] if install_dir is None: - libdir = state.environment.coredata.optstore.get_value_for_untyped(OptionKey('libdir')) - assert isinstance(libdir, str), 'for mypy' + libdir = state.environment.coredata.optstore.get_value_for(OptionKey('libdir'), str) install_dir = os.path.join(libdir, 'cmake', name) conf = kwargs['configuration'] @@ -389,8 +387,7 @@ def configure_package_config_file(self, state: ModuleState, args: TYPE_var, kwar FeatureNew.single_use('cmake.configure_package_config_file dict as configuration', '0.62.0', state.subproject, location=state.current_node) conf = build.ConfigurationData(conf) - prefix = state.environment.coredata.optstore.get_value_for_untyped(OptionKey('prefix')) - assert isinstance(prefix, str), 'for mypy' + prefix = state.environment.coredata.optstore.get_value_for(OptionKey('prefix'), str) abs_install_dir = install_dir if not os.path.isabs(abs_install_dir): abs_install_dir = os.path.join(prefix, install_dir) diff --git a/mesonbuild/modules/external_project.py b/mesonbuild/modules/external_project.py index 039e0baf5f4c..e3626345b861 100644 --- a/mesonbuild/modules/external_project.py +++ b/mesonbuild/modules/external_project.py @@ -76,18 +76,10 @@ def __init__(self, self.src_dir = Path(self.env.get_source_dir(), self.subdir) self.build_dir = Path(self.env.get_build_dir(), self.subdir, 'build') self.install_dir = Path(self.env.get_build_dir(), self.subdir, 'dist') - _p = self.env.coredata.optstore.get_value_for_untyped(OptionKey('prefix')) - assert isinstance(_p, str), 'for mypy' - self.prefix = Path(_p) - _l = self.env.coredata.optstore.get_value_for_untyped(OptionKey('libdir')) - assert isinstance(_l, str), 'for mypy' - self.libdir = Path(_l) - _l = self.env.coredata.optstore.get_value_for_untyped(OptionKey('bindir')) - assert isinstance(_l, str), 'for mypy' - self.bindir = Path(_l) - _i = self.env.coredata.optstore.get_value_for_untyped(OptionKey('includedir')) - assert isinstance(_i, str), 'for mypy' - self.includedir = Path(_i) + self.prefix = Path(self.env.coredata.optstore.get_value_for(OptionKey('prefix'), str)) + self.libdir = Path(self.env.coredata.optstore.get_value_for(OptionKey('libdir'), str)) + self.bindir = Path(self.env.coredata.optstore.get_value_for(OptionKey('bindir'), str)) + self.includedir = Path(self.env.coredata.optstore.get_value_for(OptionKey('includedir'), str)) self.name = self.src_dir.name self.prefix = self._cygpath_convert(self.prefix) diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index 8dd37499b90d..203b08b32e68 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -525,8 +525,7 @@ def compile_resources(self, state: 'ModuleState', args: T.Tuple[str, 'FileOrStri if gresource: # Only one target for .gresource files return ModuleReturnValue(target_c, [target_c]) - install_dir = kwargs['install_dir'] or state.environment.coredata.optstore.get_value_for_untyped(OptionKey('includedir')) - assert isinstance(install_dir, str), 'for mypy' + install_dir = kwargs['install_dir'] or state.environment.coredata.optstore.get_value_for(OptionKey('includedir'), str) target_h = GResourceHeaderTarget( f'{target_name}_h', state.subdir, @@ -922,8 +921,7 @@ def _get_langs_compilers_flags(state: 'ModuleState', langs_compilers: T.List[T.T if state.project_args.get(lang): cflags += state.project_args[lang] if OptionKey('b_sanitize') in compiler.base_options: - sanitize = state.environment.coredata.optstore.get_value_for_untyped('b_sanitize') - assert isinstance(sanitize, list) + sanitize = state.environment.coredata.optstore.get_value_for(OptionKey('b_sanitize'), list) cflags += compiler.sanitizer_compile_args(None, sanitize) # These must be first in ldflags if 'address' in sanitize: @@ -1683,8 +1681,7 @@ def gdbus_codegen(self, state: 'ModuleState', args: T.Tuple[str, T.Optional[T.Un targets = [] install_header = kwargs['install_header'] - install_dir = kwargs['install_dir'] or state.environment.coredata.optstore.get_value_for_untyped(OptionKey('includedir')) - assert isinstance(install_dir, str), 'for mypy' + install_dir = kwargs['install_dir'] or state.environment.coredata.optstore.get_value_for(OptionKey('includedir'), str) output = namebase + '.c' # Added in https://gitlab.gnome.org/GNOME/glib/commit/e4d68c7b3e8b01ab1a4231bf6da21d045cb5a816 (2.55.2) @@ -2052,13 +2049,12 @@ def _make_mkenum_impl( cmd: T.List[str], *, install: bool = False, - install_dir: T.Optional[T.Sequence[T.Union[str, bool]]] = None, + install_dir: T.Optional[T.Union[str, Literal[False]]] = None, depends: T.Optional[T.Sequence[build.BuildTargetTypes]] = None ) -> build.CustomTarget: real_cmd: CommandList = [self._find_tool(state, 'glib-mkenums')] real_cmd.extend(cmd) - _install_dir = install_dir or state.environment.coredata.optstore.get_value_for_untyped(OptionKey('includedir')) - assert isinstance(_install_dir, str), 'for mypy' + _install_dir = install_dir or state.environment.coredata.optstore.get_value_for(OptionKey('includedir'), str) return CustomTarget( output, @@ -2269,8 +2265,7 @@ def generate_vapi(self, state: 'ModuleState', args: T.Tuple[str], kwargs: 'Gener cmd.append(gir_file) vapi_output = library + '.vapi' - datadir = state.environment.coredata.optstore.get_value_for_untyped(OptionKey('datadir')) - assert isinstance(datadir, str), 'for mypy' + datadir = state.environment.coredata.optstore.get_value_for(OptionKey('datadir'), str) install_dir = kwargs['install_dir'] or os.path.join(datadir, 'vala', 'vapi') if kwargs['install']: diff --git a/mesonbuild/modules/hotdoc.py b/mesonbuild/modules/hotdoc.py index 5b1b44165184..ca6c5eebbab4 100644 --- a/mesonbuild/modules/hotdoc.py +++ b/mesonbuild/modules/hotdoc.py @@ -303,7 +303,7 @@ def make_targets(self) -> T.Tuple[HotdocTarget, mesonlib.ExecutableSerialisation for path in self.include_paths: self.cmd.extend(['--include-path', path]) - if self.state.environment.coredata.optstore.get_value_for_untyped(OptionKey('werror', subproject=self.state.subproject)): + if self.state.environment.coredata.optstore.get_value_for(OptionKey('werror', subproject=self.state.subproject), bool): self.cmd.append('--fatal-warnings') self.generate_hotdoc_config() diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py index a4a912096654..760a8c0997ca 100644 --- a/mesonbuild/modules/i18n.py +++ b/mesonbuild/modules/i18n.py @@ -412,8 +412,7 @@ def gettext(self, state: 'ModuleState', args: T.Tuple[str], kwargs: 'Gettext') - targets.append(pottarget) install = kwargs['install'] - install_dir = kwargs['install_dir'] or state.environment.coredata.optstore.get_value_for_untyped(OptionKey('localedir')) - assert isinstance(install_dir, str), 'for mypy' + install_dir = kwargs['install_dir'] or state.environment.coredata.optstore.get_value_for(OptionKey('localedir'), str) if not languages: languages = read_linguas(path.join(state.environment.source_dir, state.subdir)) for l in languages: diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py index 25f2cc780fc3..372251801f99 100644 --- a/mesonbuild/modules/pkgconfig.py +++ b/mesonbuild/modules/pkgconfig.py @@ -75,11 +75,6 @@ class GenerateKw(TypedDict): ) -def _as_str(obj: object) -> str: - assert isinstance(obj, str) - return obj - - @dataclass class MetaData: @@ -545,7 +540,7 @@ def _generate_pkgconfig_file(self, state: ModuleState, deps: DependenciesHelper, else: pure_path_class = state.environment.machines.host.pure_path_class outdir = state.environment.scratch_dir - prefix = pure_path_class(_as_str(coredata.optstore.get_value_for_untyped(OptionKey('prefix')))) + prefix = pure_path_class(coredata.optstore.get_value_for(OptionKey('prefix'), str)) if pkgroot: prefix = self._get_relocatable_prefix(pkgroot, prefix, pure_path_class) # relocatable paths will never have a drive letter @@ -558,7 +553,7 @@ def _generate_pkgconfig_file(self, state: ModuleState, deps: DependenciesHelper, if optname == 'prefix': ofile.write('prefix={}\n'.format(self._escape(prefix))) else: - dirpath = PurePath(_as_str(coredata.optstore.get_value_for_untyped(OptionKey(optname)))) + dirpath = PurePath(coredata.optstore.get_value_for(OptionKey(optname), str)) ofile.write('{}={}\n'.format(optname, self._escape('${prefix}' / dirpath))) if uninstalled and not dataonly: ofile.write('srcdir={}\n'.format(self._escape(srcdir))) @@ -779,13 +774,13 @@ def parse_variable_list(vardict: T.Dict[str, str]) -> T.List[T.Tuple[str, str]]: if pkgroot is None: m = state.environment.machines.host if m.is_freebsd(): - pkgroot = os.path.join(_as_str(state.environment.coredata.optstore.get_value_for_untyped(OptionKey('prefix'))), 'libdata', 'pkgconfig') + pkgroot = os.path.join(state.environment.coredata.optstore.get_value_for(OptionKey('prefix'), str), 'libdata', 'pkgconfig') pkgroot_name = os.path.join('{prefix}', 'libdata', 'pkgconfig') elif m.is_haiku(): - pkgroot = os.path.join(_as_str(state.environment.coredata.optstore.get_value_for_untyped(OptionKey('prefix'))), 'develop', 'lib', 'pkgconfig') + pkgroot = os.path.join(state.environment.coredata.optstore.get_value_for(OptionKey('prefix'), str), 'develop', 'lib', 'pkgconfig') pkgroot_name = os.path.join('{prefix}', 'develop', 'lib', 'pkgconfig') else: - pkgroot = os.path.join(_as_str(state.environment.coredata.optstore.get_value_for_untyped(OptionKey('libdir'))), 'pkgconfig') + pkgroot = os.path.join(state.environment.coredata.optstore.get_value_for(OptionKey('libdir'), str), 'pkgconfig') pkgroot_name = os.path.join('{libdir}', 'pkgconfig') relocatable = state.get_option('pkgconfig.relocatable') self._generate_pkgconfig_file(state, deps, subdirs, name, description, url, diff --git a/mesonbuild/modules/python.py b/mesonbuild/modules/python.py index 904dbf5b8724..95aad0abc9b2 100644 --- a/mesonbuild/modules/python.py +++ b/mesonbuild/modules/python.py @@ -116,8 +116,7 @@ class PythonInstallation(ProgramHolder['PythonExternalProgram']): def __init__(self, python: 'PythonExternalProgram', interpreter: 'Interpreter'): ProgramHolder.__init__(self, python, interpreter) info = python.info - prefix = self.interpreter.environment.coredata.optstore.get_value_for_untyped(OptionKey('prefix')) - assert isinstance(prefix, str), 'for mypy' + prefix = self.interpreter.environment.coredata.optstore.get_value_for(OptionKey('prefix'), str) if python.build_config: self.version = python.build_config['language']['version'] @@ -178,7 +177,7 @@ def extension_module_method(self, args: T.Tuple[str, T.List[BuildTargetSource]], self.current_node) limited_api_version = kwargs.pop('limited_api') - allow_limited_api = self.interpreter.environment.coredata.optstore.get_value_for_untyped(OptionKey('python.allow_limited_api')) + allow_limited_api = self.interpreter.environment.coredata.optstore.get_value_for(OptionKey('python.allow_limited_api'), bool) if limited_api_version != '' and allow_limited_api: target_suffix = self.limited_api_suffix @@ -217,7 +216,7 @@ def extension_module_method(self, args: T.Tuple[str, T.List[BuildTargetSource]], new_link_args = mesonlib.extract_as_list(kwargs, 'link_args') - is_debug = self.interpreter.environment.coredata.optstore.get_value_for_untyped('debug') + is_debug = self.interpreter.environment.coredata.optstore.get_value_for(OptionKey('debug'), bool) if is_debug: new_link_args.append(python_windows_debug_link_exception) else: @@ -266,7 +265,7 @@ def _dependency_method_impl(self, kwargs: DependencyObjectKWs) -> Dependency: if dep is not None: return dep - build_config = self.interpreter.environment.coredata.optstore.get_value_for_untyped(OptionKey('python.build_config')) + build_config = self.interpreter.environment.coredata.optstore.get_value_for(OptionKey('python.build_config'), str) new_kwargs = kwargs.copy() new_kwargs['required'] = False @@ -402,7 +401,7 @@ def __init__(self, interpreter: 'Interpreter') -> None: def _get_install_scripts(self) -> T.List[mesonlib.ExecutableSerialisation]: backend = self.interpreter.backend ret = [] - optlevel = self.interpreter.environment.coredata.optstore.get_value_for_untyped(OptionKey('python.bytecompile')) + optlevel = self.interpreter.environment.coredata.optstore.get_value_for(OptionKey('python.bytecompile'), int) if optlevel == -1: return ret if not any(PythonExternalProgram.run_bytecompile.values()): @@ -469,7 +468,7 @@ def _get_win_pythonpath(name_or_path: str) -> T.Optional[str]: return None def _find_installation_impl(self, state: 'ModuleState', display_name: str, name_or_path: str, required: bool) -> MaybePythonProg: - build_config = self.interpreter.environment.coredata.optstore.get_value_for_untyped(OptionKey('python.build_config')) + build_config = self.interpreter.environment.coredata.optstore.get_value_for(OptionKey('python.build_config'), str) if not name_or_path: python = PythonExternalProgram('python3', mesonlib.python_command, build_config_path=build_config) diff --git a/mesonbuild/modules/rust.py b/mesonbuild/modules/rust.py index bae404f86f1f..3e4a858513f5 100644 --- a/mesonbuild/modules/rust.py +++ b/mesonbuild/modules/rust.py @@ -27,6 +27,7 @@ from ..interpreter.interpreterobjects import Doctest from ..mesonlib import (is_parent_path, File, MachineChoice, MesonException, PerMachine) from ..programs import ExternalProgram, NonExistingExternalProgram +from ..options import OptionKey if T.TYPE_CHECKING: from . import ModuleState @@ -922,11 +923,7 @@ def bindgen(self, state: ModuleState, args: T.List, kwargs: FuncBindgen) -> Modu if self._bindgen_rust_target and '--rust-target' not in cmd: cmd.extend(['--rust-target', self._bindgen_rust_target]) if self._bindgen_set_std and '--rust-edition' not in cmd: - try: - rust_std = state.environment.coredata.optstore.get_value_for_untyped('rust_std') - except KeyError: - rust_std = 'none' - assert isinstance(rust_std, str), 'for mypy' + rust_std = state.environment.coredata.optstore.get_value_for(OptionKey('rust_std'), str, default='none') if rust_std != 'none': cmd.extend(['--rust-edition', rust_std]) cmd.append('--') diff --git a/mesonbuild/msetup.py b/mesonbuild/msetup.py index 3267376187f3..e22f3525e2ab 100644 --- a/mesonbuild/msetup.py +++ b/mesonbuild/msetup.py @@ -306,9 +306,9 @@ def _generate(self, env: environment.Environment, capture: bool, vslite_ctx: T.O # collect warnings about unsupported build configurations; must be done after full arg processing # by Interpreter() init, but this is most visible at the end - if env.coredata.optstore.get_value_for_untyped('backend') == 'xcode': + if env.coredata.optstore.get_value_for(OptionKey('backend'), str) == 'xcode': mlog.warning('xcode backend is currently unmaintained, patches welcome') - if env.coredata.optstore.get_value_for_untyped('layout') == 'flat': + if env.coredata.optstore.get_value_for(OptionKey('layout'), str) == 'flat': mlog.warning('-Dlayout=flat is unsupported and probably broken. It was a failed experiment at ' 'making Windows build artifacts runnable while uninstalled, due to PATH considerations, ' 'but was untested by CI and anyways breaks reasonable use of conflicting targets in different subdirs. ' diff --git a/mesonbuild/mtest.py b/mesonbuild/mtest.py index 89d7d71fb183..8586b9f45946 100644 --- a/mesonbuild/mtest.py +++ b/mesonbuild/mtest.py @@ -2296,11 +2296,11 @@ def run(options: argparse.Namespace) -> int: return 1 b = build.load(options.wd) - need_vsenv = T.cast('bool', b.environment.coredata.optstore.get_value_for_untyped(OptionKey('vsenv'))) + need_vsenv = b.environment.coredata.optstore.get_value_for(OptionKey('vsenv'), bool) setup_vsenv(need_vsenv) if not options.no_rebuild: - backend = b.environment.coredata.optstore.get_value_for_untyped(OptionKey('backend')) + backend = b.environment.coredata.optstore.get_value_for(OptionKey('backend'), str) if backend == 'none': # nothing to build... options.no_rebuild = True diff --git a/mesonbuild/munstable_coredata.py b/mesonbuild/munstable_coredata.py index 48fab0d6dc9d..fea6c909b9d3 100644 --- a/mesonbuild/munstable_coredata.py +++ b/mesonbuild/munstable_coredata.py @@ -53,7 +53,7 @@ def run(options): print('') coredata = cdata.load(options.builddir) - backend = coredata.optstore.get_value_for_untyped(OptionKey('backend')) + backend = coredata.optstore.get_value_for(OptionKey('backend'), str) for k, v in sorted(coredata.__dict__.items()): if k in {'backend_options', 'base_options', 'builtins', 'compiler_options', 'user_options'}: # use `meson configure` to view these diff --git a/mesonbuild/options.py b/mesonbuild/options.py index 574cb262ef6d..fe0ec337b77a 100644 --- a/mesonbuild/options.py +++ b/mesonbuild/options.py @@ -1082,8 +1082,7 @@ def set_option(self, key: OptionKey, new_value: ElementaryOptionValues, first_in assert isinstance(new_value, str), 'for mypy' new_value = self.sanitize_prefix(new_value) elif self.is_builtin_option(key): - prefix = self.get_value_for_untyped('prefix') - assert isinstance(prefix, str), 'for mypy' + prefix = self.get_value_for(OptionKey('prefix'), str) new_value = self.sanitize_dir_option_value(prefix, key, new_value) try: diff --git a/mesonbuild/scripts/regen_checker.py b/mesonbuild/scripts/regen_checker.py index adbb442f568c..ff10f9ceb199 100644 --- a/mesonbuild/scripts/regen_checker.py +++ b/mesonbuild/scripts/regen_checker.py @@ -44,8 +44,7 @@ def run(args: T.List[str]) -> int: with open(coredata_file, 'rb') as f: coredata = pickle.load(f) assert isinstance(coredata, CoreData) - backend = coredata.optstore.get_value_for_untyped(OptionKey('backend')) - assert isinstance(backend, str) + backend = coredata.optstore.get_value_for(OptionKey('backend'), str) regen_timestamp = os.stat(dumpfile).st_mtime if need_regen(regeninfo, regen_timestamp): regen(regeninfo, coredata.meson_command, backend) From 5415f9a736b886a2b77331708a341b524b6bf9ac Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 11 Mar 2026 12:12:06 -0700 Subject: [PATCH 13/22] modules: replace state.get_option with OptionStore type safe getters --- mesonbuild/modules/__init__.py | 6 ------ mesonbuild/modules/hotdoc.py | 4 +++- mesonbuild/modules/pkgconfig.py | 2 +- mesonbuild/modules/python.py | 4 ++-- mesonbuild/modules/rust.py | 6 ++---- mesonbuild/modules/snippets.py | 3 ++- 6 files changed, 10 insertions(+), 15 deletions(-) diff --git a/mesonbuild/modules/__init__.py b/mesonbuild/modules/__init__.py index fbdf379c30a9..27e24873b773 100644 --- a/mesonbuild/modules/__init__.py +++ b/mesonbuild/modules/__init__.py @@ -23,7 +23,6 @@ from ..interpreterbase import TYPE_var, TYPE_kwargs from ..programs import Program from ..dependencies import Dependency - from ..options import ElementaryOptionValues class ModuleState: """Object passed to all module methods. @@ -159,11 +158,6 @@ def test(self, args: T.Tuple[str, T.Union[build.Executable, build.Jar, Program, # TODO: Use interpreter internal API, but we need to go through @typed_kwargs self._interpreter.func_test(self.current_node, real_args, kwargs) - # TODO: get rid of this - def get_option(self, name: str, subproject: str = '', - machine: MachineChoice = MachineChoice.HOST) -> ElementaryOptionValues: - return self.environment.coredata.optstore.get_value_for_untyped(OptionKey(name, subproject, machine)) - def is_user_defined_option(self, name: str, subproject: str = '', machine: MachineChoice = MachineChoice.HOST, lang: T.Optional[str] = None) -> bool: diff --git a/mesonbuild/modules/hotdoc.py b/mesonbuild/modules/hotdoc.py index ca6c5eebbab4..7f42a11fac4a 100644 --- a/mesonbuild/modules/hotdoc.py +++ b/mesonbuild/modules/hotdoc.py @@ -329,7 +329,9 @@ def make_targets(self) -> T.Tuple[HotdocTarget, mesonlib.ExecutableSerialisation install_script = None if install: - datadir = os.path.join(self.state.get_option('prefix'), self.state.get_option('datadir')) + datadir = os.path.join( + self.state.environment.coredata.optstore.get_value_for(OptionKey('prefix'), str), + self.state.environment.coredata.optstore.get_value_for(OptionKey('datadir'), str)) devhelp = self.kwargs.get('devhelp_activate', False) if not isinstance(devhelp, bool): FeatureDeprecated.single_use('hotdoc.generate_doc() devhelp_activate must be boolean', '1.1.0', self.state.subproject) diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py index 372251801f99..ddf4a8ce7c47 100644 --- a/mesonbuild/modules/pkgconfig.py +++ b/mesonbuild/modules/pkgconfig.py @@ -782,7 +782,7 @@ def parse_variable_list(vardict: T.Dict[str, str]) -> T.List[T.Tuple[str, str]]: else: pkgroot = os.path.join(state.environment.coredata.optstore.get_value_for(OptionKey('libdir'), str), 'pkgconfig') pkgroot_name = os.path.join('{libdir}', 'pkgconfig') - relocatable = state.get_option('pkgconfig.relocatable') + relocatable = state.environment.coredata.optstore.get_value_for(OptionKey('pkgconfig.relocatable'), bool) self._generate_pkgconfig_file(state, deps, subdirs, name, description, url, version, license, pcfile, conflicts, variables, unescaped_variables, False, dataonly, diff --git a/mesonbuild/modules/python.py b/mesonbuild/modules/python.py index 95aad0abc9b2..c14f464c4fd6 100644 --- a/mesonbuild/modules/python.py +++ b/mesonbuild/modules/python.py @@ -86,13 +86,13 @@ def _get_path(self, state: T.Optional['ModuleState'], key: str) -> str: if not state: # This happens only from run_project_tests.py return rel_path - value = T.cast('str', state.get_option(f'python.{key}dir')) + value = state.environment.coredata.optstore.get_value_for(OptionKey(f'python.{key}dir'), str) if value: if state.is_user_defined_option('python.install_env'): raise mesonlib.MesonException(f'python.{key}dir and python.install_env are mutually exclusive') return value - install_env = state.get_option('python.install_env') + install_env = state.environment.coredata.optstore.get_value_for(OptionKey('python.install_env'), str) if install_env == 'auto': install_env = 'venv' if self.info['is_venv'] else 'system' diff --git a/mesonbuild/modules/rust.py b/mesonbuild/modules/rust.py index 3e4a858513f5..16ccd2bc592f 100644 --- a/mesonbuild/modules/rust.py +++ b/mesonbuild/modules/rust.py @@ -874,8 +874,7 @@ def bindgen(self, state: ModuleState, args: T.List, kwargs: FuncBindgen) -> Modu raise InterpreterException(f'Unknown file type extension for: {name}') # We only want include directories and defines, other things may not be valid - cargs = state.get_option(f'{language}_args', state.subproject) - assert isinstance(cargs, list), 'for mypy' + cargs = state.environment.coredata.optstore.get_value_for(OptionKey(f'{language}_args', state.subproject), list) for a in itertools.chain(state.global_args.get(language, []), state.project_args.get(language, []), cargs): if a.startswith(('-I', '/I', '-D', '/D', '-U', '/U')): clang_args.append(a) @@ -885,8 +884,7 @@ def bindgen(self, state: ModuleState, args: T.List, kwargs: FuncBindgen) -> Modu # Add the C++ standard to the clang arguments. Attempt to translate VS # extension versions into the nearest standard version - std = state.get_option(f'{language}_std') - assert isinstance(std, str), 'for mypy' + std = state.environment.coredata.optstore.get_value_for(OptionKey(f'{language}_std'), str) if std.startswith('vc++'): if std.endswith('latest'): mlog.warning('Attempting to translate vc++latest into a clang compatible version.', diff --git a/mesonbuild/modules/snippets.py b/mesonbuild/modules/snippets.py index bfc8d7ab7e09..611e5c66b562 100644 --- a/mesonbuild/modules/snippets.py +++ b/mesonbuild/modules/snippets.py @@ -22,6 +22,7 @@ from ..interpreterbase import KwargInfo, typed_kwargs, typed_pos_args from ..interpreter.type_checking import NoneType from .. import mesonlib +from ..options import OptionKey if T.TYPE_CHECKING: from typing_extensions import TypedDict @@ -63,7 +64,7 @@ def symbol_visibility_header_method(self, state: ModuleState, args: T.Tuple[str] static_compilation = kwargs['static_compilation'] or f'{namespace}_STATIC_COMPILATION' static_only = kwargs['static_only'] if static_only is None: - default_library = state.get_option('default_library') + default_library = state.environment.coredata.optstore.get_value_for(OptionKey('default_library'), str) static_only = default_library == 'static' content = textwrap.dedent('''\ // SPDX-license-identifier: 0BSD OR CC0-1.0 OR WTFPL OR Apache-2.0 OR LGPL-2.0-or-later From eb043310b7d6c068bd3ef89c311c3f3e9ece425e Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 11 Mar 2026 12:28:37 -0700 Subject: [PATCH 14/22] Make use of type safe get_option_for_target There are still a few uses of the unsafe variant, manly around compilers and some wrappers that need to be removed. Additionally, this work allows some cleanups to remove try/except blocks --- mesonbuild/backend/backends.py | 1 + mesonbuild/backend/ninjabackend.py | 7 +-- mesonbuild/backend/vs2010backend.py | 2 +- mesonbuild/build.py | 19 +++---- mesonbuild/compilers/compilers.py | 53 +++++++++----------- mesonbuild/compilers/rust.py | 2 +- mesonbuild/interpreter/interpreterobjects.py | 3 +- 7 files changed, 36 insertions(+), 51 deletions(-) diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index d035efea2bb1..99e6dc9f30a5 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -2089,6 +2089,7 @@ def is_unity(self, target: build.BuildTarget) -> bool: return target.subproject != '' raise MesonException(f'Internal error: invalid option type for "unity": {val}') + # TODO: get rid of this def get_target_option(self, target: build.BuildTarget, name: T.Union[str, OptionKey]) -> ElementaryOptionValues: if isinstance(name, str): key = OptionKey(name, subproject=target.subproject) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 27d737d63af2..bccb0bc1daba 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -3339,11 +3339,8 @@ def quote_make_target(targetName: str) -> str: def target_uses_import_std(self, target: build.BuildTarget) -> bool: if 'cpp' not in target.compilers: return False - try: - if self.environment.coredata.optstore.get_option_for_target_untyped(target, 'cpp_importstd') == 'true': - return True - except KeyError: - return False + return self.environment.coredata.optstore.get_option_for_target( + target, OptionKey('cpp_importstd'), str, default='false') == 'true' def handle_cpp_import_std(self, target: build.BuildTarget, compiler): istd_args = [] diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index e1216461c41c..07089b31acb8 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -1383,7 +1383,7 @@ def add_non_makefile_vcxproj_elements( # Exception handling has to be set in the xml in addition to the "AdditionalOptions" because otherwise # cl will give warning D9025: overriding '/Ehs' with cpp_eh value if 'cpp' in target.compilers: - eh = self.environment.coredata.optstore.get_option_for_target_untyped(target, OptionKey('cpp_eh', machine=target.for_machine)) + eh = self.environment.coredata.optstore.get_option_for_target(target, OptionKey('cpp_eh', machine=target.for_machine), str) if eh == 'a': ET.SubElement(clconf, 'ExceptionHandling').text = 'Async' elif eh == 's': diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 1517ff06a32c..69d2ff7fe61e 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -1051,7 +1051,7 @@ def process_compilers_late(self) -> None: # In the case of cython it's possible that we have an # implementation detail language - if self.uses_cython() and lang == self.environment.coredata.optstore.get_option_for_target_untyped(self, 'cython_language'): + if self.uses_cython() and lang == self.environment.coredata.optstore.get_option_for_target(self, OptionKey('cython_language'), str): self.compilers[lang] = self.environment.coredata.compilers[self.for_machine][lang] is_error = False @@ -1186,8 +1186,7 @@ def process_compilers(self) -> T.List[Language]: if 'vala' in self.compilers and 'c' not in self.compilers: self.compilers['c'] = self.all_compilers['c'] if 'cython' in self.compilers: - _value = self.environment.coredata.optstore.get_option_for_target_untyped(self, 'cython_language') - assert isinstance(_value, str), 'for mypy' + _value = self.environment.coredata.optstore.get_option_for_target(self, OptionKey('cython_language'), str) value = T.cast('Language', _value) try: self.compilers[value] = self.all_compilers[value] @@ -1449,9 +1448,7 @@ def _extract_pic_pie(self, kwargs: T.Union[StaticLibraryKeywordArguments, Execut if kwargs.get(arg) is not None: return kwargs[arg] elif k in self.environment.coredata.optstore: - val = self.environment.coredata.optstore.get_option_for_target_untyped(self, k) - assert isinstance(val, bool), 'for mypy' - return val + return self.environment.coredata.optstore.get_option_for_target(self, k, bool) return False def install_dir_names(self) -> T.List[T.Optional[str]]: @@ -2385,8 +2382,7 @@ def post_init(self) -> None: self.outputs[0] = self.filename def determine_default_prefix_and_suffix(self) -> T.Tuple[str, str]: - scheme = self.environment.coredata.optstore.get_option_for_target_untyped(self, 'namingscheme') - assert isinstance(scheme, str), 'for mypy' + scheme = self.environment.coredata.optstore.get_option_for_target(self, OptionKey('namingscheme'), str) if scheme == 'platform': schemename = self.get_platform_scheme_name() prefix, suffix = DEFAULT_STATIC_LIBRARY_NAMES[schemename] @@ -2418,9 +2414,7 @@ def determine_default_prefix_and_suffix(self) -> T.Tuple[str, str]: suffix = 'a' if 'c' in self.compilers and self.compilers['c'].get_id() == 'tasking' and not self.prelink: key = OptionKey('b_lto', self.subproject, self.for_machine) - v = self.environment.coredata.optstore.get_option_for_target_untyped(self, key) - assert isinstance(v, bool), 'for mypy' - if v: + if self.environment.coredata.optstore.get_option_for_target(self, key, bool): suffix = 'ma' return (prefix, suffix) @@ -2568,8 +2562,7 @@ def get_default_install_dir(self) -> T.Tuple[str, str]: return self.environment.get_shared_lib_dir(), '{libdir_shared}' def determine_naming_info(self) -> T.Tuple[str, str, str, str, bool]: - scheme = self.environment.coredata.optstore.get_option_for_target_untyped(self, 'namingscheme') - assert isinstance(scheme, str), 'for mypy' + scheme = self.environment.coredata.optstore.get_option_for_target(self, OptionKey('namingscheme'), str) if scheme == 'platform': schemename = self.get_platform_scheme_name() prefix, suffix, import_suffix = DEFAULT_SHARED_LIBRARY_NAMES[schemename] diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 3baaf8fb5b49..a2a77cae7497 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -239,22 +239,19 @@ class CompileCheckMode(enum.Enum): } +# TODO: Can we delete this? def option_enabled(boptions: T.Set[OptionKey], target: 'BuildTarget', env: 'Environment', option: T.Union[str, OptionKey]) -> bool: if isinstance(option, str): option = OptionKey(option) - try: - if option not in boptions: - return False - ret = env.coredata.optstore.get_option_for_target_untyped(target, option) - assert isinstance(ret, bool), 'must return bool' # could also be str - return ret - except KeyError: + if option not in boptions: return False + return env.coredata.optstore.get_option_for_target(target, option, bool, default=False) +# TODO: delete this def get_option_value_for_target(env: 'Environment', target: 'BuildTarget', opt: OptionKey, fallback: '_T') -> '_T': """Get the value of an option, or the fallback value.""" try: @@ -274,9 +271,10 @@ def are_asserts_disabled(target: 'BuildTarget', env: 'Environment') -> bool: :param env: the environment :return: whether to disable assertions or not """ - return (env.coredata.optstore.get_option_for_target_untyped(target, 'b_ndebug') == 'true' or - (env.coredata.optstore.get_option_for_target_untyped(target, 'b_ndebug') == 'if-release' and - env.coredata.optstore.get_option_for_target_untyped(target, 'buildtype') in {'release', 'plain'})) + key = OptionKey('b_ndebug', target.subproject, target.for_machine) + return (env.coredata.optstore.get_option_for_target(target, key, str) == 'true' or + (env.coredata.optstore.get_option_for_target(target, key, str) == 'if-release' and + env.coredata.optstore.get_option_for_target(target, key.evolve(name='buildtype'), str) in {'release', 'plain'})) def are_asserts_disabled_for_subproject(subproject: str, env: 'Environment') -> bool: @@ -286,11 +284,12 @@ def are_asserts_disabled_for_subproject(subproject: str, env: 'Environment') -> env.coredata.optstore.get_value_for(key.evolve(name='buildtype'), str) in {'release', 'plain'})) +# TODO: remove use of try/except, use default= instead def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Environment') -> T.List[str]: args: T.List[str] = [] lto = False try: - if env.coredata.optstore.get_option_for_target_untyped(target, 'b_lto'): + if env.coredata.optstore.get_option_for_target(target, OptionKey('b_lto'), bool): num_threads = get_option_value_for_target(env, target, OptionKey('b_lto_threads'), 0) ltomode = get_option_value_for_target(env, target, OptionKey('b_lto_mode'), 'default') args.extend(compiler.get_lto_compile_args( @@ -301,14 +300,12 @@ def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Env except (KeyError, AttributeError): pass try: - clrout = env.coredata.optstore.get_option_for_target_untyped(target, 'b_colorout') - assert isinstance(clrout, str) + clrout = env.coredata.optstore.get_option_for_target(target, OptionKey('b_colorout'), str) args += compiler.get_colorout_args(clrout) except KeyError: pass try: - sanitize = env.coredata.optstore.get_option_for_target_untyped(target, 'b_sanitize') - assert isinstance(sanitize, list) + sanitize = env.coredata.optstore.get_option_for_target(target, OptionKey('b_sanitize'), list) if sanitize == ['none']: sanitize = [] sanitize_args = compiler.sanitizer_compile_args(target, sanitize) @@ -321,7 +318,7 @@ def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Env except KeyError: pass try: - pgo_val = env.coredata.optstore.get_option_for_target_untyped(target, 'b_pgo') + pgo_val = env.coredata.optstore.get_option_for_target(target, OptionKey('b_pgo'), str) if pgo_val == 'generate': args.extend(compiler.get_profile_generate_args()) elif pgo_val == 'use': @@ -329,7 +326,7 @@ def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Env except (KeyError, AttributeError): pass try: - if env.coredata.optstore.get_option_for_target_untyped(target, 'b_coverage'): + if env.coredata.optstore.get_option_for_target(target, OptionKey('b_coverage'), bool): args += compiler.get_coverage_args() except (KeyError, AttributeError): pass @@ -341,8 +338,8 @@ def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Env bitcode = option_enabled(compiler.base_options, target, env, 'b_bitcode') args.extend(compiler.get_embed_bitcode_args(bitcode, lto)) try: - crt_val = env.coredata.optstore.get_option_for_target_untyped(target, 'b_vscrt') - assert isinstance(crt_val, str) + crt_val = env.coredata.optstore.get_option_for_target(target, OptionKey('b_vscrt'), str) + # TODO: Is this attributeError posible? try: args += compiler.get_crt_compile_args(crt_val) except AttributeError: @@ -357,8 +354,8 @@ def get_base_link_args(target: 'BuildTarget', args: T.List[str] = [] build_dir = env.get_build_dir() try: - if env.coredata.optstore.get_option_for_target_untyped(target, 'b_lto'): - if env.coredata.optstore.get_option_for_target_untyped(target, 'werror'): + if env.coredata.optstore.get_option_for_target(target, OptionKey('b_lto'), bool): + if env.coredata.optstore.get_option_for_target(target, OptionKey('werror'), bool): args.extend(linker.get_werror_args()) thinlto_cache_dir = None @@ -380,8 +377,7 @@ def get_base_link_args(target: 'BuildTarget', except (KeyError, AttributeError): pass try: - sanitizer = env.coredata.optstore.get_option_for_target_untyped(target, 'b_sanitize') - assert isinstance(sanitizer, list) + sanitizer = env.coredata.optstore.get_option_for_target(target, OptionKey('b_sanitize'), list) if sanitizer == ['none']: sanitizer = [] sanitizer_args = linker.sanitizer_link_args(target, sanitizer) @@ -394,7 +390,7 @@ def get_base_link_args(target: 'BuildTarget', except KeyError: pass try: - pgo_val = env.coredata.optstore.get_option_for_target_untyped(target, 'b_pgo') + pgo_val = env.coredata.optstore.get_option_for_target(target, OptionKey('b_pgo'), str) if pgo_val == 'generate': args.extend(linker.get_profile_generate_args()) elif pgo_val == 'use': @@ -402,7 +398,7 @@ def get_base_link_args(target: 'BuildTarget', except (KeyError, AttributeError): pass try: - if env.coredata.optstore.get_option_for_target_untyped(target, 'b_coverage'): + if env.coredata.optstore.get_option_for_target(target, OptionKey('b_coverage'), bool): args += linker.get_coverage_link_args() except (KeyError, AttributeError): pass @@ -429,12 +425,9 @@ def get_base_link_args(target: 'BuildTarget', args.extend(linker.get_allow_undefined_link_args()) try: - crt_val = env.coredata.optstore.get_option_for_target_untyped(target, 'b_vscrt') - assert isinstance(crt_val, str) + crt_val = env.coredata.optstore.get_option_for_target(target, OptionKey('b_vscrt'), str) try: - crtargs = linker.get_crt_link_args(crt_val) - assert isinstance(crtargs, list) - args += crtargs + args.extend(linker.get_crt_link_args(crt_val)) except AttributeError: pass except KeyError: diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py index cef1d3f3591e..6282d6a0dec8 100644 --- a/mesonbuild/compilers/rust.py +++ b/mesonbuild/compilers/rust.py @@ -269,7 +269,7 @@ def get_nightly(self, target: T.Optional[BuildTarget]) -> bool: if not target: return self.allow_nightly key = self.form_compileropt_key('nightly') - nightly_opt = self.environment.coredata.optstore.get_option_for_target_untyped(target, key) + nightly_opt = self.environment.coredata.optstore.get_option_for_target(target, key, str) if nightly_opt == 'enabled' and not self.is_nightly: raise EnvironmentException(f'Rust compiler {self.name_string()} is not a nightly compiler as required by the "nightly" option.') return nightly_opt != 'disabled' and self.is_nightly diff --git a/mesonbuild/interpreter/interpreterobjects.py b/mesonbuild/interpreter/interpreterobjects.py index 9e5205a95d47..ec6c13a6c7b6 100644 --- a/mesonbuild/interpreter/interpreterobjects.py +++ b/mesonbuild/interpreter/interpreterobjects.py @@ -27,6 +27,7 @@ from ..dependencies import Dependency, ExternalLibrary, InternalDependency from ..programs import ExternalProgram, Program from ..mesonlib import HoldableObject, listify +from ..options import OptionKey import typing as T @@ -1034,7 +1035,7 @@ def extract_objects_method(self, args: T.Tuple[T.List[T.Union[mesonlib.FileOrStr if self.subproject != self.held_object.subproject: raise InterpreterException('Tried to extract objects from a different subproject.') tobj = self._target_object - unity_value = self.interpreter.coredata.optstore.get_option_for_target_untyped(tobj, "unity") + unity_value = self.interpreter.coredata.optstore.get_option_for_target(tobj, OptionKey("unity"), str) is_unity = (unity_value == 'on' or (unity_value == 'subprojects' and tobj.subproject != '')) return tobj.extract_objects(args[0], is_unity) From dbccdccd9a6b39f9fa257f8fda0f7d782784b66b Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 11 Mar 2026 12:47:21 -0700 Subject: [PATCH 15/22] options: Add a getter for a maybe target --- mesonbuild/options.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mesonbuild/options.py b/mesonbuild/options.py index fe0ec337b77a..26dbfe6cd3bc 100644 --- a/mesonbuild/options.py +++ b/mesonbuild/options.py @@ -933,6 +933,13 @@ def get_option_for_target(self, target: 'BuildTarget', key: OptionKey, raise MesonBugException(f'Expected {key!s} to have type {type_!s}, but had type {type(val)!s}') return val + def get_option_for_maybe_target(self, target: T.Optional[BuildTarget], key: OptionKey, + type_: T.Type[ElementaryOptionType], + *, default: T.Optional[ElementaryOptionType] = None) -> ElementaryOptionType: + if target is not None: + return self.get_option_for_target(target, key, type_, default=default) + return self.get_value_for(key, type_, default=default) + def get_external_args(self, for_machine: MachineChoice, lang: Language) -> T.List[str]: key = OptionKey(f'{lang}_args', machine=for_machine) return self.get_value_for(key, list) From 247f085872c965da6dad144ec7b8d9dcf5046e39 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 11 Mar 2026 15:01:14 -0700 Subject: [PATCH 16/22] compilers: Fix the signature of get_option_{std,compile,link}_args These are allowed to take None for target. This is the only case where the subproject argument is not `target.subproject`. So, to prevent issues where the subproject doesn't match, I've used `typing.overload` to create two signatures. The subproject is only allowed in the case where the target is None, and not in the case where Target is defined. This allows the type checker to enforce that you must have a subproject without a target, and may not have one with. --- mesonbuild/backend/backends.py | 4 +- mesonbuild/backend/ninjabackend.py | 8 +- mesonbuild/backend/vs2010backend.py | 3 +- mesonbuild/backend/xcodebackend.py | 2 +- mesonbuild/compilers/c.py | 86 +++++++++++----- mesonbuild/compilers/compilers.py | 25 ++++- mesonbuild/compilers/cpp.py | 130 ++++++++++++++++++------ mesonbuild/compilers/cuda.py | 40 ++++++-- mesonbuild/compilers/cython.py | 8 +- mesonbuild/compilers/fortran.py | 10 +- mesonbuild/compilers/mixins/elbrus.py | 4 +- mesonbuild/compilers/mixins/islinker.py | 3 +- mesonbuild/compilers/objc.py | 9 +- mesonbuild/compilers/objcpp.py | 9 +- mesonbuild/compilers/rust.py | 6 +- mesonbuild/compilers/swift.py | 16 ++- mesonbuild/compilers/vala.py | 3 +- mesonbuild/linkers/linkers.py | 5 +- 18 files changed, 276 insertions(+), 95 deletions(-) diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 99e6dc9f30a5..96d54c6be1bc 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -948,8 +948,8 @@ def generate_basic_compiler_args(self, target: build.BuildTarget, compiler: 'Com commands += compiler.get_werror_args() # Add compile args for c_* or cpp_* build options set on the # command-line or default_options inside project(). - commands += compiler.get_option_compile_args(target, target.subproject) - commands += compiler.get_option_std_args(target, target.subproject) + commands += compiler.get_option_compile_args(target) + commands += compiler.get_option_std_args(target) optimization = self.get_target_option(target, 'optimization') assert isinstance(optimization, str), 'for mypy' diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index bccb0bc1daba..ad781b913e20 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1842,7 +1842,7 @@ def generate_cython_transpile(self, target: build.BuildTarget) -> \ args += cython.get_always_args() args += cython.get_debug_args(self.get_target_option(target, 'debug')) args += cython.get_optimization_args(self.get_target_option(target, 'optimization')) - args += cython.get_option_compile_args(target, target.subproject) + args += cython.get_option_compile_args(target) args += cython.get_option_std_args(target, target.subproject) args += self.build.get_global_args(cython, target.for_machine) args += self.build.get_project_args(cython, target) @@ -3342,7 +3342,7 @@ def target_uses_import_std(self, target: build.BuildTarget) -> bool: return self.environment.coredata.optstore.get_option_for_target( target, OptionKey('cpp_importstd'), str, default='false') == 'true' - def handle_cpp_import_std(self, target: build.BuildTarget, compiler): + def handle_cpp_import_std(self, target: build.BuildTarget, compiler: Compiler): istd_args = [] istd_dep = [] if not self.target_uses_import_std(target): @@ -3356,7 +3356,7 @@ def handle_cpp_import_std(self, target: build.BuildTarget, compiler): mod_file = 'gcm.cache/std.gcm' mod_obj_file = 'std.o' elem = NinjaBuildElement(self.all_outputs, [mod_file, mod_obj_file], 'CUSTOM_COMMAND', []) - compile_args = compiler.get_option_compile_args(target, self.environment) + compile_args = compiler.get_option_compile_args(target) compile_args += compiler.get_option_std_args(target, self.environment) compile_args += ['-c', '-fmodules', '-fsearch-include-path', 'bits/std.cc'] elem.add_item('COMMAND', compiler.exelist + compile_args) @@ -3374,7 +3374,7 @@ def handle_cpp_import_std(self, target: build.BuildTarget, compiler): raise SystemExit('VS std import header could not be located.') in_file_str = str(in_file) elem = NinjaBuildElement(self.all_outputs, [mod_file, mod_obj_file], 'CUSTOM_COMMAND', [in_file_str]) - compile_args = compiler.get_option_compile_args(target, self.environment) + compile_args = compiler.get_option_compile_args(target) compile_args += compiler.get_option_std_args(target, self.environment) compile_args += ['/nologo', '/c', '/O2', in_file_str] elem.add_item('COMMAND', compiler.exelist + compile_args) diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index 07089b31acb8..072c056e5e22 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -1027,8 +1027,7 @@ def get_args_defines_and_inc_dirs(self, target: build.BuildTarget, compiler: com file_args[l] += comp.get_always_args() file_args[l] += compilers.get_base_compile_args( target, comp, self.environment) - file_args[l] += comp.get_option_compile_args( - target, target.subproject) + file_args[l] += comp.get_option_compile_args(target) file_args[l] += comp.get_option_std_args( target, target.subproject) diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py index 936f5b98e9a7..8dc9ea12da57 100644 --- a/mesonbuild/backend/xcodebackend.py +++ b/mesonbuild/backend/xcodebackend.py @@ -1741,7 +1741,7 @@ def generate_single_build_target(self, objects_dict: PbxDict, target_name: str, continue # Start with warning args warn_args = compiler.get_warn_args(self.get_target_option(target, 'warning_level')) - std_args = compiler.get_option_compile_args(target, target.subproject) + std_args = compiler.get_option_compile_args(target) std_args += compiler.get_option_std_args(target, target.subproject) # Add compile args added using add_project_arguments() pargs = self.build.get_project_args(compiler, target) diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 2bff42b1d97a..778d3f0bb140 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -44,6 +44,7 @@ from ..mesonlib import MachineChoice from .compilers import CompileCheckMode from ..build import BuildTarget + from ..interpreterbase import SubProject CompilerMixinBase = Compiler else: @@ -127,15 +128,29 @@ def get_options(self) -> 'MutableKeyedOptionDictType': gnu_winlibs) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: - args = [] + @T.overload + def get_option_std_args(self, target: BuildTarget) -> T.List[str]: ... + + @T.overload + def get_option_std_args(self, target: None, subproject: SubProject) -> T.List[str]: ... + + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject + args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': args.append('-std=' + std) return args - def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + @T.overload + def get_option_link_args(self, target: BuildTarget) -> T.List[str]: ... + + @T.overload + def get_option_link_args(self, target: None, subproject: SubProject) -> T.List[str]: ... + + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject if self.info.is_windows() or self.info.is_cygwin(): retval = self.get_compileropt_value('winlibs', target, subproject) assert isinstance(retval, list) @@ -212,15 +227,16 @@ def get_options(self) -> 'MutableKeyedOptionDictType': std_opt.set_versions(['c90', 'c99', 'c11'], gnu=True) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: - args = [] + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject + args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': args.append('-std=' + std) return args - def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: return [] @@ -255,8 +271,9 @@ def get_options(self) -> 'MutableKeyedOptionDictType': gnu_winlibs) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: - args = [] + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject + args: T.List[str] = [] key = OptionKey('c_std', machine=self.for_machine) std = self.get_compileropt_value(key, target, subproject) assert isinstance(std, str) @@ -264,7 +281,8 @@ def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = args.append('-std=' + std) return args - def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject if self.info.is_windows() or self.info.is_cygwin(): # without a typeddict mypy can't figure this out retval = self.get_compileropt_value('winlibs', target, subproject) @@ -308,7 +326,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': std_opt.set_versions(cppstd_choices, gnu=True) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) @@ -382,7 +401,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': std_opt.set_versions(stds, gnu=True) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) @@ -409,7 +429,8 @@ def get_options(self) -> MutableKeyedOptionDictType: msvc_winlibs) return opts - def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject retval = self.get_compileropt_value('winlibs', target, subproject) assert isinstance(retval, list) libs: T.List[str] = retval.copy() @@ -444,8 +465,9 @@ def get_options(self) -> 'MutableKeyedOptionDictType': std_opt.set_versions(stds, gnu=True, gnu_deprecated=True) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: - args = [] + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject + args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) # As of MVSC 16.8, /std:c11 and /std:c17 are the only valid C standard options. @@ -465,7 +487,8 @@ def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoic env, linker=linker, full_version=full_version) ClangClCompiler.__init__(self, target) - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != "none": @@ -493,7 +516,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': std_opt.set_versions(['c89', 'c99', 'c11']) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) @@ -526,8 +550,9 @@ def get_options(self) -> 'MutableKeyedOptionDictType': std_opt.set_versions(['c89', 'c99', 'c11']) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: - args = [] + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject + args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': @@ -559,8 +584,9 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_no_stdinc_args(self) -> T.List[str]: return [] - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: - args = [] + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject + args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std == 'c89': @@ -607,8 +633,9 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_no_stdinc_args(self) -> T.List[str]: return [] - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: - args = [] + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject + args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': @@ -702,8 +729,9 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_no_stdinc_args(self) -> T.List[str]: return [] - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: - args = [] + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject + args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': @@ -736,8 +764,9 @@ def get_options(self) -> 'MutableKeyedOptionDictType': self._update_language_stds(opts, ['c99']) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: - args = [] + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject + args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': @@ -764,8 +793,9 @@ def get_options(self) -> 'MutableKeyedOptionDictType': self._update_language_stds(opts, ['c99']) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: - args = [] + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject + args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index a2a77cae7497..ce4bd7ce0882 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -36,6 +36,7 @@ from ..linkers.linkers import DynamicLinker from ..mesonlib import MachineChoice from ..dependencies import Dependency + from ..interpreterbase import SubProject # See the comment on `lang_suffixes` if modifying this list. Language = Literal[ @@ -644,13 +645,31 @@ def make_option_name(self, key: OptionKey) -> str: def get_options(self) -> 'MutableKeyedOptionDictType': return {} - def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + @T.overload + def get_option_compile_args(self, target: BuildTarget) -> T.List[str]: ... + + @T.overload + def get_option_compile_args(self, target: None, subproject: SubProject) -> T.List[str]: ... + + def get_option_compile_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: return [] - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + @T.overload + def get_option_std_args(self, target: BuildTarget) -> T.List[str]: ... + + @T.overload + def get_option_std_args(self, target: None, subproject: SubProject) -> T.List[str]: ... + + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: return [] - def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + @T.overload + def get_option_link_args(self, target: BuildTarget) -> T.List[str]: ... + + @T.overload + def get_option_link_args(self, target: None, subproject: SubProject) -> T.List[str]: ... + + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: return self.linker.get_option_link_args(target, subproject) def check_header(self, hname: str, prefix: str, *, diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index c7386325488d..e43cf7ade6cf 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -41,6 +41,7 @@ from ..linkers.linkers import DynamicLinker from ..mesonlib import MachineChoice from ..build import BuildTarget + from ..interpreterbase import SubProject CompilerMixinBase = CLikeCompiler else: CompilerMixinBase = object @@ -261,9 +262,12 @@ def get_options(self) -> 'MutableKeyedOptionDictType': gnu_winlibs) return opts - def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_compile_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] + # We should only get `None, subproject` or `BuildTarget` + subproject = subproject if subproject is not None else target.subproject + rtti = self.get_compileropt_value('rtti', target, subproject) debugstl = self.get_compileropt_value('debugstl', target, subproject) eh = self.get_compileropt_value('eh', target, subproject) @@ -289,7 +293,8 @@ def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[ return args - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) @@ -297,7 +302,8 @@ def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = args.append(self._find_best_cpp_std(std)) return args - def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject if self.info.is_windows() or self.info.is_cygwin(): # without a typedict mypy can't understand this. retval = self.get_compileropt_value('winlibs', target, subproject) @@ -366,7 +372,8 @@ def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_ ClangCPPCompiler.__init__(self, ccache, exelist, version, for_machine, env, linker=linker, defines=defines, full_version=full_version) - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) @@ -409,7 +416,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': std_opt.set_versions(['c++98', 'c++03', 'c++11', 'c++14', 'c++17'], gnu=True) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) @@ -422,7 +430,7 @@ def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = return args - def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: return [] @@ -481,9 +489,12 @@ def get_options(self) -> 'MutableKeyedOptionDictType': return opts - def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_compile_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] + # We should only get `None, subproject` or `BuildTarget` + subproject = subproject if subproject is not None else target.subproject + rtti = self.get_compileropt_value('rtti', target, subproject) debugstl = self.get_compileropt_value('debugstl', target, subproject) eh = self.get_compileropt_value('eh', target, subproject) @@ -502,7 +513,8 @@ def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[ args.append('-D_GLIBCXX_DEBUG=1') return args - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) @@ -510,7 +522,8 @@ def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = args.append(self._find_best_cpp_std(std)) return args - def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject if self.info.is_windows() or self.info.is_cygwin(): # without a typedict mypy can't understand this. retval = self.get_compileropt_value('winlibs', target, subproject) @@ -582,7 +595,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': std_opt.set_versions(cppstd_choices) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) @@ -650,8 +664,12 @@ def has_function(self, funcname: str, prefix: str, *, return super().has_function(funcname, prefix, extra_args=extra_args, dependencies=dependencies) # Elbrus C++ compiler does not support RTTI, so don't check for it. - def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_compile_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] + + # We should only get `None, subproject` or `BuildTarget` + subproject = subproject if subproject is not None else target.subproject + eh = self.get_compileropt_value('eh', target, subproject) assert isinstance(eh, str) @@ -663,7 +681,8 @@ def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[ args.append('-D_GLIBCXX_DEBUG=1') return args - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) @@ -728,9 +747,12 @@ def get_options(self) -> 'MutableKeyedOptionDictType': self._update_language_stds(opts, c_stds + g_stds) return opts - def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_compile_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] + # We should only get `None, subproject` or `BuildTarget` + subproject = subproject if subproject is not None else target.subproject + rtti = self.get_compileropt_value('rtti', target, subproject) debugstl = self.get_compileropt_value('debugstl', target, subproject) eh = self.get_compileropt_value('eh', target, subproject) @@ -747,7 +769,8 @@ def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[ args.append('-D_GLIBCXX_DEBUG=1') return args - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) @@ -760,7 +783,7 @@ def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = return args - def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: return [] @@ -787,7 +810,14 @@ class VisualStudioLikeCPPCompilerMixin(CompilerMixinBase): 'c++latest': (False, "latest"), } - def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + @T.overload + def get_option_link_args(self, target: BuildTarget) -> T.List[str]: ... + + @T.overload + def get_option_link_args(self, target: None, subproject: SubProject) -> T.List[str]: ... + + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject # need a typeddict for this key = self.form_compileropt_key('winlibs').evolve(subproject=subproject) if target: @@ -830,9 +860,18 @@ def _get_options_impl(self, opts: 'MutableKeyedOptionDictType', cpp_stds: T.List choices=['false', 'true']) return opts - def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + @T.overload + def get_option_compile_args(self, target: BuildTarget) -> T.List[str]: ... + + @T.overload + def get_option_compile_args(self, target: None, subproject: SubProject) -> T.List[str]: ... + + def get_option_compile_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] + # We should only get `None, subproject` or `BuildTarget` + subproject = subproject if subproject is not None else target.subproject + eh = self.get_compileropt_value('eh', target, subproject) rtti = self.get_compileropt_value('rtti', target, subproject) @@ -851,7 +890,14 @@ def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[ return args - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + @T.overload + def get_option_std_args(self, target: BuildTarget) -> T.List[str]: ... + + @T.overload + def get_option_std_args(self, target: None, subproject: SubProject) -> T.List[str]: ... + + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) @@ -874,7 +920,14 @@ class CPP11AsCPP14Mixin(CompilerMixinBase): This is a limitation of Clang and MSVC that ICL doesn't share. """ - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + @T.overload + def get_option_std_args(self, target: BuildTarget) -> T.List[str]: ... + + @T.overload + def get_option_std_args(self, target: None, subproject: SubProject) -> T.List[str]: ... + + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject # Note: there is no explicit flag for supporting C++11; we attempt to do the best we can # which means setting the C++ standard version to C++14, in compilers that support it # (i.e., after VS2015U3) @@ -888,7 +941,11 @@ def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = mlog.warning(self.id, 'does not support C++11;', 'attempting best effort; setting the standard to C++14', once=True, fatal=False) - original_args = super().get_option_std_args(target, subproject) + + if target is not None: + original_args = super().get_option_std_args(target) + else: + original_args = super().get_option_std_args(target, subproject) std_mapping = {'/std:c++11': '/std:c++14'} processed_args = [std_mapping.get(x, x) for x in original_args] return processed_args @@ -924,12 +981,23 @@ def get_options(self) -> 'MutableKeyedOptionDictType': cpp_stds.extend(['c++20', 'vc++20']) return self._get_options_impl(super().get_options(), cpp_stds) - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + @T.overload + def get_option_std_args(self, target: BuildTarget) -> T.List[str]: ... + + @T.overload + def get_option_std_args(self, target: None, subproject: SubProject) -> T.List[str]: ... + + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject std = self.get_compileropt_value('std', target, subproject) if std != 'none' and version_compare(self.version, '<19.00.24210'): mlog.warning('This version of MSVC does not support cpp_std arguments', fatal=False) - args = super().get_option_std_args(target, subproject) + args: T.List[str] # pylint fails to deduce the type of args without this + if target is not None: + args = super().get_option_std_args(target) + else: + args = super().get_option_std_args(target, subproject) if version_compare(self.version, '<19.11'): try: @@ -1008,8 +1076,9 @@ def get_options(self) -> 'MutableKeyedOptionDictType': std_opt.set_versions(['c++03', 'c++11']) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] + subproject = subproject if subproject is not None else target.subproject std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std == 'c++11': @@ -1018,7 +1087,7 @@ def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = args.append('--cpp') return args - def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: return [] def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: @@ -1043,7 +1112,7 @@ def get_compile_only_args(self) -> T.List[str]: def get_output_args(self, outputname: str) -> T.List[str]: return [f'-output=obj={outputname}'] - def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: return [] def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]: @@ -1065,8 +1134,9 @@ def get_options(self) -> 'MutableKeyedOptionDictType': std_opt.set_versions(['c++03']) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] + subproject = subproject if subproject is not None else target.subproject std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': @@ -1076,7 +1146,7 @@ def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = def get_always_args(self) -> T.List[str]: return [] - def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: return [] class C2000CPPCompiler(TICPPCompiler): @@ -1104,8 +1174,9 @@ def get_options(self) -> 'MutableKeyedOptionDictType': self._update_language_stds(opts, []) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] + subproject = subproject if subproject is not None else target.subproject std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': @@ -1131,8 +1202,9 @@ def get_options(self) -> 'MutableKeyedOptionDictType': self._update_language_stds(opts, []) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] + subproject = subproject if subproject is not None else target.subproject std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py index ba5ccbbe283c..7705abbb076a 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -19,6 +19,7 @@ from ..environment import Environment # noqa: F401 from ..linkers.linkers import DynamicLinker from ..mesonlib import MachineChoice + from ..interpreterbase import SubProject cuda_optimization_args: T.Dict[str, T.List[str]] = { @@ -609,16 +610,35 @@ def get_options(self) -> 'MutableKeyedOptionDictType': return opts - def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + @T.overload + def get_option_compile_args(self, target: BuildTarget) -> T.List[str]: ... + + @T.overload + def get_option_compile_args(self, target: None, subproject: SubProject) -> T.List[str]: ... + + def get_option_compile_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args = self._get_ccbin_args(target, subproject) + # We should only get `None, subproject` or `BuildTarget` + subproject = subproject if subproject is not None else target.subproject + try: - host_compiler_args = self.host_compiler.get_option_compile_args(target, subproject) + if target is not None: + host_compiler_args = self.host_compiler.get_option_compile_args(target) + else: + host_compiler_args = self.host_compiler.get_option_compile_args(target, subproject) except KeyError: host_compiler_args = [] return args + self._to_host_flags(host_compiler_args) - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + @T.overload + def get_option_std_args(self, target: BuildTarget) -> T.List[str]: ... + + @T.overload + def get_option_std_args(self, target: None, subproject: SubProject) -> T.List[str]: ... + + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject # On Windows, the version of the C++ standard used by nvcc is dictated by # the combination of CUDA version and MSVC version; the --std= is thus ignored # and attempting to use it will result in a warning: https://stackoverflow.com/a/51272091/741027 @@ -629,14 +649,22 @@ def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = return ['--std=' + std] try: - host_compiler_args = self.host_compiler.get_option_std_args(target, subproject) + if target is not None: + host_compiler_args = self.host_compiler.get_option_std_args(target) + else: + host_compiler_args = self.host_compiler.get_option_std_args(target, subproject) except KeyError: host_compiler_args = [] return self._to_host_flags(host_compiler_args) - def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = subproject if subproject is not None else target.subproject args = self._get_ccbin_args(target, subproject) - return args + self._to_host_flags(self.host_compiler.get_option_link_args(target, subproject), Phase.LINKER) + if target is not None: + host_args = self.host_compiler.get_option_std_args(target) + else: + host_args = self.host_compiler.get_option_std_args(target, subproject) + return args + self._to_host_flags(host_args, Phase.LINKER) def get_soname_args(self, prefix: str, shlib_name: str, suffix: str, soversion: str, darwin_versions: T.Tuple[str, str]) -> T.List[str]: diff --git a/mesonbuild/compilers/cython.py b/mesonbuild/compilers/cython.py index e3e5a3ef601f..237c73994ec5 100644 --- a/mesonbuild/compilers/cython.py +++ b/mesonbuild/compilers/cython.py @@ -15,6 +15,7 @@ if T.TYPE_CHECKING: from ..options import MutableKeyedOptionDictType from ..build import BuildTarget + from ..interpreterbase import SubProject class CythonCompiler(Compiler): @@ -92,7 +93,7 @@ def _transpiled_sanity_check_compile_args( def _sanity_check_compile_args(self, sourcename: str, binname: str ) -> T.Tuple[T.List[str], T.List[str]]: args, largs = super()._sanity_check_compile_args(sourcename, binname) - args.extend(self.get_option_compile_args(None)) + args.extend(self.get_option_compile_args(None, T.cast('SubProject', ''))) return args, largs def _sanity_check_source_code(self) -> str: @@ -131,8 +132,11 @@ def get_options(self) -> 'MutableKeyedOptionDictType': return opts - def get_option_compile_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_compile_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] + + # We should only get `None, subproject` or `BuildTarget` + subproject = subproject if subproject is not None else target.subproject version = self.get_compileropt_value('version', target, subproject) assert isinstance(version, str) args.append(f'-{version}') diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py index 24d4a6c03a2e..3d48da0a4e2c 100644 --- a/mesonbuild/compilers/fortran.py +++ b/mesonbuild/compilers/fortran.py @@ -34,6 +34,7 @@ from ..linkers.linkers import DynamicLinker from ..mesonlib import MachineChoice from ..build import BuildTarget + from ..interpreterbase import SubProject class FortranCompiler(CLikeCompiler, Compiler): @@ -284,8 +285,9 @@ def get_options(self) -> 'MutableKeyedOptionDictType': self._update_language_stds(opts, fortran_stds) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] + subproject = subproject if subproject is not None else target.subproject std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': @@ -414,8 +416,9 @@ def get_options(self) -> 'MutableKeyedOptionDictType': self._update_language_stds(opts, ['none', 'legacy', 'f95', 'f2003', 'f2008', 'f2018']) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] + subproject = subproject if subproject is not None else target.subproject std = self.get_compileropt_value('std', target, subproject) stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'} assert isinstance(std, str) @@ -472,8 +475,9 @@ def get_options(self) -> 'MutableKeyedOptionDictType': self._update_language_stds(opts, ['none', 'legacy', 'f95', 'f2003', 'f2008', 'f2018']) return opts - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] + subproject = subproject if subproject is not None else target.subproject std = self.get_compileropt_value('std', target, subproject) stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'} assert isinstance(std, str) diff --git a/mesonbuild/compilers/mixins/elbrus.py b/mesonbuild/compilers/mixins/elbrus.py index e3c67034b32d..10058d9a1dab 100644 --- a/mesonbuild/compilers/mixins/elbrus.py +++ b/mesonbuild/compilers/mixins/elbrus.py @@ -18,6 +18,7 @@ if T.TYPE_CHECKING: from ...build import BuildTarget + from ...interpreterbase import SubProject class ElbrusCompiler(GnuLikeCompiler): @@ -82,8 +83,9 @@ def get_pch_suffix(self) -> str: # Actually it's not supported for now, but probably will be supported in future return 'pch' - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] + subproject = subproject if subproject is not None else target.subproject key = OptionKey(f'{self.language}_std', subproject=subproject, machine=self.for_machine) if target: std = self.environment.coredata.optstore.get_option_for_target_untyped(target, key) diff --git a/mesonbuild/compilers/mixins/islinker.py b/mesonbuild/compilers/mixins/islinker.py index 1c0361918991..7eb891f6aa1e 100644 --- a/mesonbuild/compilers/mixins/islinker.py +++ b/mesonbuild/compilers/mixins/islinker.py @@ -20,6 +20,7 @@ from ...compilers.compilers import Compiler from ...build import BuildTarget from ...options import OptionStore + from ...interpreterbase import SubProject else: # This is a bit clever, for mypy we pretend that these mixins descend from # Compiler, so we get all of the methods and attributes defined for us, but @@ -59,7 +60,7 @@ def get_linker_always_args(self) -> T.List[str]: def get_linker_lib_prefix(self) -> str: return '' - def get_option_link_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: return [] def has_multi_link_args(self, args: T.List[str]) -> T.Tuple[bool, bool]: diff --git a/mesonbuild/compilers/objc.py b/mesonbuild/compilers/objc.py index 2d69fd693092..5a96ee47e598 100644 --- a/mesonbuild/compilers/objc.py +++ b/mesonbuild/compilers/objc.py @@ -20,6 +20,7 @@ from ..mesonlib import MachineChoice from ..build import BuildTarget from ..options import MutableKeyedOptionDictType + from ..interpreterbase import SubProject class ObjCCompiler(CLikeCompiler, Compiler): @@ -74,8 +75,9 @@ def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_ self.supported_warn_args(gnu_common_warning_args) + self.supported_warn_args(gnu_objc_warning_args))} - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] + subproject = subproject if subproject is not None else target.subproject key = OptionKey('c_std', subproject=subproject, machine=self.for_machine) if target: std = self.environment.coredata.optstore.get_option_for_target_untyped(target, key) @@ -112,8 +114,9 @@ def make_option_name(self, key: OptionKey) -> str: return 'c_std' return super().make_option_name(key) - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: - args = [] + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + args: T.List[str] = [] + subproject = subproject if subproject is not None else target.subproject key = OptionKey('c_std', machine=self.for_machine) std = self.get_compileropt_value(key, target, subproject) assert isinstance(std, str) diff --git a/mesonbuild/compilers/objcpp.py b/mesonbuild/compilers/objcpp.py index 90fb304a7412..167a34160006 100644 --- a/mesonbuild/compilers/objcpp.py +++ b/mesonbuild/compilers/objcpp.py @@ -20,6 +20,7 @@ from ..mesonlib import MachineChoice from ..build import BuildTarget from ..options import MutableKeyedOptionDictType + from ..interpreterbase import SubProject class ObjCPPCompiler(CLikeCompiler, Compiler): @@ -78,8 +79,9 @@ def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_ self.supported_warn_args(gnu_common_warning_args) + self.supported_warn_args(gnu_objc_warning_args))} - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] + subproject = subproject if subproject is not None else target.subproject key = OptionKey('cpp_std', subproject=subproject, machine=self.for_machine) if target: std = self.environment.coredata.optstore.get_option_for_target_untyped(target, key) @@ -107,8 +109,9 @@ def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_ '3': default_warn_args + ['-Wextra', '-Wpedantic'], 'everything': ['-Weverything']} - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: - args = [] + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + args: T.List[str] = [] + subproject = subproject if subproject is not None else target.subproject key = OptionKey('cpp_std', machine=self.for_machine) std = self.get_compileropt_value(key, target, subproject) assert isinstance(std, str) diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py index 6282d6a0dec8..21a62aba3373 100644 --- a/mesonbuild/compilers/rust.py +++ b/mesonbuild/compilers/rust.py @@ -26,6 +26,7 @@ from ..mesonlib import MachineChoice from ..dependencies import Dependency from ..build import BuildTarget + from ..interpreterbase import SubProject from typing_extensions import Protocol @@ -386,8 +387,9 @@ def get_dependency_compile_args(self, dep: 'Dependency') -> T.List[str]: # provided by the linker flags. return [] - def get_option_std_args(self, target: BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: - args = [] + def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: + args: T.List[str] = [] + subproject = subproject if subproject is not None else target.subproject std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) if std != 'none': diff --git a/mesonbuild/compilers/swift.py b/mesonbuild/compilers/swift.py index 6bc90ffd41e4..da3b12741cb6 100644 --- a/mesonbuild/compilers/swift.py +++ b/mesonbuild/compilers/swift.py @@ -19,6 +19,7 @@ from ..environment import Environment from ..linkers.linkers import DynamicLinker from ..mesonlib import MachineChoice + from ..interpreterbase import SubProject swift_optimization_args: T.Dict[str, T.List[str]] = { 'plain': [], @@ -128,8 +129,15 @@ def get_options(self) -> MutableKeyedOptionDictType: return opts - def get_option_std_args(self, target: build.BuildTarget, subproject: T.Optional[str] = None) -> T.List[str]: + @T.overload + def get_option_std_args(self, target: build.BuildTarget) -> T.List[str]: ... + + @T.overload + def get_option_std_args(self, target: None, subproject: SubProject) -> T.List[str]: ... + + def get_option_std_args(self, target: T.Optional[build.BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] + subproject = subproject if subproject is not None else target.subproject std = self.get_compileropt_value('std', target, subproject) assert isinstance(std, str) @@ -145,7 +153,11 @@ def get_option_std_args(self, target: build.BuildTarget, subproject: T.Optional[ c_lang = first(c_langs, lambda x: x in target.compilers) if c_lang is not None: cc = target.compilers[c_lang] - args.extend(arg for c_arg in cc.get_option_std_args(target, subproject) for arg in ['-Xcc', c_arg]) + if target is not None: + cc_std_args = cc.get_option_std_args(target) + else: + cc_std_args = cc.get_option_std_args(target, subproject) + args.extend(arg for c_arg in cc_std_args for arg in ['-Xcc', c_arg]) return args diff --git a/mesonbuild/compilers/vala.py b/mesonbuild/compilers/vala.py index f2c14f46940e..625db201a025 100644 --- a/mesonbuild/compilers/vala.py +++ b/mesonbuild/compilers/vala.py @@ -18,6 +18,7 @@ from ..mesonlib import MachineChoice from ..dependencies import Dependency from ..build import BuildTarget + from ..interpreterbase import SubProject class ValaCompiler(Compiler): @@ -173,7 +174,7 @@ def thread_flags(self) -> T.List[str]: def thread_link_flags(self) -> T.List[str]: return [] - def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: return [] def build_wrapper_args(self, diff --git a/mesonbuild/linkers/linkers.py b/mesonbuild/linkers/linkers.py index cb8956adf5be..8b5f6473f908 100644 --- a/mesonbuild/linkers/linkers.py +++ b/mesonbuild/linkers/linkers.py @@ -19,6 +19,7 @@ from ..mesonlib import MachineChoice from ..build import BuildTarget from ..compilers import Compiler + from ..interpreterbase import SubProject class StaticLinker: @@ -80,7 +81,7 @@ def thread_flags(self) -> T.List[str]: def openmp_flags(self) -> T.List[str]: return [] - def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: return [] @classmethod @@ -195,7 +196,7 @@ def get_lib_prefix(self) -> str: def get_option_args(self, target: 'BuildTarget', env: 'Environment', subproject: T.Optional[str] = None) -> T.List[str]: return [] - def get_option_link_args(self, target: 'BuildTarget', subproject: T.Optional[str] = None) -> T.List[str]: + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: return [] def has_multi_arguments(self, args: T.List[str]) -> T.Tuple[bool, bool]: From 1ef2408c40d5e4c9419e2d2a164f366770d9493c Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Thu, 12 Mar 2026 09:13:16 -0700 Subject: [PATCH 17/22] compilers: Add a subproject parameter to the `form_compileropt_key` method --- mesonbuild/compilers/compilers.py | 4 ++-- mesonbuild/compilers/cpp.py | 4 ++-- mesonbuild/compilers/cuda.py | 7 ++++--- mesonbuild/compilers/objc.py | 12 ++++++------ mesonbuild/compilers/objcpp.py | 6 +++--- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index ce4bd7ce0882..cf549a6756c1 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1606,8 +1606,8 @@ def get_preprocessor(self) -> Compiler: """ raise EnvironmentException(f'{self.get_id()} does not support preprocessor') - def form_compileropt_key(self, basename: str) -> OptionKey: - return OptionKey(f'{self.language}_{basename}', machine=self.for_machine) + def form_compileropt_key(self, basename: str, subproject: T.Optional[SubProject] = None) -> OptionKey: + return OptionKey(f'{self.language}_{basename}', subproject=subproject, machine=self.for_machine) # TODO: get rid of this def get_compileropt_value(self, diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index e43cf7ade6cf..6f726a722f9b 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -819,7 +819,7 @@ def get_option_link_args(self, target: None, subproject: SubProject) -> T.List[s def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject # need a typeddict for this - key = self.form_compileropt_key('winlibs').evolve(subproject=subproject) + key = self.form_compileropt_key('winlibs', subproject) if target: value = self.environment.coredata.optstore.get_option_for_target_untyped(target, key) else: @@ -932,7 +932,7 @@ def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Opt # which means setting the C++ standard version to C++14, in compilers that support it # (i.e., after VS2015U3) # if one is using anything before that point, one cannot set the standard. - stdkey = self.form_compileropt_key('std').evolve(subproject=subproject) + stdkey = self.form_compileropt_key('std', subproject) if target is not None: std = self.environment.coredata.optstore.get_option_for_target_untyped(target, stdkey) else: diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py index 7705abbb076a..8d27696d910e 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -538,7 +538,7 @@ def _sanity_check_compile_args(self, sourcename: str, binname: str # Use the -ccbin option, if available, even during sanity checking. # Otherwise, on systems where CUDA does not support the default compiler, # NVCC becomes unusable. - flags += self._get_ccbin_args(None, '') + flags += self._get_ccbin_args(None, T.cast('SubProject', '')) # If cross-compiling, we can't run the sanity check, only compile it. if self.is_cross and not self.environment.has_exe_wrapper(): @@ -775,8 +775,9 @@ def get_dependency_link_args(self, dep: 'Dependency') -> T.List[str]: return self._to_host_flags(super().get_dependency_link_args(dep), Phase.LINKER) def _get_ccbin_args(self, target: 'T.Optional[BuildTarget]', - subproject: T.Optional[str] = None) -> T.List[str]: - key = self.form_compileropt_key('ccbindir').evolve(subproject=subproject) + subproject: T.Optional[SubProject] = None) -> T.List[str]: + subproject = target.subproject if subproject is None else subproject + key = self.form_compileropt_key('ccbindir', subproject) if target: ccbindir = self.environment.coredata.optstore.get_option_for_target_untyped(target, key) else: diff --git a/mesonbuild/compilers/objc.py b/mesonbuild/compilers/objc.py index 5a96ee47e598..6975db40941a 100644 --- a/mesonbuild/compilers/objc.py +++ b/mesonbuild/compilers/objc.py @@ -51,10 +51,10 @@ def get_display_language() -> str: def _sanity_check_source_code(self) -> str: return '#import\nint main(void) { return 0; }\n' - def form_compileropt_key(self, basename: str) -> OptionKey: + def form_compileropt_key(self, basename: str, subproject: T.Optional[SubProject] = None) -> OptionKey: if basename == 'std': - return OptionKey(f'c_{basename}', machine=self.for_machine) - return super().form_compileropt_key(basename) + return OptionKey('c_std}', subproject=subproject, machine=self.for_machine) + return super().form_compileropt_key(basename, subproject) class GnuObjCCompiler(GnuCStds, GnuCompiler, ObjCCompiler): @@ -104,10 +104,10 @@ def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_ '3': default_warn_args + ['-Wextra', '-Wpedantic'], 'everything': ['-Weverything']} - def form_compileropt_key(self, basename: str) -> OptionKey: + def form_compileropt_key(self, basename: str, subproject: T.Optional[SubProject] = None) -> OptionKey: if basename == 'std': - return OptionKey('c_std', machine=self.for_machine) - return super().form_compileropt_key(basename) + return OptionKey('c_std', subproject=subproject, machine=self.for_machine) + return super().form_compileropt_key(basename, subproject) def make_option_name(self, key: OptionKey) -> str: if key.name == 'std': diff --git a/mesonbuild/compilers/objcpp.py b/mesonbuild/compilers/objcpp.py index 167a34160006..f355bd2eb0c7 100644 --- a/mesonbuild/compilers/objcpp.py +++ b/mesonbuild/compilers/objcpp.py @@ -35,10 +35,10 @@ def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_ full_version=full_version, linker=linker) CLikeCompiler.__init__(self) - def form_compileropt_key(self, basename: str) -> OptionKey: + def form_compileropt_key(self, basename: str, subproject: T.Optional[SubProject] = None) -> OptionKey: if basename == 'std': - return OptionKey('cpp_std', machine=self.for_machine) - return super().form_compileropt_key(basename) + return OptionKey('cpp_std', subproject=subproject, machine=self.for_machine) + return super().form_compileropt_key(basename, subproject) def make_option_name(self, key: OptionKey) -> str: if key.name == 'std': From 2114f5b66adbb1f2a0681c80cfe6f60a19843e80 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Thu, 12 Mar 2026 09:17:44 -0700 Subject: [PATCH 18/22] compilers: Replace get_compileropt_value with direct optstore calls There is some added complexity because the langauge of an option was merged back into the name of the key instead of being a separate field. This method was basically doing the same thing as get_option_for_maybe_target, plus building a key. Some of the uses didn't make sense, as we knew we didn't have a target and just wanted a global value, plus we lost our type checking. --- mesonbuild/compilers/c.py | 87 ++++++++++----------- mesonbuild/compilers/compilers.py | 13 --- mesonbuild/compilers/cpp.py | 126 ++++++++++++++---------------- mesonbuild/compilers/cuda.py | 4 +- mesonbuild/compilers/cython.py | 16 ++-- mesonbuild/compilers/fortran.py | 14 ++-- mesonbuild/compilers/objc.py | 5 +- mesonbuild/compilers/objcpp.py | 5 +- mesonbuild/compilers/rust.py | 7 +- mesonbuild/compilers/swift.py | 4 +- 10 files changed, 127 insertions(+), 154 deletions(-) diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 778d3f0bb140..ef7380174fe3 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -137,8 +137,8 @@ def get_option_std_args(self, target: None, subproject: SubProject) -> T.List[st def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('-std=' + std) return args @@ -152,12 +152,8 @@ def get_option_link_args(self, target: None, subproject: SubProject) -> T.List[s def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject if self.info.is_windows() or self.info.is_cygwin(): - retval = self.get_compileropt_value('winlibs', target, subproject) - assert isinstance(retval, list) - libs: T.List[str] = retval.copy() - for l in libs: - assert isinstance(l, str) - return libs + key = self.form_compileropt_key('winlibs', subproject) + return self.environment.coredata.optstore.get_option_for_maybe_target(target, key, list).copy() return [] @@ -230,8 +226,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('-std=' + std) return args @@ -274,24 +270,23 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - key = OptionKey('c_std', machine=self.for_machine) - std = self.get_compileropt_value(key, target, subproject) - assert isinstance(std, str) + key = OptionKey('c_std', subproject, self.for_machine) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('-std=' + std) return args + @T.overload + def get_option_link_args(self, target: BuildTarget) -> T.List[str]: ... + + @T.overload + def get_option_link_args(self, target: None, subproject: SubProject) -> T.List[str]: ... + def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject if self.info.is_windows() or self.info.is_cygwin(): - # without a typeddict mypy can't figure this out - retval = self.get_compileropt_value('winlibs', target, subproject) - - assert isinstance(retval, list) - libs: T.List[str] = retval.copy() - for l in libs: - assert isinstance(l, str) - return libs + key = self.form_compileropt_key('winlibs', subproject) + return self.environment.coredata.optstore.get_option_for_maybe_target(target, key, list).copy() return [] def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]: @@ -329,8 +324,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('-std=' + std) return args @@ -404,8 +399,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('-std=' + std) return args @@ -431,12 +426,8 @@ def get_options(self) -> MutableKeyedOptionDictType: def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject - retval = self.get_compileropt_value('winlibs', target, subproject) - assert isinstance(retval, list) - libs: T.List[str] = retval.copy() - for l in libs: - assert isinstance(l, str) - return libs + key = self.form_compileropt_key('winlibs', subproject) + return self.environment.coredata.optstore.get_option_for_maybe_target(target, key, list).copy() class VisualStudioCCompiler(MSVCCompiler, VisualStudioLikeCCompilerMixin, CCompiler): @@ -468,7 +459,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) # As of MVSC 16.8, /std:c11 and /std:c17 are the only valid C standard options. if std in {'c11'}: @@ -489,8 +481,8 @@ def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoic def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != "none": return [f'/clang:-std={std}'] return [] @@ -519,8 +511,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std == 'c89': mlog.log("ICL doesn't explicitly implement c89, setting the standard to 'none', which is close.", once=True) elif std != 'none': @@ -553,8 +545,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('--' + std) return args @@ -587,8 +579,8 @@ def get_no_stdinc_args(self) -> T.List[str]: def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std == 'c89': args.append('-lang=c') elif std == 'c99': @@ -636,8 +628,8 @@ def get_no_stdinc_args(self) -> T.List[str]: def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('-ansi') args.append('-std=' + std) @@ -732,8 +724,8 @@ def get_no_stdinc_args(self) -> T.List[str]: def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('--' + std) return args @@ -767,8 +759,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('-lang') args.append(std) @@ -796,7 +788,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) assert isinstance(std, str) if std != 'none': args.append('-lang ' + std) diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index cf549a6756c1..2d13c0758327 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -1609,19 +1609,6 @@ def get_preprocessor(self) -> Compiler: def form_compileropt_key(self, basename: str, subproject: T.Optional[SubProject] = None) -> OptionKey: return OptionKey(f'{self.language}_{basename}', subproject=subproject, machine=self.for_machine) - # TODO: get rid of this - def get_compileropt_value(self, - key: T.Union[str, OptionKey], - target: T.Optional[BuildTarget], - subproject: T.Optional[str] = None - ) -> options.ElementaryOptionValues: - if isinstance(key, str): - key = self.form_compileropt_key(key) - if target: - return self.environment.coredata.optstore.get_option_for_target_untyped(target, key) - else: - return self.environment.coredata.optstore.get_value_for_untyped(key.evolve(subproject=subproject)) - def _update_language_stds(self, opts: MutableKeyedOptionDictType, value: T.List[str]) -> None: key = self.form_compileropt_key('std') std = opts[key] diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 6f726a722f9b..78aa58d53d78 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -268,13 +268,12 @@ def get_option_compile_args(self, target: T.Optional[BuildTarget], subproject: T # We should only get `None, subproject` or `BuildTarget` subproject = subproject if subproject is not None else target.subproject - rtti = self.get_compileropt_value('rtti', target, subproject) - debugstl = self.get_compileropt_value('debugstl', target, subproject) - eh = self.get_compileropt_value('eh', target, subproject) - - assert isinstance(rtti, bool) - assert isinstance(eh, str) - assert isinstance(debugstl, bool) + key = self.form_compileropt_key('rtti', subproject) + rtti = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, bool) + key = self.form_compileropt_key('debugstl', subproject) + debugstl = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, bool) + key = self.form_compileropt_key('eh', subproject) + eh = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) non_msvc_eh_options(eh, args) @@ -296,8 +295,8 @@ def get_option_compile_args(self, target: T.Optional[BuildTarget], subproject: T def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append(self._find_best_cpp_std(std)) return args @@ -305,13 +304,8 @@ def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Opt def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject if self.info.is_windows() or self.info.is_cygwin(): - # without a typedict mypy can't understand this. - retval = self.get_compileropt_value('winlibs', target, subproject) - assert isinstance(retval, list) - libs = retval[:] - for l in libs: - assert isinstance(l, str) - return libs + key = self.form_compileropt_key('winlibs', subproject) + return self.environment.coredata.optstore.get_option_for_maybe_target(target, key, list).copy() return [] def get_assert_args(self, disable: bool) -> T.List[str]: @@ -375,8 +369,8 @@ def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_ def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append(self._find_best_cpp_std(std)) return args @@ -419,13 +413,13 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('-std=' + std) - eh = self.get_compileropt_value('eh', target, subproject) - assert isinstance(eh, str) + key = self.form_compileropt_key('eh', subproject) + eh = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) non_msvc_eh_options(eh, args) return args @@ -495,13 +489,12 @@ def get_option_compile_args(self, target: T.Optional[BuildTarget], subproject: T # We should only get `None, subproject` or `BuildTarget` subproject = subproject if subproject is not None else target.subproject - rtti = self.get_compileropt_value('rtti', target, subproject) - debugstl = self.get_compileropt_value('debugstl', target, subproject) - eh = self.get_compileropt_value('eh', target, subproject) - - assert isinstance(rtti, bool) - assert isinstance(eh, str) - assert isinstance(debugstl, bool) + key = self.form_compileropt_key('rtti', subproject) + rtti = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, bool) + key = self.form_compileropt_key('debugstl', subproject) + debugstl = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, bool) + key = self.form_compileropt_key('eh', subproject) + eh = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) non_msvc_eh_options(eh, args) @@ -516,8 +509,8 @@ def get_option_compile_args(self, target: T.Optional[BuildTarget], subproject: T def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append(self._find_best_cpp_std(std)) return args @@ -525,13 +518,8 @@ def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Opt def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject if self.info.is_windows() or self.info.is_cygwin(): - # without a typedict mypy can't understand this. - retval = self.get_compileropt_value('winlibs', target, subproject) - assert isinstance(retval, list) - libs: T.List[str] = retval[:] - for l in libs: - assert isinstance(l, str) - return libs + key = self.form_compileropt_key('winlibs', subproject) + return self.environment.coredata.optstore.get_option_for_maybe_target(target, key, list).copy() return [] def get_assert_args(self, disable: bool) -> T.List[str]: @@ -598,8 +586,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append(self._find_best_cpp_std(std)) return args @@ -670,13 +658,12 @@ def get_option_compile_args(self, target: T.Optional[BuildTarget], subproject: T # We should only get `None, subproject` or `BuildTarget` subproject = subproject if subproject is not None else target.subproject - eh = self.get_compileropt_value('eh', target, subproject) - assert isinstance(eh, str) - + key = self.form_compileropt_key('eh', subproject) + eh = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) non_msvc_eh_options(eh, args) - debugstl = self.get_compileropt_value('debugstl', target, subproject) - assert isinstance(debugstl, bool) + key = self.form_compileropt_key('debugstl', subproject) + debugstl = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, bool) if debugstl: args.append('-D_GLIBCXX_DEBUG=1') return args @@ -684,8 +671,8 @@ def get_option_compile_args(self, target: T.Optional[BuildTarget], subproject: T def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append(self._find_best_cpp_std(std)) return args @@ -753,9 +740,12 @@ def get_option_compile_args(self, target: T.Optional[BuildTarget], subproject: T # We should only get `None, subproject` or `BuildTarget` subproject = subproject if subproject is not None else target.subproject - rtti = self.get_compileropt_value('rtti', target, subproject) - debugstl = self.get_compileropt_value('debugstl', target, subproject) - eh = self.get_compileropt_value('eh', target, subproject) + key = self.form_compileropt_key('rtti', subproject) + rtti = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, bool) + key = self.form_compileropt_key('debugstl', subproject) + debugstl = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, bool) + key = self.form_compileropt_key('eh', subproject) + eh = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) assert isinstance(rtti, bool) assert isinstance(eh, str) @@ -772,8 +762,8 @@ def get_option_compile_args(self, target: T.Optional[BuildTarget], subproject: T def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': remap_cpp03 = { 'c++03': 'c++98', @@ -872,11 +862,10 @@ def get_option_compile_args(self, target: T.Optional[BuildTarget], subproject: T # We should only get `None, subproject` or `BuildTarget` subproject = subproject if subproject is not None else target.subproject - eh = self.get_compileropt_value('eh', target, subproject) - rtti = self.get_compileropt_value('rtti', target, subproject) - - assert isinstance(rtti, bool) - assert isinstance(eh, str) + key = self.form_compileropt_key('rtti', subproject) + rtti = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, bool) + key = self.form_compileropt_key('eh', subproject) + eh = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if eh == 'default': args.append('/EHsc') @@ -899,8 +888,8 @@ def get_option_std_args(self, target: None, subproject: SubProject) -> T.List[st def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject args: T.List[str] = [] - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) permissive, ver = self.VC_VERSION_MAP[std] if ver is not None: @@ -989,7 +978,8 @@ def get_option_std_args(self, target: None, subproject: SubProject) -> T.List[st def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject - std = self.get_compileropt_value('std', target, subproject) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none' and version_compare(self.version, '<19.00.24210'): mlog.warning('This version of MSVC does not support cpp_std arguments', fatal=False) @@ -1079,8 +1069,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] subproject = subproject if subproject is not None else target.subproject - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std == 'c++11': args.append('--cpp11') elif std == 'c++03': @@ -1137,8 +1127,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] subproject = subproject if subproject is not None else target.subproject - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('--' + std) return args @@ -1177,8 +1167,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] subproject = subproject if subproject is not None else target.subproject - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('-lang') args.append(std) @@ -1205,8 +1195,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] subproject = subproject if subproject is not None else target.subproject - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('-lang ' + std) return args diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py index 8d27696d910e..e443a7e09d34 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -643,8 +643,8 @@ def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Opt # the combination of CUDA version and MSVC version; the --std= is thus ignored # and attempting to use it will result in a warning: https://stackoverflow.com/a/51272091/741027 if not is_windows(): - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': return ['--std=' + std] diff --git a/mesonbuild/compilers/cython.py b/mesonbuild/compilers/cython.py index 237c73994ec5..1ae5bfbef24b 100644 --- a/mesonbuild/compilers/cython.py +++ b/mesonbuild/compilers/cython.py @@ -58,7 +58,8 @@ def get_pic_args(self) -> T.List[str]: def _sanity_check_filenames(self) -> T.Tuple[str, T.Optional[str], str]: sourcename, _, binname = super()._sanity_check_filenames() - lang = self.get_compileropt_value('language', None) + key = self.form_compileropt_key('language', None) + lang = self.environment.coredata.optstore.get_value_for(key, str) assert isinstance(lang, str) # This is almost certainly not good enough @@ -70,8 +71,8 @@ def _sanity_check_filenames(self) -> T.Tuple[str, T.Optional[str], str]: def _transpiled_sanity_check_compile_args( self, compiler: Compiler, sourcename: str, binname: str ) -> T.Tuple[T.List[str], T.List[str]]: - version = self.get_compileropt_value('version', None) - assert isinstance(version, str) + key = self.form_compileropt_key('version', None) + version = self.environment.coredata.optstore.get_value_for(key, str) from ..dependencies import find_external_dependency with mlog.no_logging(): @@ -137,12 +138,13 @@ def get_option_compile_args(self, target: T.Optional[BuildTarget], subproject: T # We should only get `None, subproject` or `BuildTarget` subproject = subproject if subproject is not None else target.subproject - version = self.get_compileropt_value('version', target, subproject) - assert isinstance(version, str) + + key = self.form_compileropt_key('version', None) + version = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) args.append(f'-{version}') - lang = self.get_compileropt_value('language', target, subproject) - assert isinstance(lang, str) + key = self.form_compileropt_key('language', None) + lang = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if lang == 'cpp': args.append('--cplus') return args diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py index 3d48da0a4e2c..4de1de9881b6 100644 --- a/mesonbuild/compilers/fortran.py +++ b/mesonbuild/compilers/fortran.py @@ -288,8 +288,8 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] subproject = subproject if subproject is not None else target.subproject - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('-std=' + std) return args @@ -419,9 +419,10 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] subproject = subproject if subproject is not None else target.subproject - std = self.get_compileropt_value('std', target, subproject) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) + stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'} - assert isinstance(std, str) if std != 'none': args.append('-stand=' + stds[std]) return args @@ -478,9 +479,10 @@ def get_options(self) -> 'MutableKeyedOptionDictType': def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] subproject = subproject if subproject is not None else target.subproject - std = self.get_compileropt_value('std', target, subproject) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) + stds = {'legacy': 'none', 'f95': 'f95', 'f2003': 'f03', 'f2008': 'f08', 'f2018': 'f18'} - assert isinstance(std, str) if std != 'none': args.append('/stand:' + stds[std]) return args diff --git a/mesonbuild/compilers/objc.py b/mesonbuild/compilers/objc.py index 6975db40941a..de8a1060a763 100644 --- a/mesonbuild/compilers/objc.py +++ b/mesonbuild/compilers/objc.py @@ -117,9 +117,8 @@ def make_option_name(self, key: OptionKey) -> str: def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] subproject = subproject if subproject is not None else target.subproject - key = OptionKey('c_std', machine=self.for_machine) - std = self.get_compileropt_value(key, target, subproject) - assert isinstance(std, str) + key = OptionKey('c_std', subproject, self.for_machine) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('-std=' + std) return args diff --git a/mesonbuild/compilers/objcpp.py b/mesonbuild/compilers/objcpp.py index f355bd2eb0c7..ebd743cc6735 100644 --- a/mesonbuild/compilers/objcpp.py +++ b/mesonbuild/compilers/objcpp.py @@ -112,9 +112,8 @@ def __init__(self, ccache: T.List[str], exelist: T.List[str], version: str, for_ def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] subproject = subproject if subproject is not None else target.subproject - key = OptionKey('cpp_std', machine=self.for_machine) - std = self.get_compileropt_value(key, target, subproject) - assert isinstance(std, str) + key = OptionKey('cpp_std', subproject, self.for_machine) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('-std=' + std) return args diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py index 21a62aba3373..43e9dde7664a 100644 --- a/mesonbuild/compilers/rust.py +++ b/mesonbuild/compilers/rust.py @@ -156,7 +156,8 @@ def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoic self.has_check_cfg = version_compare(version, '>=1.80.0') def init_from_options(self) -> None: - nightly_opt = self.get_compileropt_value('nightly', None) + key = self.form_compileropt_key('nightly', None) + nightly_opt = self.environment.coredata.optstore.get_value_for(key, str) if nightly_opt == 'enabled' and not self.is_nightly: raise EnvironmentException(f'Rust compiler {self.name_string()} is not a nightly compiler as required by the "nightly" option.') self.allow_nightly = nightly_opt != 'disabled' and self.is_nightly @@ -390,8 +391,8 @@ def get_dependency_compile_args(self, dep: 'Dependency') -> T.List[str]: def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: args: T.List[str] = [] subproject = subproject if subproject is not None else target.subproject - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('--edition=' + std) return args diff --git a/mesonbuild/compilers/swift.py b/mesonbuild/compilers/swift.py index da3b12741cb6..58ab86c38ac6 100644 --- a/mesonbuild/compilers/swift.py +++ b/mesonbuild/compilers/swift.py @@ -139,8 +139,8 @@ def get_option_std_args(self, target: T.Optional[build.BuildTarget], subproject: args: T.List[str] = [] subproject = subproject if subproject is not None else target.subproject - std = self.get_compileropt_value('std', target, subproject) - assert isinstance(std, str) + key = self.form_compileropt_key('std', subproject) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args += ['-swift-version', std] From 711defa5ca79511db12a59eb1039438b2e4ac066 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Thu, 12 Mar 2026 09:57:17 -0700 Subject: [PATCH 19/22] backend: delete get_target_option It was just another layer of indirection, and doesn't provide type safety --- mesonbuild/backend/backends.py | 47 +++++++++++------------------ mesonbuild/backend/ninjabackend.py | 32 ++++++++++++-------- mesonbuild/backend/vs2010backend.py | 19 +++++++----- mesonbuild/backend/xcodebackend.py | 10 ++++-- 4 files changed, 54 insertions(+), 54 deletions(-) diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 96d54c6be1bc..483003c96603 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -27,7 +27,7 @@ from .. import compilers from ..compilers import detect, lang_suffixes from ..mesonlib import ( - File, MachineChoice, MesonException, MesonBugException, OrderedSet, + File, MachineChoice, MesonException, OrderedSet, ExecutableSerialisation, EnvironmentException, classify_unity_sources, get_compiler_for_source, get_rsp_threshold, unique_list @@ -43,7 +43,6 @@ from ..interpreter import Test from ..linkers.linkers import StaticLinker from ..mesonlib import FileMode, FileOrString - from ..options import ElementaryOptionValues from typing_extensions import Literal, TypedDict, NotRequired @@ -438,8 +437,7 @@ def generate_unity_files(self, target: build.BuildTarget, unity_src: str) -> T.L abs_files: T.List[str] = [] result: T.List[mesonlib.File] = [] compsrcs = classify_unity_sources(target.compilers.values(), unity_src) - unity_size = self.get_target_option(target, 'unity_size') - assert isinstance(unity_size, int), 'for mypy' + unity_size = self.environment.coredata.optstore.get_option_for_target(target, OptionKey('unity_size'), int) def init_language_file(suffix: str, unity_file_number: int) -> T.TextIO: unity_src = self.get_unity_source_file(target, suffix, unity_file_number) @@ -801,7 +799,7 @@ def object_filename_from_source(self, target: build.BuildTarget, compiler: Compi object_suffix = machine.get_object_suffix() # For the TASKING compiler, in case of LTO or prelinking the object suffix has to be .mil if compiler.get_id() == 'tasking': - use_lto = self.get_target_option(target, 'b_lto') + use_lto = self.environment.coredata.optstore.get_option_for_target(target, OptionKey('b_lto'), bool) if use_lto or (isinstance(target, build.StaticLibrary) and target.prelink): if not source.rsplit('.', 1)[1] in lang_suffixes['c']: if isinstance(target, build.StaticLibrary) and not target.prelink: @@ -853,8 +851,8 @@ def _determine_ext_objs(self, extobj: 'build.ExtractedObjects') -> T.List[str]: if self.is_unity(extobj.target): compsrcs = classify_unity_sources(extobj.target.compilers.values(), sources) sources = [] - unity_size = self.get_target_option(extobj.target, 'unity_size') - assert isinstance(unity_size, int), 'for mypy' + unity_size = self.environment.coredata.optstore.get_option_for_target( + extobj.target, OptionKey('unity_size'), int) for comp, srcs in compsrcs.items(): if comp.language in LANGS_CANT_UNITY: @@ -905,10 +903,8 @@ def create_msvc_pch_implementation(self, target: build.BuildTarget, lang: str, p return pch_rel_to_build def target_uses_pch(self, target: build.BuildTarget) -> bool: - try: - return T.cast('bool', self.get_target_option(target, 'b_pch')) - except (KeyError, AttributeError): - return False + return self.environment.coredata.optstore.get_option_for_target( + target, OptionKey('b_pch'), bool, default=False) @staticmethod def escape_extra_args(args: T.List[str]) -> T.List[str]: @@ -939,24 +935,25 @@ def generate_basic_compiler_args(self, target: build.BuildTarget, compiler: 'Com # Add things like /NOLOGO or -pipe; usually can't be overridden commands += compiler.get_always_args() # warning_level is a string, but mypy can't determine that - commands += compiler.get_warn_args(T.cast('str', self.get_target_option(target, 'warning_level'))) + commands += compiler.get_warn_args(self.environment.coredata.optstore.get_option_for_target( + target, OptionKey('warning_level'), str)) # Add -Werror if werror=true is set in the build options set on the # command-line or default_options inside project(). This only sets the # action to be done for warnings if/when they are emitted, so it's ok # to set it after or get_warn_args(). - if self.get_target_option(target, 'werror'): + if self.environment.coredata.optstore.get_option_for_target(target, OptionKey('werror'), bool): commands += compiler.get_werror_args() # Add compile args for c_* or cpp_* build options set on the # command-line or default_options inside project(). commands += compiler.get_option_compile_args(target) commands += compiler.get_option_std_args(target) - optimization = self.get_target_option(target, 'optimization') - assert isinstance(optimization, str), 'for mypy' + optimization = self.environment.coredata.optstore.get_option_for_target( + target, OptionKey('optimization'), str) commands += compiler.get_optimization_args(optimization) - debug = self.get_target_option(target, 'debug') - assert isinstance(debug, bool), 'for mypy' + debug = self.environment.coredata.optstore.get_option_for_target( + target, OptionKey('debug'), bool) commands += compiler.get_debug_args(debug) # Add compile args added using add_project_arguments() @@ -1736,8 +1733,8 @@ def generate_target_install(self, d: InstallData) -> None: # TODO: Create GNUStrip/AppleStrip/etc. hierarchy for more # fine-grained stripping of static archives. can_strip = not isinstance(t, build.StaticLibrary) - should_strip = can_strip and self.get_target_option(t, 'strip') - assert isinstance(should_strip, bool), 'for mypy' + should_strip = can_strip and self.environment.coredata.optstore.get_option_for_target( + t, OptionKey('strip'), bool) # Install primary build output (library/executable/jar, etc) # Done separately because of strip/aliases/rpath if first_outdir is not False: @@ -2080,7 +2077,7 @@ def compile_target_to_generator(self, target: build.CompileTarget) -> build.Gene def is_unity(self, target: build.BuildTarget) -> bool: if isinstance(target, build.CompileTarget): return False - val = self.get_target_option(target, 'unity') + val = self.environment.coredata.optstore.get_option_for_target(target, OptionKey('unity'), str) if val == 'on': return True if val == 'off': @@ -2088,13 +2085,3 @@ def is_unity(self, target: build.BuildTarget) -> bool: if val == 'subprojects': return target.subproject != '' raise MesonException(f'Internal error: invalid option type for "unity": {val}') - - # TODO: get rid of this - def get_target_option(self, target: build.BuildTarget, name: T.Union[str, OptionKey]) -> ElementaryOptionValues: - if isinstance(name, str): - key = OptionKey(name, subproject=target.subproject) - elif isinstance(name, OptionKey): - key = name - else: - raise MesonBugException('Internal error: invalid option type.') - return self.environment.coredata.optstore.get_option_for_target_untyped(target, key) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index ad781b913e20..e9b5fd63f439 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1134,9 +1134,8 @@ def should_use_dyndeps_for_target(self, target: 'build.BuildTarget') -> bool: cpp = target.compilers['cpp'] if cpp.get_id() != 'msvc': return False - cppversion = self.get_target_option(target, OptionKey('cpp_std', - machine=target.for_machine, - subproject=target.subproject)) + cppversion = self.environment.coredata.optstore.get_option_for_target( + target, OptionKey('cpp_std', machine=target.for_machine, subproject=target.subproject), str) if cppversion not in ('latest', 'c++latest', 'vc++latest'): return False if not mesonlib.current_vs_supports_modules(): @@ -1763,7 +1762,9 @@ def generate_vala_compile(self, target: build.BuildTarget) -> \ valac_outputs.append(vala_c_file) args = self.generate_basic_compiler_args(target, valac) - args += valac.get_colorout_args(self.get_target_option(target, 'b_colorout')) + args += valac.get_colorout_args( + self.environment.coredata.optstore.get_option_for_target( + target, OptionKey('b_colorout'), str)) # Tell Valac to output everything in our private directory. Sadly this # means it will also preserve the directory components of Vala sources # found inside the build tree (generated sources). @@ -1840,15 +1841,18 @@ def generate_cython_transpile(self, target: build.BuildTarget) -> \ args: T.List[str] = [] args += cython.get_always_args() - args += cython.get_debug_args(self.get_target_option(target, 'debug')) - args += cython.get_optimization_args(self.get_target_option(target, 'optimization')) + args += cython.get_debug_args(self.environment.coredata.optstore.get_option_for_target( + target, OptionKey('debug'), bool)) + args += cython.get_optimization_args(self.environment.coredata.optstore.get_option_for_target( + target, OptionKey('optimization'), str)) args += cython.get_option_compile_args(target) - args += cython.get_option_std_args(target, target.subproject) + args += cython.get_option_std_args(target) args += self.build.get_global_args(cython, target.for_machine) args += self.build.get_project_args(cython, target) args += target.get_extra_args('cython') - ext = self.get_target_option(target, OptionKey('cython_language', machine=target.for_machine)) + ext = self.environment.coredata.optstore.get_option_for_target( + target, OptionKey('cython_language', machine=target.for_machine), str) pyx_sources = [] # Keep track of sources we're adding to build @@ -2193,7 +2197,7 @@ def _link_library(libname: str, static: bool, bundle: bool = False) -> None: # against are dynamic or this is a dynamic library itself, # otherwise we'll end up with multiple implementations of libstd. has_rust_shared_deps = True - elif self.get_target_option(target, 'rust_dynamic_std'): + elif self.environment.coredata.optstore.get_option_for_target(target, OptionKey('rust_dynamic_std'), bool): if target.rust_crate_type == 'staticlib': # staticlib crates always include a copy of the Rust libstd, # therefore it is not possible to also link it dynamically. @@ -3251,7 +3255,7 @@ def generate_single_compile(self, target: build.BuildTarget, src, # then compilation rule name is a special one to output MIL files # instead of object files for .c files if compiler.get_id() == 'tasking': - target_lto = self.get_target_option(target, OptionKey('b_lto', machine=target.for_machine, subproject=target.subproject)) + target_lto = self.environment.coredata.optstore.get_option_for_target(target, OptionKey('b_lto', target.subproject, target.for_machine), bool) if ((isinstance(target, build.StaticLibrary) and target.prelink) or target_lto) and src.rsplit('.', 1)[1] in compilers.lang_suffixes['c']: compiler_name = self.get_compiler_rule_name('tasking_mil_compile', compiler.for_machine) else: @@ -3769,9 +3773,10 @@ def generate_link(self, target: build.BuildTarget, outname, obj_list, linker: T. # Add things like /NOLOGO; usually can't be overridden commands += linker.get_linker_always_args() # Add buildtype linker args: optimization level, etc. - commands += linker.get_optimization_link_args(self.get_target_option(target, 'optimization')) + commands += linker.get_optimization_link_args( + self.environment.coredata.optstore.get_option_for_target(target, OptionKey('optimization'), str)) # Add /DEBUG and the pdb filename when using MSVC - if self.get_target_option(target, 'debug'): + if self.environment.coredata.optstore.get_option_for_target(target, OptionKey('debug'), bool): commands += self.get_link_debugfile_args(linker, target) debugfile = self.get_link_debugfile_name(linker, target) if debugfile is not None: @@ -3861,7 +3866,8 @@ def generate_link(self, target: build.BuildTarget, outname, obj_list, linker: T. elem = NinjaBuildElement(self.all_outputs, outname, linker_rule, obj_list, implicit_outs=implicit_outs) elem.add_dep(dep_targets + custom_target_libraries) if linker.get_id() == 'tasking': - if len([x for x in dep_targets + custom_target_libraries if x.endswith('.ma')]) > 0 and not self.get_target_option(target, OptionKey('b_lto', target.subproject, target.for_machine)): + if (any(x for x in dep_targets + custom_target_libraries if x.endswith('.ma')) and not + self.environment.coredata.optstore.get_option_for_target(target, OptionKey('b_lto', target.subproject, target.for_machine), bool)): raise MesonException(f'Tried to link the target named \'{target.name}\' with a MIL archive without LTO enabled! This causes the compiler to ignore the archive.') # Compiler args must be included in TI C28x linker commands. diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index 072c056e5e22..5fbc6702570c 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -1043,7 +1043,8 @@ def get_args_defines_and_inc_dirs(self, target: build.BuildTarget, compiler: com # Compile args added from the env or cross file: CFLAGS/CXXFLAGS, etc. We want these # to override all the defaults, but not the per-target compile args. for lang in file_args.keys(): - file_args[lang] += self.get_target_option(target, OptionKey(f'{lang}_args', machine=target.for_machine)) + file_args[lang] += self.environment.coredata.optstore.get_option_for_target( + target, OptionKey(f'{lang}_args', target.subproject, target.for_machine), list) for args in file_args.values(): # This is where Visual Studio will insert target_args, target_defines, # etc, which are added later from external deps (see below). @@ -1318,8 +1319,8 @@ def add_non_makefile_vcxproj_elements( # FIXME: Should the following just be set in create_basic_project(), even if # irrelevant for current target? - lto = self.get_target_option(target, 'b_lto') - pgo = self.get_target_option(target, 'b_pgo') + lto = self.environment.coredata.optstore.get_option_for_target(target, OptionKey('b_lto'), bool) + pgo = self.environment.coredata.optstore.get_option_for_target(target, OptionKey('b_pgo'), str) if lto: if pgo == 'off': @@ -1344,7 +1345,8 @@ def add_non_makefile_vcxproj_elements( if True in ((dep.name == 'openmp') for dep in target.get_external_deps()): ET.SubElement(clconf, 'OpenMPSupport').text = 'true' # CRT type; debug or release - vscrt_type = self.get_target_option(target, 'b_vscrt') + vscrt_type = self.environment.coredata.optstore.get_option_for_target( + target, OptionKey('b_vscrt'), str) vscrt_val = compiler.get_crt_val(vscrt_type) if vscrt_val == 'mdd': ET.SubElement(type_config, 'UseDebugLibraries').text = 'true' @@ -1400,10 +1402,11 @@ def add_non_makefile_vcxproj_elements( ET.SubElement(clconf, 'PreprocessorDefinitions').text = ';'.join(target_defines) ET.SubElement(clconf, 'FunctionLevelLinking').text = 'true' # Warning level - warning_level = T.cast('str', self.get_target_option(target, 'warning_level')) + warning_level = self.environment.coredata.optstore.get_option_for_target( + target, OptionKey('warning_level'), str) warning_level = 'EnableAllWarnings' if warning_level == 'everything' else 'Level' + str(1 + int(warning_level)) ET.SubElement(clconf, 'WarningLevel').text = warning_level - if self.get_target_option(target, 'werror'): + if self.environment.coredata.optstore.get_option_for_target(target, OptionKey('werror'), bool): ET.SubElement(clconf, 'TreatWarningAsError').text = 'true' # Optimization flags o_flags = split_o_flags_args(build_args) @@ -1568,8 +1571,8 @@ def add_non_makefile_vcxproj_elements( # /nologo ET.SubElement(link, 'SuppressStartupBanner').text = 'true' # /release - addchecksum = self.get_target_option(target, 'buildtype') != 'debug' - if addchecksum: + buildtype = self.environment.coredata.optstore.get_option_for_target(target, OptionKey('buildtype'), str) + if buildtype != 'debug': ET.SubElement(link, 'SetChecksum').text = 'true' # Visual studio doesn't simply allow the src files of a project to be added with the 'Condition=...' attribute, diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py index 8dc9ea12da57..bf4a06e931e8 100644 --- a/mesonbuild/backend/xcodebackend.py +++ b/mesonbuild/backend/xcodebackend.py @@ -1740,7 +1740,9 @@ def generate_single_build_target(self, objects_dict: PbxDict, target_name: str, if compiler is None: continue # Start with warning args - warn_args = compiler.get_warn_args(self.get_target_option(target, 'warning_level')) + warn_args = compiler.get_warn_args( + self.environment.coredata.optstore.get_option_for_target( + target, OptionKey('warning_level'), str)) std_args = compiler.get_option_compile_args(target) std_args += compiler.get_option_std_args(target, target.subproject) # Add compile args added using add_project_arguments() @@ -1791,9 +1793,11 @@ def generate_single_build_target(self, objects_dict: PbxDict, target_name: str, if target.suffix: suffix = '.' + target.suffix settings_dict.add_item('EXECUTABLE_SUFFIX', suffix) - settings_dict.add_item('GCC_GENERATE_DEBUGGING_SYMBOLS', BOOL2XCODEBOOL[self.get_target_option(target, 'debug')]) + settings_dict.add_item('GCC_GENERATE_DEBUGGING_SYMBOLS', BOOL2XCODEBOOL[ + self.environment.coredata.optstore.get_option_for_target(target, OptionKey('debug'), bool)]) settings_dict.add_item('GCC_INLINES_ARE_PRIVATE_EXTERN', 'NO') - opt_flag = OPT2XCODEOPT[self.get_target_option(target, 'optimization')] + opt_flag = OPT2XCODEOPT[ + self.environment.coredata.optstore.get_option_for_target(target, OptionKey('optimization'), str)] if opt_flag is not None: settings_dict.add_item('GCC_OPTIMIZATION_LEVEL', opt_flag) if target.has_pch: From cdf0fa9a8e10a505bffa9870e7fe23890f33213d Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Thu, 12 Mar 2026 11:08:51 -0700 Subject: [PATCH 20/22] compilers: replace get_option_value_for_target with OptionStore methods --- mesonbuild/compilers/compilers.py | 32 ++++++++----------------------- 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 2d13c0758327..d0c3135cb533 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -252,19 +252,6 @@ def option_enabled(boptions: T.Set[OptionKey], return env.coredata.optstore.get_option_for_target(target, option, bool, default=False) -# TODO: delete this -def get_option_value_for_target(env: 'Environment', target: 'BuildTarget', opt: OptionKey, fallback: '_T') -> '_T': - """Get the value of an option, or the fallback value.""" - try: - v = env.coredata.optstore.get_option_for_target_untyped(target, opt) - except (KeyError, AttributeError): - return fallback - - assert isinstance(v, type(fallback)), f'Should have {type(fallback)!r} but was {type(v)!r}' - # Mypy doesn't understand that the above assert ensures that v is type _T - return v - - def are_asserts_disabled(target: 'BuildTarget', env: 'Environment') -> bool: """Should debug assertions be disabled @@ -291,8 +278,8 @@ def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Env lto = False try: if env.coredata.optstore.get_option_for_target(target, OptionKey('b_lto'), bool): - num_threads = get_option_value_for_target(env, target, OptionKey('b_lto_threads'), 0) - ltomode = get_option_value_for_target(env, target, OptionKey('b_lto_mode'), 'default') + num_threads = env.coredata.optstore.get_option_for_target(target, OptionKey('b_lto_threads'), int, default=0) + ltomode = env.coredata.optstore.get_option_for_target(target, OptionKey('b_lto_mode'), str, default='default') args.extend(compiler.get_lto_compile_args( target=target, threads=num_threads, @@ -355,19 +342,16 @@ def get_base_link_args(target: 'BuildTarget', args: T.List[str] = [] build_dir = env.get_build_dir() try: - if env.coredata.optstore.get_option_for_target(target, OptionKey('b_lto'), bool): - if env.coredata.optstore.get_option_for_target(target, OptionKey('werror'), bool): - args.extend(linker.get_werror_args()) - + if env.coredata.optstore.get_option_for_target(target, OptionKey('b_lto'), bool, default=False): thinlto_cache_dir = None cachedir_key = OptionKey('b_thinlto_cache') - if get_option_value_for_target(env, target, cachedir_key, False): - thinlto_cache_dir = get_option_value_for_target(env, target, OptionKey('b_thinlto_cache_dir'), '') + if env.coredata.optstore.get_option_for_target(target, cachedir_key, bool, default=False): + thinlto_cache_dir = env.coredata.optstore.get_option_for_target(target, OptionKey('b_thinlto_cache_dir'), str, default='') if thinlto_cache_dir == '': thinlto_cache_dir = os.path.join(build_dir, 'meson-private', 'thinlto-cache') - os.makedirs(thinlto_cache_dir, exist_ok=True) - num_threads = get_option_value_for_target(env, target, OptionKey('b_lto_threads'), 0) - lto_mode = get_option_value_for_target(env, target, OptionKey('b_lto_mode'), 'default') + os.mkdir(thinlto_cache_dir) + num_threads = env.coredata.optstore.get_option_for_target(target, OptionKey('b_lto_threads'), int, default=0) + lto_mode = env.coredata.optstore.get_option_for_target(target, OptionKey('b_lto_mode'), str, default='default') args.extend(linker.get_lto_link_args( target=target, threads=num_threads, From 2958e54b3e222a244230c91c74540ad515dba5a8 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 3 Apr 2026 11:19:28 -0700 Subject: [PATCH 21/22] compilers: Use get_option_for_maybe_target --- mesonbuild/compilers/cpp.py | 13 +++---------- mesonbuild/compilers/cuda.py | 11 ++++------- mesonbuild/compilers/mixins/elbrus.py | 6 +----- mesonbuild/compilers/objc.py | 6 +----- mesonbuild/compilers/objcpp.py | 6 +----- 5 files changed, 10 insertions(+), 32 deletions(-) diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 78aa58d53d78..7d758931f7bc 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -808,13 +808,9 @@ def get_option_link_args(self, target: None, subproject: SubProject) -> T.List[s def get_option_link_args(self, target: T.Optional[BuildTarget], subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = subproject if subproject is not None else target.subproject - # need a typeddict for this key = self.form_compileropt_key('winlibs', subproject) - if target: - value = self.environment.coredata.optstore.get_option_for_target_untyped(target, key) - else: - value = self.environment.coredata.optstore.get_value_for_untyped(key) - return T.cast('T.List[str]', value)[:] + value = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, list) + return value.copy() def _get_options_impl(self, opts: 'MutableKeyedOptionDictType', cpp_stds: T.List[str]) -> 'MutableKeyedOptionDictType': opts = super().get_options() @@ -922,10 +918,7 @@ def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Opt # (i.e., after VS2015U3) # if one is using anything before that point, one cannot set the standard. stdkey = self.form_compileropt_key('std', subproject) - if target is not None: - std = self.environment.coredata.optstore.get_option_for_target_untyped(target, stdkey) - else: - std = self.environment.coredata.optstore.get_value_for_untyped(stdkey) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, stdkey, str) if std in {'vc++11', 'c++11'}: mlog.warning(self.id, 'does not support C++11;', 'attempting best effort; setting the standard to C++14', diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py index e443a7e09d34..75d203e4fd1a 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -778,14 +778,11 @@ def _get_ccbin_args(self, target: 'T.Optional[BuildTarget]', subproject: T.Optional[SubProject] = None) -> T.List[str]: subproject = target.subproject if subproject is None else subproject key = self.form_compileropt_key('ccbindir', subproject) - if target: - ccbindir = self.environment.coredata.optstore.get_option_for_target_untyped(target, key) - else: - ccbindir = self.environment.coredata.optstore.get_value_for_untyped(key) - if isinstance(ccbindir, str) and ccbindir != '': + ccbindir = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) + + if ccbindir != '': return [self._shield_nvcc_list_arg('-ccbin='+ccbindir, False)] - else: - return [] + return [] def get_profile_generate_args(self) -> T.List[str]: return ['-Xcompiler=' + x for x in self.host_compiler.get_profile_generate_args()] diff --git a/mesonbuild/compilers/mixins/elbrus.py b/mesonbuild/compilers/mixins/elbrus.py index 10058d9a1dab..de37408ec104 100644 --- a/mesonbuild/compilers/mixins/elbrus.py +++ b/mesonbuild/compilers/mixins/elbrus.py @@ -87,11 +87,7 @@ def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Opt args: T.List[str] = [] subproject = subproject if subproject is not None else target.subproject key = OptionKey(f'{self.language}_std', subproject=subproject, machine=self.for_machine) - if target: - std = self.environment.coredata.optstore.get_option_for_target_untyped(target, key) - else: - std = self.environment.coredata.optstore.get_value_for_untyped(key) - assert isinstance(std, str) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('-std=' + std) return args diff --git a/mesonbuild/compilers/objc.py b/mesonbuild/compilers/objc.py index de8a1060a763..f4b88ae7a2e2 100644 --- a/mesonbuild/compilers/objc.py +++ b/mesonbuild/compilers/objc.py @@ -79,11 +79,7 @@ def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Opt args: T.List[str] = [] subproject = subproject if subproject is not None else target.subproject key = OptionKey('c_std', subproject=subproject, machine=self.for_machine) - if target: - std = self.environment.coredata.optstore.get_option_for_target_untyped(target, key) - else: - std = self.environment.coredata.optstore.get_value_for_untyped(key) - assert isinstance(std, str) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('-std=' + std) return args diff --git a/mesonbuild/compilers/objcpp.py b/mesonbuild/compilers/objcpp.py index ebd743cc6735..b2c605074275 100644 --- a/mesonbuild/compilers/objcpp.py +++ b/mesonbuild/compilers/objcpp.py @@ -83,11 +83,7 @@ def get_option_std_args(self, target: T.Optional[BuildTarget], subproject: T.Opt args: T.List[str] = [] subproject = subproject if subproject is not None else target.subproject key = OptionKey('cpp_std', subproject=subproject, machine=self.for_machine) - if target: - std = self.environment.coredata.optstore.get_option_for_target_untyped(target, key) - else: - std = self.environment.coredata.optstore.get_value_for_untyped(key) - assert isinstance(std, str) + std = self.environment.coredata.optstore.get_option_for_maybe_target(target, key, str) if std != 'none': args.append('-std=' + std) return args From 12bbf92dbcfceb916ddfd5416ed837a2c6b04229 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 3 Apr 2026 11:25:03 -0700 Subject: [PATCH 22/22] compilers: Remove option_enabled This is just a wrapper around `get_value_for_target` with `default=False`. --- mesonbuild/compilers/compilers.py | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index d0c3135cb533..28c471d552b8 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -240,18 +240,6 @@ class CompileCheckMode(enum.Enum): } -# TODO: Can we delete this? -def option_enabled(boptions: T.Set[OptionKey], - target: 'BuildTarget', - env: 'Environment', - option: T.Union[str, OptionKey]) -> bool: - if isinstance(option, str): - option = OptionKey(option) - if option not in boptions: - return False - return env.coredata.optstore.get_option_for_target(target, option, bool, default=False) - - def are_asserts_disabled(target: 'BuildTarget', env: 'Environment') -> bool: """Should debug assertions be disabled @@ -323,7 +311,7 @@ def get_base_compile_args(target: 'BuildTarget', compiler: 'Compiler', env: 'Env except KeyError: pass # This does not need a try...except - bitcode = option_enabled(compiler.base_options, target, env, 'b_bitcode') + bitcode = env.coredata.optstore.get_option_for_target(target, OptionKey('b_bitcode'), bool, default=False) args.extend(compiler.get_embed_bitcode_args(bitcode, lto)) try: crt_val = env.coredata.optstore.get_option_for_target(target, OptionKey('b_vscrt'), str) @@ -388,8 +376,8 @@ def get_base_link_args(target: 'BuildTarget', except (KeyError, AttributeError): pass - as_needed = option_enabled(linker.base_options, target, env, 'b_asneeded') - bitcode = option_enabled(linker.base_options, target, env, 'b_bitcode') + as_needed = env.coredata.optstore.get_option_for_target(target, OptionKey('b_asneeded'), bool, default=False) + bitcode = env.coredata.optstore.get_option_for_target(target, OptionKey('b_bitcode'), bool, default=False) # Shared modules cannot be built with bitcode_bundle because # -bitcode_bundle is incompatible with -undefined and -bundle if bitcode and not target.typename == 'shared module': @@ -404,7 +392,7 @@ def get_base_link_args(target: 'BuildTarget', from ..build import SharedModule args.extend(linker.headerpad_args()) if (not isinstance(target, SharedModule) and - option_enabled(linker.base_options, target, env, 'b_lundef')): + env.coredata.optstore.get_option_for_target(target, OptionKey('b_lundef'), bool, default=False)): args.extend(linker.no_undefined_link_args()) else: args.extend(linker.get_allow_undefined_link_args())