[rtems-tools commit] bsp-builder: Support per BSP excludes.

Chris Johns chrisj at rtems.org
Thu Aug 18 23:55:12 UTC 2016


Module:    rtems-tools
Branch:    master
Commit:    51e19af92d92483b12caee2d2dd9299eb5cefe6d
Changeset: http://git.rtems.org/rtems-tools/commit/?id=51e19af92d92483b12caee2d2dd9299eb5cefe6d

Author:    Chris Johns <chrisj at rtems.org>
Date:      Thu Aug 18 21:00:29 2016 +1000

bsp-builder: Support per BSP excludes.

---

 tester/rt/check.py | 137 ++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 114 insertions(+), 23 deletions(-)

diff --git a/tester/rt/check.py b/tester/rt/check.py
index 76e6951..711a084 100755
--- a/tester/rt/check.py
+++ b/tester/rt/check.py
@@ -36,6 +36,11 @@ import operator
 import os
 import sys
 
+try:
+    import configparser
+except:
+    import ConfigParser as configparser
+
 from rtemstoolkit import execute
 from rtemstoolkit import error
 from rtemstoolkit import log
@@ -94,13 +99,45 @@ class warnings_counter:
                         self.warnings[w] += 1
         log.output(text)
 
+class results:
+
+    def __init__(self):
+        self.passes = []
+        self.fails = []
+
+    def add(self, good, arch, bsp, configure, warnings):
+        if good:
+            self.passes += [(arch, bsp, configure, warnings)]
+        else:
+            self.fails += [(arch, bsp, configure, 0)]
+
+    def report(self):
+        log.notice('* Passes: %d   Failures: %d' %
+                   (len(self.passes), len(self.fails)))
+        log.output()
+        log.output('Build Report')
+        log.output('   Passes: %d   Failures: %d' %
+                   (len(self.passes), len(self.fails)))
+        log.output(' Failures:')
+        for f in self.fails:
+            arch_bsp = '%s/%s' % (f[0], f[1])
+            config_cmd = f[2]
+            config_at = config_cmd.find('configure')
+            if config_at != -1:
+                config_cmd = config_cmd[config_at:]
+            log.output(' %20s:  %s' % (arch_bsp, config_cmd))
+        log.output(' Passes:')
+        for f in self.passes:
+            arch_bsp = '%s/%s' % (f[0], f[1])
+            config_cmd = f[2]
+            config_at = config_cmd.find('configure')
+            if config_at != -1:
+                config_cmd = config_cmd[config_at:]
+            log.output(' %20s:  %d  %s' % (arch_bsp, f[3], config_cmd))
+
 class configuration:
 
     def __init__(self):
-        try:
-            import configparser
-        except:
-            import ConfigParser as configparser
         self.config = configparser.ConfigParser()
         self.name = None
         self.archs = { }
@@ -127,6 +164,15 @@ class configuration:
                 raise error.general('config: no %s found in %s' % (label, section))
         return None
 
+    def _get_items(self, section, err = True):
+        try:
+            items = self.config.items(section)
+            return items
+        except:
+            if err:
+                raise error.general('config: section %s not found' % (section))
+        return []
+
     def _comma_list(self, section, label, error = True):
         items = self._get_item(section, label, error)
         if items is None:
@@ -137,7 +183,10 @@ class configuration:
         if not path.exists(name):
             raise error.general('config: cannot read configuration: %s' % (name))
         self.name = name
-        self.config.read(name)
+        try:
+            self.config.read(name)
+        except configparser.ParsingError as ce:
+            raise error.general('config: %s' % (ce))
         archs = []
         self.profiles['profiles'] = self._comma_list('profiles', 'profiles', error = False)
         if len(self.profiles['profiles']) == 0:
@@ -153,12 +202,19 @@ class configuration:
             self.profiles[profile['name']] = profile
         for a in set(archs):
             arch = {}
