aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/mconf.py
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 /mesonbuild/mconf.py
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.
Diffstat (limited to 'mesonbuild/mconf.py')
-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: