[RSB 5 2/3] sb: Back port fixes from the development branch

chrisj at rtems.org chrisj at rtems.org
Thu Sep 8 07:46:26 UTC 2022


From: Chris Johns <chrisj at 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



More information about the devel mailing list