-            arch['excludes'] = self._comma_list(a, 'excludes', error = False)
+            arch['excludes'] = {}
+            for exclude in self._comma_list(a, 'exclude', error = False):
+                arch['excludes'][exclude] = ['all']
+            for i in self._get_items(a, False):
+                if i[0].startswith('exclude_'):
+                    exclude = i[0][len('exclude_'):]
+                    if exclude not in arch['excludes']:
+                        arch['excludes'][exclude] = []
+                    arch['excludes'][exclude] += sorted(set([b.strip() for b in i[1].split(',')]))
             arch['bsps'] = self._comma_list(a, 'bsps', error = False)
             for b in arch['bsps']:
                 arch[b] = {}
                 arch[b]['bspopts'] = self._comma_list(a, 'bspopts_%s' % (b), error = False)
-                arch[b]['config'] = self._comma_list(a, 'config_%s' % (b), error = False)
             self.archs[a] = arch
         builds = {}
         builds['default'] = self._get_item('builds', 'default').split()
@@ -172,7 +228,11 @@ class configuration:
         return self.builds['variations']
 
     def excludes(self, arch):
-        return self.archs[arch]['excludes']
+        excludes = self.archs[arch]['excludes'].keys()
+        for exclude in self.archs[arch]['excludes']:
+            if 'all' not in self.archs[arch]['excludes'][exclude]:
+                excludes.remove(exclude)
+        return sorted(excludes)
 
     def archs(self):
         return sorted(self.archs.keys())
@@ -186,6 +246,13 @@ class configuration:
     def bsp_present(self, arch, bsp):
         return bsp in self.archs[arch]['bsps']
 
+    def bsp_excludes(self, arch, bsp):
+        excludes = self.archs[arch]['excludes'].keys()
+        for exclude in self.archs[arch]['excludes']:
+            if bsp not in self.archs[arch]['excludes'][exclude]:
+                excludes.remove(exclude)
+        return sorted(excludes)
+
     def bspopts(self, arch, bsp):
         return self.archs[arch][bsp]['bspopts']
 
@@ -194,7 +261,7 @@ class configuration:
 
     def variant_options(self, variant):
         if variant in self.builds['var_options']:
-            self.builds['var_options'][variant]
+            return self.builds['var_options'][variant]
         return []
 
     def profile_present(self, profile):
@@ -224,6 +291,7 @@ class build:
                         'objs'     : 0,
                         'libs'     : 0 }
         self.warnings = warnings_counter(rtems)
+        self.results = results()
         if not path.exists(path.join(rtems, 'configure')) or \
            not path.exists(path.join(rtems, 'Makefile.in')) or \
            not path.exists(path.join(rtems, 'cpukit')):
@@ -243,10 +311,20 @@ class build:
         return self.config.arch_bsps(arch)
 
     def _variations(self, arch, bsp):
+        def _match(var, vars):
+            matches = []
+            for v in vars:
+                if var in v.split('-'):
+                    matches += [v]
+            return matches
+
         vars = self.config.variations()
         for v in self.config.excludes(arch):
-            if v in vars:
-                vars.remove(v)
+            for m in _match(v, vars):
+                vars.remove(m)
+        for v in self.config.bsp_excludes(arch, bsp):
+            for m in _match(v, vars):
+                vars.remove(m)
         return vars
 
     def _arch_bsp_dir_make(self, arch, bsp):
@@ -319,9 +397,11 @@ class build:
             log.output('- ' * 35)
             log.notice('. Configuring: %s' % (bs))
             try:
+                result = '+ Pass'
                 bpath = self._build_dir(arch, bsp, bs)
                 path.mkdir(bpath)
-                cmd = self._config_command(build_set[bs], arch, bsp)
+                config_cmd = self._config_command(build_set[bs], arch, bsp)
+                cmd = config_cmd
                 e = execute.capture_execution(log = warnings)
                 log.output('run: ' + cmd)
                 if self.options['dry-run']:
@@ -329,6 +409,7 @@ class build:
                 else:
                     exit_code, proc, output = e.shell(cmd, cwd = path.host(bpath))
                 if exit_code != 0:
+                    result = '- FAIL'
                     self.errors['configure'] += 1
                     log.notice('- Configure failed: %s' % (bs))
                     log.output('cmd failed: %s' % (cmd))
@@ -345,16 +426,18 @@ class build:
                     else:
                         exit_code, proc, output = e.shell(cmd, cwd = path.host(bpath))
                     if exit_code != 0:
