From b9ab0bf6bcb408b9b89ae2da12754029ddb81ed2 Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Wed, 20 Dec 2023 14:23:26 -0800 Subject: [PATCH] WIP: use a version argument to `get_option()` instead of adding a new option --- docs/markdown/Builtin-options.md | 8 +++---- docs/markdown/snippets/b_sanitizer_changes.md | 3 ++- mesonbuild/interpreter/interpreter.py | 24 +++++++++++-------- mesonbuild/interpreter/kwargs.py | 9 +++++-- .../linuxlike/16 sanitizers/meson.build | 2 +- 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/docs/markdown/Builtin-options.md b/docs/markdown/Builtin-options.md index 3bdee12128ee..7cd0085ab814 100644 --- a/docs/markdown/Builtin-options.md +++ b/docs/markdown/Builtin-options.md @@ -206,7 +206,6 @@ available on all platforms or with all compilers: | b_pch | true | true, false | Use precompiled headers | | b_pgo | off | off, generate, use | Use profile guided optimization | | b_sanitize | none | see below | Code sanitizer to use | -| b_sanitizers | [] | see below | Code sanitizer to use | | b_staticpic | true | true, false | Build static libraries as position independent | | b_pie | false | true, false | Build position-independent executables (since 0.49.0) | | b_vscrt | from_buildtype | none, md, mdd, mt, mtd, from_buildtype, static_from_buildtype | VS runtime library to use (since 0.48.0) (static_from_buildtype since 0.56.0) | @@ -218,10 +217,9 @@ were string values, and restricted to a specific subset of values: `none`, compiler and linker check. For backwards compatibility reasons `get_option('b_sanitize')` continues to return a string value, which is guaranteed to match the old string value if the array value contains the same -values (ie, `['undefined', 'address'] == 'address,undefined`). I a value not -allowed before 1.4 is used `b_sanitize` will return a string in undefined order. -A new value of `b_sanitizers` can be used for >= 1.4 to get a free form array, -with no ordering guarantees. +values (ie, `['undefined', 'address'] == 'address,undefined`). However, +`get_option('b_sanitize', version : 2)`, Meson will return an array in +unspecified order. \* < 0 means disable, == 0 means automatic selection, > 0 sets a specific number to use diff --git a/docs/markdown/snippets/b_sanitizer_changes.md b/docs/markdown/snippets/b_sanitizer_changes.md index 114b16b29988..a3769db36cef 100644 --- a/docs/markdown/snippets/b_sanitizer_changes.md +++ b/docs/markdown/snippets/b_sanitizer_changes.md @@ -12,5 +12,6 @@ This solves a number of longstanding issues such as: In order to not break backwards compatibility, meson will continue to return `get_option('b_sanitize')` as a string, with a guarantee that -`address,undefined` will remain ordered. A new `get_option('b_sanitizers')` +`address,undefined` will remain ordered. Calling + `get_option('b_sanitize', version : 2)` option returns a free form list with no ordering guarantees. diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 08b26c966275..44cbac58e39f 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -1079,31 +1079,35 @@ def get_option_internal(self, optname: str) -> coredata.UserOption: raise InterpreterException(f'Tried to access unknown option {optname!r}.') @typed_pos_args('get_option', str) - @noKwargs + @typed_kwargs('get_option', KwargInfo('version', int, default=1, since='1.4', validator=lambda x: 'Must be an integer greater than 0' if x < 1 else None)) def func_get_option(self, node: mparser.BaseNode, args: T.Tuple[str], - kwargs: 'TYPE_kwargs') -> T.Union[coredata.UserOption, 'TYPE_var']: + kwargs: kwtypes.FuncGetOption) -> T.Union[coredata.UserOption, 'TYPE_var']: optname = args[0] + opt_ver = kwargs['version'] + if optname == 'b_sanitize': + if opt_ver > 2: + raise InvalidArguments('b_sanitize only has two option versions') + FeatureNew.single_use('b_sanitize version 2 (as an array)', '1.4', self.subproject, location=node) + elif opt_ver != 1: + raise InvalidArguments(f'{optname} does not have multiple versions') + if ':' in optname: raise InterpreterException('Having a colon in option name is forbidden, ' 'projects are not allowed to directly access ' 'options of other subprojects.') - if optname_regex.search(optname.split('.', maxsplit=1)[-1]) is not None: raise InterpreterException(f'Invalid option name {optname!r}') - if optname == 'b_sanitizers': - FeatureNew.single_use('get_option(\'b_sanitizers\')', '1.4', self.subproject, 'use b_sanitize instead', node) - opt = self.get_option_internal('b_sanitize') - else: - opt = self.get_option_internal(optname) + opt = self.get_option_internal(optname) if isinstance(opt, coredata.UserFeatureOption): opt.name = optname return opt elif optname == 'b_sanitize': assert isinstance(opt, coredata.UserArrayOption), 'for mypy' - # to ensure backwards compat this always returns a string - return ','.join(sorted(opt.value)) + if opt_ver == 1: + return ','.join(sorted(opt.value)) + return opt.value elif isinstance(opt, coredata.UserOption): if isinstance(opt.value, str): return P_OBJ.OptionString(opt.value, f'{{{optname}}}') diff --git a/mesonbuild/interpreter/kwargs.py b/mesonbuild/interpreter/kwargs.py index 17f7876a04d0..813b590b79f9 100644 --- a/mesonbuild/interpreter/kwargs.py +++ b/mesonbuild/interpreter/kwargs.py @@ -1,6 +1,6 @@ # SPDX-License-Identifier: Apache-2.0 -# Copyright © 2021 The Meson Developers -# Copyright © 2021 Intel Corporation +# Copyright © 2021-2023 Intel Corporation +# Copyright © 2021-2023 Intel Corporation from __future__ import annotations """Keyword Argument type annotations.""" @@ -475,3 +475,8 @@ class FuncDeclareDependency(TypedDict): sources: T.List[T.Union[FileOrString, build.GeneratedTypes]] variables: T.Dict[str, str] version: T.Optional[str] + + +class FuncGetOption(TypedDict): + + version: int diff --git a/test cases/linuxlike/16 sanitizers/meson.build b/test cases/linuxlike/16 sanitizers/meson.build index 183faff2fd76..2b9400230bf8 100644 --- a/test cases/linuxlike/16 sanitizers/meson.build +++ b/test cases/linuxlike/16 sanitizers/meson.build @@ -5,6 +5,6 @@ project('sanitizer', 'c', meson_version : '>= 1.4') assert(get_option('b_sanitize') == 'address,undefined', 'order of address + undefined is not correct') -array = get_option('b_sanitizers') +array = get_option('b_sanitize', version : 2) assert('address' in array) assert('undefined' in array)