interpreter: Add summary of all user defined options

It is a commonly needed information to help debugging build issues. We
already were printing options with non-default value at the end of the
configure but outside of the summary.

Keeping the list of user defined options in the interpreter will also in
the future be useful to use new default value on reconfigure.
pull/9214/head
Xavier Claessens 4 years ago committed by Xavier Claessens
parent a616a23713
commit 5e55a0bb2b
  1. 6
      mesonbuild/coredata.py
  2. 26
      mesonbuild/interpreter/interpreter.py
  3. 15
      mesonbuild/msetup.py
  4. 2
      test cases/unit/72 summary/meson_options.txt
  5. 8
      unittests/allplatformstests.py

@ -981,10 +981,8 @@ def update_cmd_line_file(build_dir: str, options: argparse.Namespace):
with open(filename, 'w', encoding='utf-8') as f:
config.write(f)
def get_cmd_line_options(build_dir: str, options: argparse.Namespace) -> str:
copy = argparse.Namespace(**vars(options))
read_cmd_line_file(build_dir, copy)
cmdline = ['-D{}={}'.format(str(k), v) for k, v in copy.cmd_line_options.items()]
def format_cmd_line_options(options: argparse.Namespace) -> str:
cmdline = ['-D{}={}'.format(str(k), v) for k, v in options.cmd_line_options.items()]
if options.cross_file:
cmdline += [f'--cross-file {f}' for f in options.cross_file]
if options.native_file:

@ -72,6 +72,7 @@ import textwrap
import importlib
if T.TYPE_CHECKING:
import argparse
from . import kwargs
# Input source types passed to Targets
@ -229,6 +230,7 @@ class Interpreter(InterpreterBase, HoldableObject):
mock: bool = False,
ast: T.Optional[mparser.CodeBlockNode] = None,
is_translated: bool = False,
user_defined_options: T.Optional['argparse.Namespace'] = None,
) -> None:
super().__init__(_build.environment.get_source_dir(), subdir, subproject)
self.build = _build
@ -264,6 +266,7 @@ class Interpreter(InterpreterBase, HoldableObject):
self.project_default_options = {}
self.build_func_dict()
self.build_holder_map()
self.user_defined_options = user_defined_options
# build_def_files needs to be defined before parse_project is called
#
@ -299,18 +302,6 @@ class Interpreter(InterpreterBase, HoldableObject):
self.builtin['target_machine'] = \
OBJ.MachineHolder(self.build.environment.machines.target, self)
# TODO: Why is this in interpreter.py and not CoreData or Environment?
def get_non_matching_default_options(self) -> T.Iterator[T.Tuple[str, str, coredata.UserOption]]:
for def_opt_name, def_opt_value in self.project_default_options.items():
cur_opt_value = self.coredata.options.get(def_opt_name)
try:
if cur_opt_value is not None and cur_opt_value.validate_value(def_opt_value) != cur_opt_value.value:
yield (str(def_opt_name), def_opt_value, cur_opt_value)
except mesonlib.MesonException:
# Since the default value does not validate, it cannot be in use
# Report the user-specified value as non-matching
yield (str(def_opt_name), def_opt_value, cur_opt_value)
def build_func_dict(self):
self.funcs.update({'add_global_arguments': self.func_add_global_arguments,
'add_project_arguments': self.func_add_project_arguments,
@ -1187,6 +1178,17 @@ external dependencies (including libraries) must go to "dependencies".''')
{'bool_yn': True,
'list_sep': ' ',
})
# Add automatic section with all user defined options
if self.user_defined_options:
values = collections.OrderedDict()
if self.user_defined_options.cross_file:
values['Cross files'] = self.user_defined_options.cross_file
if self.user_defined_options.native_file:
values['Native files'] = self.user_defined_options.native_file
sorted_options = sorted(self.user_defined_options.cmd_line_options.items())
values.update({str(k): v for k, v in sorted_options})
if values:
self.summary_impl('User defined options', values, {})
# Print all summaries, main project last.
mlog.log('') # newline
main_summary = self.summary.pop('', None)

@ -28,7 +28,6 @@ from . import environment, interpreter, mesonlib
from . import build
from . import mlog, coredata
from . import mintro
from .mconf import make_lower_case
from .mesonlib import MesonException
git_ignore_file = '''# This file is autogenerated by Meson. If you change or delete it, it won't be recreated.
@ -184,9 +183,14 @@ class MesonApp:
self._generate(env)
def _generate(self, env: environment.Environment) -> None:
# Get all user defined options, including options that have been defined
# during a previous invocation or using meson configure.
user_defined_options = argparse.Namespace(**vars(self.options))
coredata.read_cmd_line_file(self.build_dir, user_defined_options)
mlog.debug('Build started at', datetime.datetime.now().isoformat())
mlog.debug('Main binary:', sys.executable)
mlog.debug('Build Options:', coredata.get_cmd_line_options(self.build_dir, self.options))
mlog.debug('Build Options:', coredata.format_cmd_line_options(user_defined_options))
mlog.debug('Python system:', platform.system())
mlog.log(mlog.bold('The Meson build system'))
mlog.log('Version:', coredata.version)
@ -198,7 +202,7 @@ class MesonApp:
mlog.log('Build type:', mlog.bold('native build'))
b = build.Build(env)
intr = interpreter.Interpreter(b)
intr = interpreter.Interpreter(b, user_defined_options=user_defined_options)
if env.is_cross_build():
logger_fun = mlog.log
else:
@ -224,11 +228,6 @@ class MesonApp:
except Exception as e:
mintro.write_meson_info_file(b, [e])
raise
# Print all default option values that don't match the current value
for def_opt_name, def_opt_value, cur_opt_value in intr.get_non_matching_default_options():
mlog.log('Option', mlog.bold(def_opt_name), 'is:',
mlog.bold('{}'.format(make_lower_case(cur_opt_value.printable_value()))),
'[default: {}]'.format(make_lower_case(def_opt_value)))
try:
dumpfile = os.path.join(env.get_scratch_dir(), 'build.dat')
# We would like to write coredata as late as possible since we use the existence of

@ -1 +1 @@
option('enabled_opt', type: 'feature', value: 'enabled')
option('enabled_opt', type: 'feature', value: 'auto')

@ -3086,7 +3086,7 @@ class AllPlatformTests(BasePlatformTests):
def test_summary(self):
testdir = os.path.join(self.unit_test_dir, '72 summary')
out = self.init(testdir)
out = self.init(testdir, extra_args=['-Denabled_opt=enabled'])
expected = textwrap.dedent(r'''
Some Subproject 2.0
@ -3128,6 +3128,12 @@ class AllPlatformTests(BasePlatformTests):
sub : YES
sub2 : NO Problem encountered: This subproject failed
subsub : YES
User defined options
backend : ''' + self.backend.name + '''
libdir : lib
prefix : /usr
enabled_opt : enabled
''')
expected_lines = expected.split('\n')[1:]
out_start = out.find(expected_lines[0])

Loading…
Cancel
Save