+                        result = '- FAIL'
                         self.errors['build'] += 1
                         log.notice('- FAIL: %s: %s' % (bs, self._error_str()))
                         log.output('cmd failed: %s' % (cmd))
                         if self.options['stop-on-error']:
                             raise error.general('Building %s failed' % (bs))
                     files = self._count_files(arch, bsp, bs)
-                    log.notice('+ Pass: %s: warnings:%d  exes:%d  objs:%s  libs:%d' % \
-                               (bs, warnings.get(),
-                                files['exes'], files['objs'], files['libs']))
-                    log.notice('  %s' % (self._error_str()))
+                log.notice('%s: %s: warnings:%d  exes:%d  objs:%s  libs:%d' % \
+                           (result, bs, warnings.get(),
+                            files['exes'], files['objs'], files['libs']))
+                log.notice('  %s' % (self._error_str()))
+                self.results.add(result[0] == '+', arch, bsp, config_cmd, warnings.get())
             finally:
                 end = datetime.datetime.now()
                 if not self.options['no-clean']:
@@ -413,6 +496,8 @@ class build:
         log.output(self.warnings.report())
 
 def run_args(args):
+    b = None
+    ec = 0
     try:
         #
         # On Windows MSYS2 prepends a path to itself to the environment
@@ -426,12 +511,13 @@ def run_args(args):
                 os.environ['PATH'] = os.pathsep.join(cspath[1:])
 
         top = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))
-        profile = 'tier-1'
         prefix = '/opt/rtems/%s' % (rtems_version())
         tools = prefix
         build_dir = 'bsp-builds'
         logf = 'bsp-build-%s.txt' % (datetime.datetime.now().strftime('%Y%m%d-%H%M%S'))
         config_file = path.join(top, 'share', 'rtems', 'tester', 'rtems', 'rtems-bsps.ini')
+        if not path.exists(config_file):
+            config_file = path.join(top, 'tester', 'rtems', 'rtems-bsps.ini')
 
         argsp = argparse.ArgumentParser()
         argsp.add_argument('--prefix', help = 'Prefix to build the BSP.', type = str)
@@ -441,6 +527,7 @@ def run_args(args):
         argsp.add_argument('--log', help = 'Log file.', type = str)
         argsp.add_argument('--stop-on-error', help = 'Stop on an error.', action = 'store_true')
         argsp.add_argument('--no-clean', help = 'Do not clean the build output.', action = 'store_true')
+        argsp.add_argument('--profiles', help = 'Build the listed profiles.', type = str, default = 'tier-1')
         argsp.add_argument('--arch', help = 'Build the specific architecture.', type = str)
         argsp.add_argument('--bsp', help = 'Build the specific BSP.', type = str)
         argsp.add_argument('--dry-run', help = 'Do not run the actual builds.', action = 'store_true')
@@ -449,7 +536,7 @@ def run_args(args):
         if opts.log is not None:
             logf = opts.log
         log.default = log.log([logf])
-        log.notice('RTEMS Tools Project - RTEMS Kernel Check, %s' % (version.str()))
+        log.notice('RTEMS Tools Project - RTEMS Kernel BSP Builder, %s' % (version.str()))
         if opts.rtems is None:
             raise error.general('No RTEMS source provided on the command line')
         if opts.prefix is not None:
@@ -476,22 +563,26 @@ def run_args(args):
             else:
                 b.build_arch(opts.arch)
         else:
-            b.build_profile(profile)
+            for profile in opts.profiles.split(','):
+                b.build_profile(profile.strip())
+        b.results.report()
 
     except error.general as gerr:
         print(gerr)
         print('BSP Build FAILED', file = sys.stderr)
-        sys.exit(1)
+        ec = 1
     except error.internal as ierr:
         print(ierr)
         print('BSP Build FAILED', file = sys.stderr)
-        sys.exit(1)
+        ec = 1
     except error.exit as eerr:
         pass
     except KeyboardInterrupt:
         log.notice('abort: user terminated')
-        sys.exit(1)
-    sys.exit(0)
+        ec = 1
+    if b is not None:
+        b.results.report()
+    sys.exit(ec)
 
 def run():
     run_args(sys.argv)



More information about the vc mailing list