aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Claessens <xavier.claessens@collabora.com>2019-07-17 14:17:18 -0400
committerJussi Pakkanen <jpakkane@gmail.com>2019-10-18 00:49:27 +0300
commit88e77e69bc91eeac271c7806fd2b1fc398db9a42 (patch)
tree2abcde987d612e4354620fcfd53d7d5f908022c9
parentb626978dc628cd9992ee2b7dbd83b566fde3b586 (diff)
downloadmeson-88e77e69bc91eeac271c7806fd2b1fc398db9a42.zip
meson-88e77e69bc91eeac271c7806fd2b1fc398db9a42.tar.gz
meson-88e77e69bc91eeac271c7806fd2b1fc398db9a42.tar.bz2
mconf: Group all options per subproject and align all groups
Also hide value of yielding subproject options to make it clear the value must be set on the main project.
-rw-r--r--mesonbuild/mconf.py187
1 files changed, 115 insertions, 72 deletions
diff --git a/mesonbuild/mconf.py b/mesonbuild/mconf.py
index 4f80140..e5b3796 100644
--- a/mesonbuild/mconf.py
+++ b/mesonbuild/mconf.py
@@ -43,6 +43,13 @@ class Conf:
self.build_dir = os.path.dirname(self.build_dir)
self.build = None
self.max_choices_line_length = 60
+ self.name_col = []
+ self.value_col = []
+ self.choices_col = []
+ self.descr_col = []
+ self.has_choices = False
+ self.all_subprojects = set()
+ self.yielding_options = set()
if os.path.isdir(os.path.join(self.build_dir, 'meson-private')):
self.build = build.load(self.build_dir)
@@ -79,71 +86,89 @@ class Conf:
# are erased when Meson is executed the next time, i.e. when
# Ninja is run.
- def print_aligned(self, arr):
- if not arr:
- return
+ def print_aligned(self):
+ col_widths = (max([len(i) for i in self.name_col], default=0),
+ max([len(i) for i in self.value_col], default=0),
+ max([len(i) for i in self.choices_col], default=0))
- titles = {'name': 'Option', 'descr': 'Description', 'value': 'Current Value', 'choices': 'Possible Values'}
- if self.default_values_only:
- titles['value'] = 'Default Value'
-
- name_col = [titles['name'], '-' * len(titles['name'])]
- value_col = [titles['value'], '-' * len(titles['value'])]
- choices_col = [titles['choices'], '-' * len(titles['choices'])]
- descr_col = [titles['descr'], '-' * len(titles['descr'])]
-
- choices_found = False
- for opt in arr:
- name_col.append(opt['name'])
- descr_col.append(opt['descr'])
- if isinstance(opt['value'], list):
- value_col.append('[{0}]'.format(', '.join(make_lower_case(opt['value']))))
- else:
- value_col.append(make_lower_case(opt['value']))
- if opt['choices']:
- choices_found = True
- if isinstance(opt['choices'], list):
- choices_list = make_lower_case(opt['choices'])
- current = '['
- while choices_list:
- i = choices_list.pop(0)
- if len(current) + len(i) >= self.max_choices_line_length:
- choices_col.append(current + ',')
- name_col.append('')
- value_col.append('')
- descr_col.append('')
- current = ' '
- if len(current) > 1:
- current += ', '
- current += i
- choices_col.append(current + ']')
- else:
- choices_col.append(make_lower_case(opt['choices']))
+ for line in zip(self.name_col, self.value_col, self.choices_col, self.descr_col):
+ if self.has_choices:
+ print('{0:{width[0]}} {1:{width[1]}} {2:{width[2]}} {3}'.format(*line, width=col_widths))
else:
- choices_col.append('')
+ print('{0:{width[0]}} {1:{width[1]}} {3}'.format(*line, width=col_widths))
- col_widths = (max([len(i) for i in name_col], default=0),
- max([len(i) for i in value_col], default=0),
- max([len(i) for i in choices_col], default=0),
- max([len(i) for i in descr_col], default=0))
+ def split_options_per_subproject(self, options):
+ result = {}
+ for k, o in options.items():
+ subproject = ''
+ if ':' in k:
+ subproject, optname = k.split(':')
+ if o.yielding and optname in options:
+ self.yielding_options.add(k)
+ self.all_subprojects.add(subproject)
+ result.setdefault(subproject, {})[k] = o
+ return result
- for line in zip(name_col, value_col, choices_col, descr_col):
- if choices_found:
- print(' {0:{width[0]}} {1:{width[1]}} {2:{width[2]}} {3:{width[3]}}'.format(*line, width=col_widths))
+ def _add_line(self, name, value, choices, descr):
+ self.name_col.append(' ' * self.print_margin + name)
+ self.value_col.append(value)
+ self.choices_col.append(choices)
+ self.descr_col.append(descr)
+
+ def add_option(self, name, descr, value, choices):
+ if isinstance(value, list):
+ value = '[{0}]'.format(', '.join(make_lower_case(value)))
+ else:
+ value = make_lower_case(value)
+
+ if choices:
+ self.has_choices = True
+ if isinstance(choices, list):
+ choices_list = make_lower_case(choices)
+ current = '['
+ while choices_list:
+ i = choices_list.pop(0)
+ if len(current) + len(i) >= self.max_choices_line_length:
+ self._add_line(name, value, current + ',', descr)
+ name = ''
+ value = ''
+ descr = ''
+ current = ' '
+ if len(current) > 1:
+ current += ', '
+ current += i
+ choices = current + ']'
else:
- print(' {0:{width[0]}} {1:{width[1]}} {3:{width[3]}}'.format(*line, width=col_widths))
+ choices = make_lower_case(choices)
+ else:
+ choices = ''
+
+ self._add_line(name, value, choices, descr)
+
+ def add_title(self, title):
+ titles = {'descr': 'Description', 'value': 'Current Value', 'choices': 'Possible Values'}
+ if self.default_values_only:
+ titles['value'] = 'Default Value'
+ self._add_line('', '', '', '')
+ self._add_line(title, titles['value'], titles['choices'], titles['descr'])
+ self._add_line('-' * len(title), '-' * len(titles['value']), '-' * len(titles['choices']), '-' * len(titles['descr']))
+
+ def add_section(self, section):
+ self.print_margin = 0
+ self._add_line('', '', '', '')
+ self._add_line(section + ':', '', '', '')
+ self.print_margin = 2
def print_options(self, title, options):
- print('\n{}:'.format(title))
if not options:
- print(' No {}\n'.format(title.lower()))
- arr = []
+ return
+ if title:
+ self.add_title(title)
for k, o in sorted(options.items()):
- d = o.description
- v = o.printable_value()
- c = o.choices
- arr.append({'name': k, 'descr': d, 'value': v, 'choices': c})
- self.print_aligned(arr)
+ printable_value = o.printable_value()
+ if k in self.yielding_options:
+ printable_value = '<inherited from main project>'
+ self.add_option(k, o.description, printable_value, o.choices)
def print_conf(self):
def print_default_values_warning():
@@ -180,26 +205,44 @@ class Conf:
test_options = {k: o for k, o in self.coredata.builtins.items() if k in test_option_names}
core_options = {k: o for k, o in self.coredata.builtins.items() if k in core_option_names}
- self.print_options('Core options', core_options)
- if self.default_values_only or self.build.environment.is_cross_build():
- self.print_options('Core options (for host machine)', self.coredata.builtins_per_machine.host)
- self.print_options(
- 'Core options (for build machine)',
- {'build.' + k: o for k, o in self.coredata.builtins_per_machine.build.items()})
- else:
- self.print_options('Core options', self.coredata.builtins_per_machine.host)
+ def insert_build_prefix(k):
+ idx = k.find(':')
+ if idx < 0:
+ return 'build.' + k
+ return k[:idx + 1] + 'build.' + k[idx + 1:]
+
+ core_options = self.split_options_per_subproject(core_options)
+ host_compiler_options = self.split_options_per_subproject(self.coredata.compiler_options.host)
+ build_compiler_options = self.split_options_per_subproject({insert_build_prefix(k): o for k, o in self.coredata.compiler_options.build.items()})
+ project_options = self.split_options_per_subproject(self.coredata.user_options)
+ show_build_options = self.default_values_only or self.build.environment.is_cross_build()
+
+ self.add_section('Main project options')
+ self.print_options('Core options', core_options[''])
+ self.print_options('', self.coredata.builtins_per_machine.host)
+ if show_build_options:
+ self.print_options('', {insert_build_prefix(k): o for k, o in self.coredata.builtins_per_machine.build.items()})
self.print_options('Backend options', self.coredata.backend_options)
self.print_options('Base options', self.coredata.base_options)
- if self.default_values_only or self.build.environment.is_cross_build():
- self.print_options('Compiler options (for host machine)', self.coredata.compiler_options.host)
- self.print_options(
- 'Compiler options (for build machine)',
- {'build.' + k: o for k, o in self.coredata.compiler_options.build.items()})
- else:
- self.print_options('Compiler options', self.coredata.compiler_options.host)
+ self.print_options('Compiler options', host_compiler_options[''])
+ if show_build_options:
+ self.print_options('', build_compiler_options[''])
self.print_options('Directories', dir_options)
- self.print_options('Project options', self.coredata.user_options)
self.print_options('Testing options', test_options)
+ self.print_options('Project options', project_options[''])
+ for subproject in sorted(self.all_subprojects):
+ if subproject == '':
+ continue
+ self.add_section('Subproject ' + subproject)
+ if subproject in core_options:
+ self.print_options('Core options', core_options[subproject])
+ if subproject in host_compiler_options:
+ self.print_options('Compiler options', host_compiler_options[subproject])
+ if subproject in build_compiler_options and show_build_options:
+ self.print_options('', build_compiler_options[subproject])
+ if subproject in project_options:
+ self.print_options('Project options', project_options[subproject])
+ self.print_aligned()
# Print the warning twice so that the user shouldn't be able to miss it
if self.default_values_only: