From: Chris Johns <chr...@rtems.org> Updates #4716 --- source-builder/sb/build.py | 18 +++- source-builder/sb/config.py | 161 ++++++++++++++++++-------------- source-builder/sb/setbuilder.py | 39 ++++++-- 3 files changed, 133 insertions(+), 85 deletions(-)
diff --git a/source-builder/sb/build.py b/source-builder/sb/build.py index ceb179a..c1b76a3 100644 --- a/source-builder/sb/build.py +++ b/source-builder/sb/build.py @@ -48,8 +48,7 @@ except KeyboardInterrupt: print('abort: user terminated') sys.exit(1) except: - print('error: unknown application load error') - sys.exit(1) + raise def humanize_number(num, suffix): for unit in ['','K','M','G','T','P','E','Z']: @@ -635,6 +634,10 @@ class build: return 0 return package.get_size('installed') + def includes(self): + if self.config: + return self.config.includes() + def get_configs(opts): def _scan(_path, ext): @@ -648,10 +651,17 @@ def get_configs(opts): return configs configs = { 'paths': [], 'files': [] } - for cp in opts.defaults.expand('%{_configdir}').split(':'): + paths = opts.defaults.expand('%{_configdir}').split(':') + root = path.host(os.path.commonprefix(paths)) + configs['root'] = root + configs['localpaths'] = [lp[len(root):] for lp in paths] + for cp in paths: hcp = path.host(path.abspath(cp)) configs['paths'] += [hcp] - configs['files'] += _scan(hcp, ['.cfg', '.bset']) + hpconfigs = sorted(set(_scan(hcp, ['.cfg', '.bset']))) + hcplocal = hcp[len(root):] + configs[hcplocal] = [path.join(hcplocal, c) for c in hpconfigs] + configs['files'] += hpconfigs configs['files'] = sorted(set(configs['files'])) return configs diff --git a/source-builder/sb/config.py b/source-builder/sb/config.py index a40147d..df2aa31 100644 --- a/source-builder/sb/config.py +++ b/source-builder/sb/config.py @@ -45,8 +45,7 @@ except KeyboardInterrupt: print('user terminated', file = sys.stderr) sys.exit(1) except: - print('error: unknown application load error', file = sys.stderr) - sys.exit(1) + raise def _check_bool(value): istrue = None @@ -69,6 +68,13 @@ def _check_nil(value): istrue = False return istrue +def _check_number(value): + try: + float(value) + return True + except ValueError: + return False + class package: def __init__(self, name, arch, config): @@ -283,6 +289,7 @@ class file: return s def _reset(self, name): + self.parent = 'root' self.name = name self.load_depth = 0 self.configpath = [] @@ -430,7 +437,8 @@ class file: if len(shell_macro) > 3: e = execute.capture_execution() if options.host_windows: - shell_cmd = ''.join([c if c != '"' else '\\' + c for c in shell_macro[2:-1]]) + shell_cmd = \ + ''.join([c if c != '"' else '\\' + c for c in shell_macro[2:-1]]) cmd = '%s -c "%s"' % (self.macros.expand('%{__sh}'), shell_cmd) else: cmd = shell_macro[2:-1] @@ -458,7 +466,8 @@ class file: if braces > 0: braces -= 1 else: - shell_cmd = '%(' + self._shell(line[pos + 2:p], nesting + 1) + ')' + shell_cmd = '%(' + \ + self._shell(line[pos + 2:p], nesting + 1) + ')' line = line[:pos] + _exec(shell_cmd) + line[p + 1:] updating = True break @@ -472,9 +481,10 @@ class file: ('with_download' in self.macros and self.macros['with_download'] == '1'): return '0' ok = False - log.trace('pkgconfig: check: crossc=%d pkg_crossc=%d prefix=%s' % ( self._cross_compile(), - self.pkgconfig_crosscompile, - self.pkgconfig_prefix)) + log.trace('pkgconfig: check: crossc=%d pkg_crossc=%d prefix=%s' + % ( self._cross_compile(), + self.pkgconfig_crosscompile, + self.pkgconfig_prefix)) log.trace('pkgconfig: check: test=%s' % (test)) if type(test) == str: test = test.split() @@ -496,6 +506,7 @@ class file: except pkgconfig.error as pe: self._error('pkgconfig: check: %s' % (pe)) except: + raise raise error.internal('pkgconfig failure') if ok: return '1' @@ -520,6 +531,7 @@ class file: except pkgconfig.error as pe: self._error('pkgconfig: %s: %s' % (flags, pe)) except: + raise raise error.internal('pkgconfig failure') if pkg_flags is None: pkg_flags = '' @@ -594,7 +606,8 @@ class file: elif m.startswith('%{expand'): colon = m.find(':') if colon < 8: - log.warning(self._name_line_msg('malformed expand macro, no colon found')) + log.warning(self._name_line_msg('malformed expand macro, ' \ + 'no colon found')) else: e = self._expand(m[colon + 1:-1].strip()) s = s.replace(m, self._label(e)) @@ -861,7 +874,8 @@ class file: dir, info, data = self._process_directive(r, dir, info, data) else: if in_dir != dir: - self._error('directives cannot change scope across if statements') + self._error('directives cannot change' \ + ' scope across if statements') return data if r[1] == '%else': @@ -904,34 +918,42 @@ class file: elif cls[0] == '&&': join_op = 'and' cls = cls[1:] - log.trace('config: %s: %3d: _if[%i]: joining: %s' % (self.name, self.lc, - self.if_depth, - join_op)) + log.trace('config: %s: %3d: _if[%i]: joining: %s' % \ + (self.name, self.lc, + self.if_depth, + join_op)) + # If OR and the previous check was true short circuit the evaluation + if join_op == 'or' and cistrue: + log.trace('config: %s: %3d: _if[%i]: OR true, short circuit eval' % \ + (self.name, self.lc, + self.if_depth)) + break ori = 0 andi = 0 i = len(cls) if '||' in cls: ori = cls.index('||') - log.trace('config: %s: %3d: _if[%i}: OR found at %i' % (self.name, self.lc, - self.if_depth, - ori)) + log.trace('config: %s: %3d: _if[%i}: OR found at %i' % \ + (self.name, self.lc, + self.if_depth, + ori)) if '&&' in cls: andi = cls.index('&&') - log.trace('config: %s: %3d: _if[%i]: AND found at %i' % (self.name, self.lc, - self.if_depth, - andi)) + log.trace('config: %s: %3d: _if[%i]: AND found at %i' % \ + (self.name, self.lc, + self.if_depth, + andi)) if ori > 0 or andi > 0: if ori == 0: i = andi elif andi == 0: i = ori - elif ori < andi: - i = andi else: - i = andi - log.trace('config: %s: %3d: _if[%i]: next OP found at %i' % (self.name, self.lc, - self.if_depth, - i)) + i = min(ori, andi) + log.trace('config: %s: %3d: _if[%i]: next OP found at %i' % \ + (self.name, self.lc, + self.if_depth, + i)) ls = cls[:i] if len(ls) == 0: self._error('invalid if expression: ' + reduce(add, sls, '')) @@ -985,37 +1007,27 @@ class file: ifls = (' '.join(ifls[:op_pos]), op, ' '.join(ifls[op_pos + 1:])) break if len(ifls) != 3: - self._error('malformed if: ' + reduce(add, ls, '')) - if ifls[1] == '==': - if ifls[0] == ifls[2]: - istrue = True - else: - istrue = False - elif ifls[1] == '!=' or ifls[1] == '=!': - if ifls[0] != ifls[2]: - istrue = True - else: - istrue = False - elif ifls[1] == '>': - if ifls[0] > ifls[2]: - istrue = True - else: - istrue = False - elif ifls[1] == '>=' or ifls[1] == '=>': - if ifls[0] >= ifls[2]: - istrue = True - else: - istrue = False - elif ifls[1] == '<=' or ifls[1] == '=<': - if ifls[0] <= ifls[2]: - istrue = True - else: - istrue = False - elif ifls[1] == '<': - if ifls[0] < ifls[2]: - istrue = True - else: - istrue = False + self._error('malformed if: ' + reduce(add, ls, '')) + lhs = ifls[0] + operator = ifls[1] + rhs = ifls[2] + if _check_number(lhs) and _check_number(rhs): + log.trace('config: %s: %3d: _if: numeric value check' % \ + (self.name, self.lc)) + lhs = float(lhs) + rhs = float(rhs) + if operator == '==': + istrue = lhs == rhs + elif operator == '!=' or operator == '=!': + istrue = lhs != rhs + elif operator == '>': + istrue = lhs > rhs + elif operator == '>=' or operator == '=>': + istrue = lhs >= rhs + elif operator == '<=' or operator == '=<': + istrue = lhs <= rhs + elif operator == '<': + istrue = lhs < rhs else: self._error('invalid %if operator: ' + reduce(add, ls, '')) @@ -1226,7 +1238,8 @@ class file: log.trace('config: %s: %3d: _parse: directive: %s' % \ (self.name, self.lc, ls[0].strip())) return ('directive', ls[0].strip(), ls[1:]) - log.warning(self._name_line_msg("unknown directive: '" + ls[0] + "'")) + log.warning(self._name_line_msg("unknown directive: '" + \ + ls[0] + "'")) return ('data', [lo]) else: return ('data', [lo]) @@ -1247,7 +1260,8 @@ class file: _package = results[2][0] else: if results[2][0].strip() != '-n': - log.warning(self._name_line_msg("unknown directive option: '%s'" % (' '.join(results[2])))) + log.warning(self._name_line_msg("unknown directive option: '%s'" % \ + (' '.join(results[2])))) _package = results[2][1].strip() self._set_package(_package) if directive and directive != results[1]: @@ -1257,7 +1271,8 @@ class file: return (directive, info, data) def _process_data(self, results, directive, info, data): - log.trace('config: %s: %3d: _process_data: result=#%r# directive=#%s# info=#%r# data=#%r#' % \ + log.trace('config: %s: %3d: _process_data: result=#%r# ' \ + 'directive=#%s# info=#%r# data=#%r#' % \ (self.name, self.lc, results, directive, info, data)) new_data = [] for l in results[1]: @@ -1284,10 +1299,12 @@ class file: if info is not None: self._info_append(info, info_data) else: - log.warning(self._name_line_msg("invalid format: '%s'" % (info_data[:-1]))) + log.warning(self._name_line_msg("invalid format: '%s'" % \ + (info_data[:-1]))) else: l = self._expand(l) - log.trace('config: %s: %3d: _data: %s %s' % (self.name, self.lc, l, new_data)) + log.trace('config: %s: %3d: _data: %s %s' % \ + (self.name, self.lc, l, new_data)) new_data.append(l) return (directive, info, data + new_data) @@ -1303,7 +1320,8 @@ class file: self.package = _package def _directive_extend(self, dir, data): - log.trace('config: %s: %3d: _directive_extend: %s: %r' % (self.name, self.lc, dir, data)) + log.trace('config: %s: %3d: _directive_extend: %s: %r' % \ + (self.name, self.lc, dir, data)) self._packages[self.package].directive_extend(dir, data) def _info_append(self, info, data): @@ -1328,7 +1346,6 @@ class file: return end if self.load_depth == 0: - self._reset(name) self._packages[self.package] = package(self.package, self.define('%{_arch}'), self) @@ -1336,6 +1353,7 @@ class file: self.load_depth += 1 save_name = self.name + save_parent = self.parent save_lc = self.lc # @@ -1382,7 +1400,9 @@ class file: raise error.general('error opening config file: %s' % (path.host(configname))) self.configpath += [configname] - self._includes += [configname] + + self._includes += [configname + ':' + self.parent] + self.parent = configname self.name = self._relative_path(configname) self.lc = 0 @@ -1413,13 +1433,12 @@ class file: except: config.close() raise - - config.close() - - self.name = save_name - self.lc = save_lc - - self.load_depth -= 1 + finally: + config.close() + self.name = save_name + self.parent = save_parent + self.lc = save_lc + self.load_depth -= 1 def defined(self, name): return name in self.macros @@ -1456,7 +1475,7 @@ class file: raise error.general('package "' + _package + '" not found') if name not in self._packages[_package].directives: raise error.general('directive "' + name + \ - '" not found in package "' + _package + '"') + '" not found in package "' + _package + '"') return self._packages[_package].directives[name] def abspath(self, rpath): diff --git a/source-builder/sb/setbuilder.py b/source-builder/sb/setbuilder.py index be5a4c4..16e8cc8 100644 --- a/source-builder/sb/setbuilder.py +++ b/source-builder/sb/setbuilder.py @@ -48,8 +48,7 @@ except KeyboardInterrupt: print('abort: user terminated', file = sys.stderr) sys.exit(1) except: - print('error: unknown application load error', file = sys.stderr) - sys.exit(1) + raise def macro_expand(macros, _str): cstr = None @@ -285,6 +284,7 @@ class buildset: line = line[1:b] return line.strip() + bset = macro_expand(self.macros, bset) bsetname = bset if not path.exists(bsetname): @@ -316,15 +316,22 @@ class buildset: if ls[0][-1] == ':' and ls[0][:-1] == 'package': self.bset_pkg = ls[1].strip() self.macros['package'] = self.bset_pkg - elif ls[0][0] == '%': + elif ls[0][0] == '%' and (len(ls[0]) > 1 and ls[0][1] != '{'): def err(msg): raise error.general('%s:%d: %s' % (self.bset, lc, msg)) - if ls[0] == '%define': + if ls[0] == '%define' or ls[0] == '%defineifnot' : + name = ls[1].strip() + value = None if len(ls) > 2: - self.macros.define(ls[1].strip(), - ' '.join([f.strip() for f in ls[2:]])) - else: - self.macros.define(ls[1].strip()) + value = ' '.join([f.strip() for f in ls[2:]]) + if ls[0] == '%defineifnot': + if self.macros.defined(name): + name = None + if name is not None: + if value is not None: + self.macros.define(name, value) + else: + self.macros.define(name) elif ls[0] == '%undefine': if len(ls) > 2: raise error.general('%s:%d: %undefine requires ' \ @@ -337,7 +344,7 @@ class buildset: elif ls[0] == '%hash': sources.hash(ls[1:], self.macros, err) else: - l = l.strip() + l = macro_expand(self.macros, l.strip()) c = build.find_config(l, self.configs) if c is None: raise error.general('%s:%d: cannot find file: %s' % (self.bset, @@ -674,6 +681,16 @@ def list_bset_cfg_files(opts, configs): return True return False +def list_host(opts): + if opts.get_arg('--list-host'): + print('Host operating system information:') + print('Operating system: %s' % macro_expand(opts.defaults, '%{_os}')) + print('Number of processors: %s' % macro_expand(opts.defaults, '%{_ncpus}')) + print('Build architecture: %s' % macro_expand(opts.defaults, '%{_host_arch}')) + print('Host triplet: %s' % macro_expand(opts.defaults, '%{_host}')) + return True + return False + def run(): import sys ec = 0 @@ -684,6 +701,7 @@ def run(): '--list-bsets': 'List available build sets', '--list-configs': 'List available configuration files.', '--list-deps': 'List the dependent files.', + '--list-host': 'List host information and the host triplet.', '--bset-tar-file': 'Create a build set tar file', '--pkg-tar-files': 'Create package tar files', '--no-report': 'Do not create a package report.', @@ -721,7 +739,8 @@ def run(): deps = [] else: deps = None - if not list_bset_cfg_files(opts, configs): + + if not list_bset_cfg_files(opts, configs) and not list_host(opts): prefix = macro_expand(opts.defaults, '%{_prefix}') if opts.canadian_cross(): opts.disable_install() -- 2.24.1 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel