Skip to content

Commit

Permalink
WIP: use a version argument to get_option() instead of adding a new…
Browse files Browse the repository at this point in the history
… option
  • Loading branch information
dcbaker committed Dec 20, 2023
1 parent bb16279 commit 78c5c45
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 19 deletions.
8 changes: 3 additions & 5 deletions docs/markdown/Builtin-options.md
Original file line number Diff line number Diff line change
Expand Up @@ -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) |
Expand All @@ -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

Expand Down
3 changes: 2 additions & 1 deletion docs/markdown/snippets/b_sanitizer_changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
24 changes: 14 additions & 10 deletions mesonbuild/interpreter/interpreter.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}}}')
Expand Down
9 changes: 7 additions & 2 deletions mesonbuild/interpreter/kwargs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: Apache-2.0
# Copyright © 2021 The Meson Developers
# Copyright © 2021 Intel Corporation
# Copyright 2021 The Meson Developers
# Copyright © 2021-2023 Intel Corporation
from __future__ import annotations

"""Keyword Argument type annotations."""
Expand Down Expand Up @@ -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
2 changes: 1 addition & 1 deletion test cases/linuxlike/16 sanitizers/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -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)

0 comments on commit 78c5c45

Please sign in to comment.