|
|
|
@ -963,10 +963,14 @@ class Test(InterpreterObject): |
|
|
|
|
|
|
|
|
|
class SubprojectHolder(InterpreterObject, ObjectHolder): |
|
|
|
|
|
|
|
|
|
def __init__(self, subinterpreter, subproject_dir, name): |
|
|
|
|
def __init__(self, subinterpreter, subproject_dir, name, warnings=0, disabled_feature=None, |
|
|
|
|
exception=None): |
|
|
|
|
InterpreterObject.__init__(self) |
|
|
|
|
ObjectHolder.__init__(self, subinterpreter) |
|
|
|
|
self.name = name |
|
|
|
|
self.warnings = warnings |
|
|
|
|
self.disabled_feature = disabled_feature |
|
|
|
|
self.exception = exception |
|
|
|
|
self.subproject_dir = subproject_dir |
|
|
|
|
self.methods.update({'get_variable': self.get_variable_method, |
|
|
|
|
'found': self.found_method, |
|
|
|
@ -1791,6 +1795,9 @@ class Summary: |
|
|
|
|
bool_yn = kwargs.get('bool_yn', False) |
|
|
|
|
if not isinstance(bool_yn, bool): |
|
|
|
|
raise InterpreterException('bool_yn keyword argument must be boolean') |
|
|
|
|
list_sep = kwargs.get('list_sep') |
|
|
|
|
if list_sep is not None and not isinstance(list_sep, str): |
|
|
|
|
raise InterpreterException('list_sep keyword argument must be string') |
|
|
|
|
for k, v in values.items(): |
|
|
|
|
if k in self.sections[section]: |
|
|
|
|
raise InterpreterException('Summary section {!r} already have key {!r}'.format(section, k)) |
|
|
|
@ -1803,9 +1810,7 @@ class Summary: |
|
|
|
|
formatted_values.append(mlog.green('YES') if i else mlog.red('NO')) |
|
|
|
|
else: |
|
|
|
|
formatted_values.append(i) |
|
|
|
|
if not formatted_values: |
|
|
|
|
formatted_values = [''] |
|
|
|
|
self.sections[section][k] = formatted_values |
|
|
|
|
self.sections[section][k] = (formatted_values, list_sep) |
|
|
|
|
self.max_key_len = max(self.max_key_len, len(k)) |
|
|
|
|
|
|
|
|
|
def dump(self): |
|
|
|
@ -1815,11 +1820,14 @@ class Summary: |
|
|
|
|
if section: |
|
|
|
|
mlog.log(' ', mlog.bold(section)) |
|
|
|
|
for k, v in values.items(): |
|
|
|
|
v, list_sep = v |
|
|
|
|
indent = self.max_key_len - len(k) + 3 |
|
|
|
|
mlog.log(' ' * indent, k + ':', v[0]) |
|
|
|
|
indent = self.max_key_len + 5 |
|
|
|
|
for i in v[1:]: |
|
|
|
|
mlog.log(' ' * indent, i) |
|
|
|
|
end = ' ' if v else '' |
|
|
|
|
mlog.log(' ' * indent, k + ':', end=end) |
|
|
|
|
if list_sep is None: |
|
|
|
|
indent = self.max_key_len + 6 |
|
|
|
|
list_sep = '\n' + ' ' * indent |
|
|
|
|
mlog.log(*v, sep=list_sep) |
|
|
|
|
mlog.log('') # newline |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -2598,10 +2606,9 @@ external dependencies (including libraries) must go to "dependencies".''') |
|
|
|
|
dirname = args[0] |
|
|
|
|
return self.do_subproject(dirname, 'meson', kwargs) |
|
|
|
|
|
|
|
|
|
def disabled_subproject(self, dirname, feature=None): |
|
|
|
|
sub = SubprojectHolder(None, self.subproject_dir, dirname) |
|
|
|
|
if feature: |
|
|
|
|
sub.disabled_feature = feature |
|
|
|
|
def disabled_subproject(self, dirname, disabled_feature=None, exception=None): |
|
|
|
|
sub = SubprojectHolder(None, self.subproject_dir, dirname, |
|
|
|
|
disabled_feature=disabled_feature, exception=exception) |
|
|
|
|
self.subprojects[dirname] = sub |
|
|
|
|
return sub |
|
|
|
|
|
|
|
|
@ -2609,7 +2616,7 @@ external dependencies (including libraries) must go to "dependencies".''') |
|
|
|
|
disabled, required, feature = extract_required_kwarg(kwargs, self.subproject) |
|
|
|
|
if disabled: |
|
|
|
|
mlog.log('Subproject', mlog.bold(dirname), ':', 'skipped: feature', mlog.bold(feature), 'disabled') |
|
|
|
|
return self.disabled_subproject(dirname, feature) |
|
|
|
|
return self.disabled_subproject(dirname, disabled_feature=feature) |
|
|
|
|
|
|
|
|
|
default_options = mesonlib.stringlistify(kwargs.get('default_options', [])) |
|
|
|
|
default_options = coredata.create_options_dict(default_options) |
|
|
|
@ -2650,7 +2657,7 @@ external dependencies (including libraries) must go to "dependencies".''') |
|
|
|
|
if not required: |
|
|
|
|
mlog.log(e) |
|
|
|
|
mlog.log('Subproject ', mlog.bold(subprojdir), 'is buildable:', mlog.red('NO'), '(disabling)') |
|
|
|
|
return self.disabled_subproject(dirname) |
|
|
|
|
return self.disabled_subproject(dirname, exception=e) |
|
|
|
|
raise e |
|
|
|
|
|
|
|
|
|
subdir = os.path.join(self.subproject_dir, resolved) |
|
|
|
@ -2678,7 +2685,7 @@ external dependencies (including libraries) must go to "dependencies".''') |
|
|
|
|
# fatal and VS CI treat any logs with "ERROR:" as fatal. |
|
|
|
|
mlog.exception(e, prefix=mlog.yellow('Exception:')) |
|
|
|
|
mlog.log('\nSubproject', mlog.bold(dirname), 'is buildable:', mlog.red('NO'), '(disabling)') |
|
|
|
|
return self.disabled_subproject(dirname) |
|
|
|
|
return self.disabled_subproject(dirname, exception=e) |
|
|
|
|
raise e |
|
|
|
|
|
|
|
|
|
def _do_subproject_meson(self, dirname, subdir, default_options, kwargs, ast=None, build_def_files=None): |
|
|
|
@ -2690,7 +2697,12 @@ external dependencies (including libraries) must go to "dependencies".''') |
|
|
|
|
|
|
|
|
|
subi.subproject_stack = self.subproject_stack + [dirname] |
|
|
|
|
current_active = self.active_projectname |
|
|
|
|
current_warnings_counter = mlog.log_warnings_counter |
|
|
|
|
mlog.log_warnings_counter = 0 |
|
|
|
|
subi.run() |
|
|
|
|
subi_warnings = mlog.log_warnings_counter |
|
|
|
|
mlog.log_warnings_counter = current_warnings_counter |
|
|
|
|
|
|
|
|
|
mlog.log('Subproject', mlog.bold(dirname), 'finished.') |
|
|
|
|
|
|
|
|
|
mlog.log() |
|
|
|
@ -2702,7 +2714,8 @@ external dependencies (including libraries) must go to "dependencies".''') |
|
|
|
|
raise InterpreterException('Subproject %s version is %s but %s required.' % (dirname, pv, wanted)) |
|
|
|
|
self.active_projectname = current_active |
|
|
|
|
self.subprojects.update(subi.subprojects) |
|
|
|
|
self.subprojects[dirname] = SubprojectHolder(subi, self.subproject_dir, dirname) |
|
|
|
|
self.subprojects[dirname] = SubprojectHolder(subi, self.subproject_dir, dirname, |
|
|
|
|
warnings=subi_warnings) |
|
|
|
|
# Duplicates are possible when subproject uses files from project root |
|
|
|
|
if build_def_files: |
|
|
|
|
self.build_def_files = list(set(self.build_def_files + build_def_files)) |
|
|
|
@ -2949,7 +2962,8 @@ external dependencies (including libraries) must go to "dependencies".''') |
|
|
|
|
mlog.log(mlog.bold('Message:'), *args) |
|
|
|
|
|
|
|
|
|
@noArgsFlattening |
|
|
|
|
@permittedKwargs({'section', 'bool_yn'}) |
|
|
|
|
@FeatureNewKwargs('summary', '0.54.0', ['list_sep']) |
|
|
|
|
@permittedKwargs({'section', 'bool_yn', 'list_sep'}) |
|
|
|
|
@FeatureNew('summary', '0.53.0') |
|
|
|
|
def func_summary(self, node, args, kwargs): |
|
|
|
|
if len(args) == 1: |
|
|
|
@ -2977,11 +2991,18 @@ external dependencies (including libraries) must go to "dependencies".''') |
|
|
|
|
all_subprojects = collections.OrderedDict() |
|
|
|
|
for name, subp in sorted(self.subprojects.items()): |
|
|
|
|
value = subp.found() |
|
|
|
|
if not value and hasattr(subp, 'disabled_feature'): |
|
|
|
|
value = 'Feature {!r} disabled'.format(subp.disabled_feature) |
|
|
|
|
if subp.disabled_feature: |
|
|
|
|
value = [value, 'Feature {!r} disabled'.format(subp.disabled_feature)] |
|
|
|
|
elif subp.exception: |
|
|
|
|
value = [value, str(subp.exception)] |
|
|
|
|
elif subp.warnings > 0: |
|
|
|
|
value = [value, '{} warnings'.format(subp.warnings)] |
|
|
|
|
all_subprojects[name] = value |
|
|
|
|
if all_subprojects: |
|
|
|
|
self.summary_impl('Subprojects', all_subprojects, {'bool_yn': True}) |
|
|
|
|
self.summary_impl('Subprojects', all_subprojects, |
|
|
|
|
{'bool_yn': True, |
|
|
|
|
'list_sep': ' ', |
|
|
|
|
}) |
|
|
|
|
# Print all summaries, main project last. |
|
|
|
|
mlog.log('') # newline |
|
|
|
|
main_summary = self.summary.pop('', None) |
|
|
|
|