From: Chris Johns <chr...@rtems.org> Closes #3536 --- {tester/rtems => config}/rtems-bsps-arm.ini | 0 {tester/rtems => config}/rtems-bsps-bfin.ini | 0 {tester/rtems => config}/rtems-bsps-epiphany.ini | 0 {tester/rtems => config}/rtems-bsps-i386.ini | 0 {tester/rtems => config}/rtems-bsps-lm32.ini | 0 {tester/rtems => config}/rtems-bsps-m32c.ini | 0 {tester/rtems => config}/rtems-bsps-m68k.ini | 0 {tester/rtems => config}/rtems-bsps-mips.ini | 0 {tester/rtems => config}/rtems-bsps-moxie.ini | 0 {tester/rtems => config}/rtems-bsps-nios2.ini | 0 {tester/rtems => config}/rtems-bsps-or1k.ini | 0 {tester/rtems => config}/rtems-bsps-powerpc.ini | 0 {tester/rtems => config}/rtems-bsps-riscv.ini | 0 {tester/rtems => config}/rtems-bsps-riscv32.ini | 0 {tester/rtems => config}/rtems-bsps-riscv64.ini | 0 {tester/rtems => config}/rtems-bsps-sh.ini | 0 {tester/rtems => config}/rtems-bsps-sparc.ini | 0 {tester/rtems => config}/rtems-bsps-sparc64.ini | 0 {tester/rtems => config}/rtems-bsps-tiers.ini | 0 {tester/rtems => config}/rtems-bsps-v850.ini | 0 {tester/rtems => config}/rtems-bsps.ini | 0 config/wscript | 44 +++ rtemstoolkit/__init__.py | 12 +- rtemstoolkit/rtems.py | 372 +++++++++++++++++++++++ rtemstoolkit/wscript | 1 + tester/rt/check.py | 341 +-------------------- wscript | 1 + 27 files changed, 434 insertions(+), 337 deletions(-) rename {tester/rtems => config}/rtems-bsps-arm.ini (100%) rename {tester/rtems => config}/rtems-bsps-bfin.ini (100%) rename {tester/rtems => config}/rtems-bsps-epiphany.ini (100%) rename {tester/rtems => config}/rtems-bsps-i386.ini (100%) rename {tester/rtems => config}/rtems-bsps-lm32.ini (100%) rename {tester/rtems => config}/rtems-bsps-m32c.ini (100%) rename {tester/rtems => config}/rtems-bsps-m68k.ini (100%) rename {tester/rtems => config}/rtems-bsps-mips.ini (100%) rename {tester/rtems => config}/rtems-bsps-moxie.ini (100%) rename {tester/rtems => config}/rtems-bsps-nios2.ini (100%) rename {tester/rtems => config}/rtems-bsps-or1k.ini (100%) rename {tester/rtems => config}/rtems-bsps-powerpc.ini (100%) rename {tester/rtems => config}/rtems-bsps-riscv.ini (100%) rename {tester/rtems => config}/rtems-bsps-riscv32.ini (100%) rename {tester/rtems => config}/rtems-bsps-riscv64.ini (100%) rename {tester/rtems => config}/rtems-bsps-sh.ini (100%) rename {tester/rtems => config}/rtems-bsps-sparc.ini (100%) rename {tester/rtems => config}/rtems-bsps-sparc64.ini (100%) rename {tester/rtems => config}/rtems-bsps-tiers.ini (100%) rename {tester/rtems => config}/rtems-bsps-v850.ini (100%) rename {tester/rtems => config}/rtems-bsps.ini (100%) create mode 100644 config/wscript create mode 100755 rtemstoolkit/rtems.py
diff --git a/tester/rtems/rtems-bsps-arm.ini b/config/rtems-bsps-arm.ini similarity index 100% rename from tester/rtems/rtems-bsps-arm.ini rename to config/rtems-bsps-arm.ini diff --git a/tester/rtems/rtems-bsps-bfin.ini b/config/rtems-bsps-bfin.ini similarity index 100% rename from tester/rtems/rtems-bsps-bfin.ini rename to config/rtems-bsps-bfin.ini diff --git a/tester/rtems/rtems-bsps-epiphany.ini b/config/rtems-bsps-epiphany.ini similarity index 100% rename from tester/rtems/rtems-bsps-epiphany.ini rename to config/rtems-bsps-epiphany.ini diff --git a/tester/rtems/rtems-bsps-i386.ini b/config/rtems-bsps-i386.ini similarity index 100% rename from tester/rtems/rtems-bsps-i386.ini rename to config/rtems-bsps-i386.ini diff --git a/tester/rtems/rtems-bsps-lm32.ini b/config/rtems-bsps-lm32.ini similarity index 100% rename from tester/rtems/rtems-bsps-lm32.ini rename to config/rtems-bsps-lm32.ini diff --git a/tester/rtems/rtems-bsps-m32c.ini b/config/rtems-bsps-m32c.ini similarity index 100% rename from tester/rtems/rtems-bsps-m32c.ini rename to config/rtems-bsps-m32c.ini diff --git a/tester/rtems/rtems-bsps-m68k.ini b/config/rtems-bsps-m68k.ini similarity index 100% rename from tester/rtems/rtems-bsps-m68k.ini rename to config/rtems-bsps-m68k.ini diff --git a/tester/rtems/rtems-bsps-mips.ini b/config/rtems-bsps-mips.ini similarity index 100% rename from tester/rtems/rtems-bsps-mips.ini rename to config/rtems-bsps-mips.ini diff --git a/tester/rtems/rtems-bsps-moxie.ini b/config/rtems-bsps-moxie.ini similarity index 100% rename from tester/rtems/rtems-bsps-moxie.ini rename to config/rtems-bsps-moxie.ini diff --git a/tester/rtems/rtems-bsps-nios2.ini b/config/rtems-bsps-nios2.ini similarity index 100% rename from tester/rtems/rtems-bsps-nios2.ini rename to config/rtems-bsps-nios2.ini diff --git a/tester/rtems/rtems-bsps-or1k.ini b/config/rtems-bsps-or1k.ini similarity index 100% rename from tester/rtems/rtems-bsps-or1k.ini rename to config/rtems-bsps-or1k.ini diff --git a/tester/rtems/rtems-bsps-powerpc.ini b/config/rtems-bsps-powerpc.ini similarity index 100% rename from tester/rtems/rtems-bsps-powerpc.ini rename to config/rtems-bsps-powerpc.ini diff --git a/tester/rtems/rtems-bsps-riscv.ini b/config/rtems-bsps-riscv.ini similarity index 100% rename from tester/rtems/rtems-bsps-riscv.ini rename to config/rtems-bsps-riscv.ini diff --git a/tester/rtems/rtems-bsps-riscv32.ini b/config/rtems-bsps-riscv32.ini similarity index 100% rename from tester/rtems/rtems-bsps-riscv32.ini rename to config/rtems-bsps-riscv32.ini diff --git a/tester/rtems/rtems-bsps-riscv64.ini b/config/rtems-bsps-riscv64.ini similarity index 100% rename from tester/rtems/rtems-bsps-riscv64.ini rename to config/rtems-bsps-riscv64.ini diff --git a/tester/rtems/rtems-bsps-sh.ini b/config/rtems-bsps-sh.ini similarity index 100% rename from tester/rtems/rtems-bsps-sh.ini rename to config/rtems-bsps-sh.ini diff --git a/tester/rtems/rtems-bsps-sparc.ini b/config/rtems-bsps-sparc.ini similarity index 100% rename from tester/rtems/rtems-bsps-sparc.ini rename to config/rtems-bsps-sparc.ini diff --git a/tester/rtems/rtems-bsps-sparc64.ini b/config/rtems-bsps-sparc64.ini similarity index 100% rename from tester/rtems/rtems-bsps-sparc64.ini rename to config/rtems-bsps-sparc64.ini diff --git a/tester/rtems/rtems-bsps-tiers.ini b/config/rtems-bsps-tiers.ini similarity index 100% rename from tester/rtems/rtems-bsps-tiers.ini rename to config/rtems-bsps-tiers.ini diff --git a/tester/rtems/rtems-bsps-v850.ini b/config/rtems-bsps-v850.ini similarity index 100% rename from tester/rtems/rtems-bsps-v850.ini rename to config/rtems-bsps-v850.ini diff --git a/tester/rtems/rtems-bsps.ini b/config/rtems-bsps.ini similarity index 100% rename from tester/rtems/rtems-bsps.ini rename to config/rtems-bsps.ini diff --git a/config/wscript b/config/wscript new file mode 100644 index 0000000..6ae6226 --- /dev/null +++ b/config/wscript @@ -0,0 +1,44 @@ +# +# RTEMS Tools Project (http://www.rtems.org/) +# Copyright 2018 Chris Johns (chr...@rtems.org) +# All rights reserved. +# +# This file is part of the RTEMS Tools package in 'rtems-tools'. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +def options(opt): + opt.load('python') + +def configure(opt): + pass + +def build(bld): + # + # Install the configuration files. + # + config = bld.path.find_dir('.') + bld.install_files('${PREFIX}/share/rtems/config', + config.ant_glob('**/*.ini'), cwd = config, + relative_trick = True) diff --git a/rtemstoolkit/__init__.py b/rtemstoolkit/__init__.py index ca2d619..6878782 100644 --- a/rtemstoolkit/__init__.py +++ b/rtemstoolkit/__init__.py @@ -1,6 +1,6 @@ # # RTEMS Tools Project (http://www.rtems.org/) -# Copyright 2010-2016 Chris Johns (chr...@rtems.org) +# Copyright 2010-2018 Chris Johns (chr...@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. @@ -30,26 +30,36 @@ all = ['check', 'config', + 'configuration', 'error', 'execute', 'git', + 'host', 'log', 'macros', 'mailer', 'options', 'path', 'reraise', + 'rtems', + 'stacktraces', + 'textbox', 'version'] from . import check from . import config +from . import configuration from . import error from . import execute from . import git +from . import host from . import log from . import macros from . import mailer from . import options from . import path from . import reraise +from . import rtems +from . import stacktraces +from . import textbox from . import version diff --git a/rtemstoolkit/rtems.py b/rtemstoolkit/rtems.py new file mode 100755 index 0000000..13b1e7a --- /dev/null +++ b/rtemstoolkit/rtems.py @@ -0,0 +1,372 @@ +# +# RTEMS Tools Project (http://www.rtems.org/) +# Copyright 20162018 Chris Johns (chr...@rtems.org) +# All rights reserved. +# +# This file is part of the RTEMS Tools package in 'rtems-tools'. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# + +from __future__ import print_function + +import copy +import os +import re +import textwrap + +from rtemstoolkit import configuration as configuration_ +from rtemstoolkit import error +from rtemstoolkit import textbox +from rtemstoolkit import version + + +def clean_windows_path(): + # + # On Windows MSYS2 prepends a path to itself to the environment + # path. This means the RTEMS specific automake is not found and which + # breaks the bootstrap. We need to remove the prepended path. Also + # remove any ACLOCAL paths from the environment. + # + if os.name == 'nt': + cspath = os.environ['PATH'].split(os.pathsep) + if 'msys' in cspath[0] and cspath[0].endswith('bin'): + os.environ['PATH'] = os.pathsep.join(cspath[1:]) + +class configuration: + + def __init__(self): + self.config = configuration_.configuration() + self.archs = { } + self.profiles = { } + + def __str__(self): + s = self.name + os.linesep + s += 'Archs:' + os.linesep + \ + pprint.pformat(self.archs, indent = 1, width = 80) + os.linesep + s += 'Profiles:' + os.linesep + \ + pprint.pformat(self.profiles, indent = 1, width = 80) + os.linesep + return s + + def _build_options(self, build, nesting = 0): + if ':' in build: + section, name = build.split(':', 1) + opts = [self.config.get_item(section, name)] + return opts + builds = self.builds_['builds'] + if build not in builds: + raise error.general('build %s not found' % (build)) + if nesting > 20: + raise error.general('nesting build %s' % (build)) + options = [] + for option in self.builds_['builds'][build]: + if ':' in option: + section, name = option.split(':', 1) + opts = [self.config.get_item(section, name)] + else: + opts = self._build_options(option, nesting + 1) + for opt in opts: + if opt not in options: + options += [opt] + return options + + def load(self, name, build): + self.config.load(name) + archs = [] + self.profiles['profiles'] = \ + self.config.comma_list('profiles', 'profiles', err = False) + if len(self.profiles['profiles']) == 0: + self.profiles['profiles'] = ['tier-%d' % (t) for t in range(1,4)] + for p in self.profiles['profiles']: + profile = {} + profile['name'] = p + profile['archs'] = self.config.comma_list(profile['name'], 'archs', err = False) + archs += profile['archs'] + for arch in profile['archs']: + bsps = 'bsps_%s' % (arch) + profile[bsps] = self.config.comma_list(profile['name'], bsps) + self.profiles[profile['name']] = profile + invalid_chars = re.compile(r'[^a-zA-Z0-9_-]') + for a in set(archs): + if len(invalid_chars.findall(a)) != 0: + raise error.general('invalid character(s) in arch name: %s' % (a)) + arch = {} + arch['excludes'] = {} + for exclude in self.config.comma_list(a, 'exclude', err = False): + arch['excludes'][exclude] = ['all'] + for i in self.config.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.config.comma_list(a, 'bsps', err = False) + for b in arch['bsps']: + if len(invalid_chars.findall(b)) != 0: + raise error.general('invalid character(s) in BSP name: %s' % (b)) + arch[b] = {} + arch[b]['bspopts'] = \ + self.config.comma_list(a, 'bspopts_%s' % (b), err = False) + self.archs[a] = arch + builds = {} + builds['default'] = self.config.get_item('builds', 'default') + if build is None: + build = builds['default'] + builds['config'] = { } + for config in self.config.get_items('config'): + builds['config'][config[0]] = config[1] + builds['build'] = build + builds_ = self.config.get_item_names('builds') + builds['builds'] = {} + for build in builds_: + build_builds = self.config.comma_list('builds', build) + has_config = False + has_build = False + for b in build_builds: + if ':' in b: + if has_build: + raise error.general('config and build in build: %s' % (build)) + has_config = True + else: + if has_config: + raise error.general('config and build in build: %s' % (build)) + has_build = True + builds['builds'][build] = build_builds + self.builds_ = builds + + def configs(self): + return sorted(list(self.builds_['config'].keys())) + + def config_flags(self, config): + if config not in self.builds_['config']: + raise error.general('config entry not found: %s' % (config)) + return self.builds_['config'][config] + + def build(self): + return self.builds_['build'] + + def builds(self): + if self.builds_['build'] in self.builds_['builds']: + build = copy.copy(self.builds_['builds'][self.builds_['build']]) + if ':' in build[0]: + return [self.builds_['build']] + return build + return None + + def build_options(self, build): + return ' '.join(self._build_options(build)) + + def excludes(self, arch, bsp): + return list(set(self.arch_excludes(arch) + self.bsp_excludes(arch, bsp))) + + def exclude_options(self, arch, bsp): + return ' '.join([self.config_flags('no-' + e) for e in self.excludes(arch, bsp)]) + + def archs(self): + return sorted(self.archs.keys()) + + def arch_present(self, arch): + return arch in self.archs + + def arch_excludes(self, arch): + 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 arch_bsps(self, arch): + return sorted(self.archs[arch]['bsps']) + + 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 'all' not in self.archs[arch]['excludes'][exclude] and \ + bsp not in self.archs[arch]['excludes'][exclude]: + excludes.remove(exclude) + return sorted(excludes) + + def bspopts(self, arch, bsp): + if arch not in self.archs: + raise error.general('invalid architecture: %s' % (arch)) + if bsp not in self.archs[arch]: + raise error.general('invalid BSP: %s' % (bsp)) + return self.archs[arch][bsp]['bspopts'] + + def profile_present(self, profile): + return profile in self.profiles + + def profile_archs(self, profile): + if profile not in self.profiles: + raise error.general('invalid profile: %s' % (profile)) + return self.profiles[profile]['archs'] + + def profile_arch_bsps(self, profile, arch): + if profile not in self.profiles: + raise error.general('invalid profile: %s' % (profile)) + if 'bsps_%s' % (arch) not in self.profiles[profile]: + raise error.general('invalid profile arch: %s' % (arch)) + return ['%s/%s' % (arch, bsp) for bsp in self.profiles[profile]['bsps_%s' % (arch)]] + + def report(self, profiles = True, builds = True, architectures = True): + width = 70 + cols_1 = [width] + cols_2 = [10, width - 10] + s = textbox.line(cols_1, line = '=', marker = '+', indent = 1) + s1 = ' File(s)' + for f in self.config.files(): + colon = ':' + for l in textwrap.wrap(f, width = cols_2[1] - 3): + s += textbox.row(cols_2, [s1, ' ' + l], marker = colon, indent = 1) + colon = ' ' + s1 = ' ' * len(s1) + s += textbox.line(cols_1, marker = '+', indent = 1) + s += os.linesep + if profiles: + s += textbox.line(cols_1, line = '=', marker = '+', indent = 1) + profiles = sorted(self.profiles['profiles']) + archs = [] + bsps = [] + for profile in profiles: + archs += self.profiles[profile]['archs'] + for arch in sorted(self.profiles[profile]['archs']): + bsps += self.profiles[profile]['bsps_%s' % (arch)] + archs = len(set(archs)) + bsps = len(set(bsps)) + s += textbox.row(cols_1, + [' Profiles : %d (archs:%d, bsps:%d)' % \ + (len(profiles), archs, bsps)], + indent = 1) + for profile in profiles: + textbox.row(cols_2, + [profile, self.profiles[profile]['name']], + indent = 1) + s += textbox.line(cols_1, marker = '+', indent = 1) + for profile in profiles: + s += textbox.row(cols_1, [' %s' % (profile)], indent = 1) + profile = self.profiles[profile] + archs = sorted(profile['archs']) + for arch in archs: + arch_bsps = ', '.join(profile['bsps_%s' % (arch)]) + if len(arch_bsps) > 0: + s += textbox.line(cols_2, marker = '+', indent = 1) + s1 = ' ' + arch + for l in textwrap.wrap(arch_bsps, + width = cols_2[1] - 3): + s += textbox.row(cols_2, [s1, ' ' + l], indent = 1) + s1 = ' ' * len(s1) + s += textbox.line(cols_2, marker = '+', indent = 1) + s += os.linesep + if builds: + s += textbox.line(cols_1, line = '=', marker = '+', indent = 1) + s += textbox.row(cols_1, + [' Builds: %s (default)' % (self.builds_['default'])], + indent = 1) + builds = self.builds_['builds'] + bsize = 0 + for build in builds: + if len(build) > bsize: + bsize = len(build) + cols_b = [bsize + 2, width - bsize - 2] + s += textbox.line(cols_b, marker = '+', indent = 1) + for build in builds: + s1 = ' ' + build + for l in textwrap.wrap(', '.join(builds[build]), + width = cols_b[1] - 3): + s += textbox.row(cols_b, [s1, ' ' + l], indent = 1) + s1 = ' ' * len(s1) + s += textbox.line(cols_b, marker = '+', indent = 1) + configs = self.builds_['config'] + s += textbox.row(cols_1, + [' Configure Options: %d' % (len(configs))], + indent = 1) + csize = 0 + for config in configs: + if len(config) > csize: + csize = len(config) + cols_c = [csize + 3, width - csize - 3] + s += textbox.line(cols_c, marker = '+', indent = 1) + for config in configs: + s1 = ' ' + config + for l in textwrap.wrap(configs[config], width = cols_c[1] - 3): + s += textbox.row(cols_c, [s1, ' ' + l], indent = 1) + s1 = ' ' * len(s1) + s += textbox.line(cols_c, marker = '+', indent = 1) + s += os.linesep + if architectures: + s += textbox.line(cols_1, line = '=', marker = '+', indent = 1) + archs = sorted(self.archs.keys()) + bsps = 0 + asize = 0 + for arch in archs: + if len(arch) > asize: + asize = len(arch) + bsps += len(self.archs[arch]['bsps']) + s += textbox.row(cols_1, + [' Architectures : %d (bsps: %d)' % (len(archs), bsps)], + indent = 1) + cols_a = [asize + 2, width - asize - 2] + s += textbox.line(cols_a, marker = '+', indent = 1) + for arch in archs: + s += textbox.row(cols_a, + [' ' + arch, ' %d' % (len(self.archs[arch]['bsps']))], + indent = 1) + s += textbox.line(cols_a, marker = '+', indent = 1) + for archn in archs: + arch = self.archs[archn] + if len(arch['bsps']) > 0: + bsize = 0 + for bsp in arch['bsps']: + if len(bsp) > bsize: + bsize = len(bsp) + cols_b = [bsize + 3, width - bsize - 3] + s += textbox.row(cols_1, [' ' + archn + ':'], indent = 1) + s += textbox.line(cols_b, marker = '+', indent = 1) + for bsp in arch['bsps']: + s1 = ' ' + bsp + bspopts = ' '.join(arch[bsp]['bspopts']) + if len(bspopts): + for l in textwrap.wrap('bopt: ' + bspopts, + width = cols_b[1] - 3): + s += textbox.row(cols_b, [s1, ' ' + l], indent = 1) + s1 = ' ' * len(s1) + excludes = [] + for exclude in arch['excludes']: + if 'all' in arch['excludes'][exclude] or \ + bsp in arch['excludes'][exclude]: + excludes += [exclude] + excludes = ', '.join(excludes) + if len(excludes): + for l in textwrap.wrap('ex: ' + excludes, + width = cols_b[1] - 3): + s += textbox.row(cols_b, [s1, ' ' + l], indent = 1) + s1 = ' ' * len(s1) + if len(bspopts) == 0 and len(excludes) == 0: + s += textbox.row(cols_b, [s1, ' '], indent = 1) + s += textbox.line(cols_b, marker = '+', indent = 1) + s += os.linesep + return s diff --git a/rtemstoolkit/wscript b/rtemstoolkit/wscript index 4b5fa34..1b124c7 100644 --- a/rtemstoolkit/wscript +++ b/rtemstoolkit/wscript @@ -148,6 +148,7 @@ def build(bld): 'options.py', 'path.py', 'reraise.py', + 'rtems.py', 'stacktraces.py', 'textbox.py', 'version.py', diff --git a/tester/rt/check.py b/tester/rt/check.py index e202946..0f9ee13 100755 --- a/tester/rt/check.py +++ b/tester/rt/check.py @@ -44,13 +44,13 @@ import traceback import pprint -from rtemstoolkit import configuration from rtemstoolkit import execute from rtemstoolkit import error from rtemstoolkit import host from rtemstoolkit import log from rtemstoolkit import mailer from rtemstoolkit import path +from rtemstoolkit import rtems from rtemstoolkit import textbox from rtemstoolkit import version @@ -880,327 +880,6 @@ class arch_bsp_builder: self._notice('Cleaning: %s' % (self._build_dir())) path.removeall(self._build_dir()) -class configuration_: - - def __init__(self): - self.config = configuration.configuration() - self.archs = { } - self.builds_ = { } - self.profiles = { } - - def __str__(self): - s = self.name + os.linesep - s += 'Archs:' + os.linesep + \ - pprint.pformat(self.archs, indent = 1, width = 80) + os.linesep - s += 'Builds:' + os.linesep + \ - pprint.pformat(self.builds_, indent = 1, width = 80) + os.linesep - s += 'Profiles:' + os.linesep + \ - pprint.pformat(self.profiles, indent = 1, width = 80) + os.linesep - return s - - def _build_options(self, build, nesting = 0): - if ':' in build: - section, name = build.split(':', 1) - opts = [self.config.get_item(section, name)] - return opts - builds = self.builds_['builds'] - if build not in builds: - raise error.general('build %s not found' % (build)) - if nesting > 20: - raise error.general('nesting build %s' % (build)) - options = [] - for option in self.builds_['builds'][build]: - if ':' in option: - section, name = option.split(':', 1) - opts = [self.config.get_item(section, name)] - else: - opts = self._build_options(option, nesting + 1) - for opt in opts: - if opt not in options: - options += [opt] - return options - - def load(self, name, build): - self.config.load(name) - archs = [] - self.profiles['profiles'] = \ - self.config.comma_list('profiles', 'profiles', err = False) - if len(self.profiles['profiles']) == 0: - self.profiles['profiles'] = ['tier-%d' % (t) for t in range(1,4)] - for p in self.profiles['profiles']: - profile = {} - profile['name'] = p - profile['archs'] = self.config.comma_list(profile['name'], 'archs', err = False) - archs += profile['archs'] - for arch in profile['archs']: - bsps = 'bsps_%s' % (arch) - profile[bsps] = self.config.comma_list(profile['name'], bsps) - self.profiles[profile['name']] = profile - invalid_chars = re.compile(r'[^a-zA-Z0-9_-]') - for a in set(archs): - if len(invalid_chars.findall(a)) != 0: - raise error.general('invalid character(s) in arch name: %s' % (a)) - arch = {} - arch['excludes'] = {} - for exclude in self.config.comma_list(a, 'exclude', err = False): - arch['excludes'][exclude] = ['all'] - for i in self.config.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.config.comma_list(a, 'bsps', err = False) - for b in arch['bsps']: - if len(invalid_chars.findall(b)) != 0: - raise error.general('invalid character(s) in BSP name: %s' % (b)) - arch[b] = {} - arch[b]['bspopts'] = \ - self.config.comma_list(a, 'bspopts_%s' % (b), err = False) - self.archs[a] = arch - builds = {} - builds['default'] = self.config.get_item('builds', 'default') - if build is None: - build = builds['default'] - builds['config'] = { } - for config in self.config.get_items('config'): - builds['config'][config[0]] = config[1] - builds['build'] = build - builds_ = self.config.get_item_names('builds') - builds['builds'] = {} - for build in builds_: - build_builds = self.config.comma_list('builds', build) - has_config = False - has_build = False - for b in build_builds: - if ':' in b: - if has_build: - raise error.general('config and build in build: %s' % (build)) - has_config = True - else: - if has_config: - raise error.general('config and build in build: %s' % (build)) - has_build = True - builds['builds'][build] = build_builds - self.builds_ = builds - - def configs(self): - return sorted(list(self.builds_['config'].keys())) - - def config_flags(self, config): - if config not in self.builds_['config']: - raise error.general('config entry not found: %s' % (config)) - return self.builds_['config'][config] - - def build(self): - return self.builds_['build'] - - def builds(self): - if self.builds_['build'] in self.builds_['builds']: - build = copy.copy(self.builds_['builds'][self.builds_['build']]) - if ':' in build[0]: - return [self.builds_['build']] - return build - return None - - def build_options(self, build): - return ' '.join(self._build_options(build)) - - def excludes(self, arch, bsp): - return list(set(self.arch_excludes(arch) + self.bsp_excludes(arch, bsp))) - - def exclude_options(self, arch, bsp): - return ' '.join([self.config_flags('no-' + e) for e in self.excludes(arch, bsp)]) - - def archs(self): - return sorted(self.archs.keys()) - - def arch_present(self, arch): - return arch in self.archs - - def arch_excludes(self, arch): - 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 arch_bsps(self, arch): - return sorted(self.archs[arch]['bsps']) - - 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 'all' not in self.archs[arch]['excludes'][exclude] and \ - bsp not in self.archs[arch]['excludes'][exclude]: - excludes.remove(exclude) - return sorted(excludes) - - def bspopts(self, arch, bsp): - if arch not in self.archs: - raise error.general('invalid architecture: %s' % (arch)) - if bsp not in self.archs[arch]: - raise error.general('invalid BSP: %s' % (bsp)) - return self.archs[arch][bsp]['bspopts'] - - def profile_present(self, profile): - return profile in self.profiles - - def profile_archs(self, profile): - if profile not in self.profiles: - raise error.general('invalid profile: %s' % (profile)) - return self.profiles[profile]['archs'] - - def profile_arch_bsps(self, profile, arch): - if profile not in self.profiles: - raise error.general('invalid profile: %s' % (profile)) - if 'bsps_%s' % (arch) not in self.profiles[profile]: - raise error.general('invalid profile arch: %s' % (arch)) - return ['%s/%s' % (arch, bsp) for bsp in self.profiles[profile]['bsps_%s' % (arch)]] - - def report(self, profiles = True, builds = True, architectures = True): - width = 70 - cols_1 = [width] - cols_2 = [10, width - 10] - s = textbox.line(cols_1, line = '=', marker = '+', indent = 1) - s1 = ' File(s)' - for f in self.config.files(): - colon = ':' - for l in textwrap.wrap(f, width = cols_2[1] - 3): - s += textbox.row(cols_2, [s1, ' ' + l], marker = colon, indent = 1) - colon = ' ' - s1 = ' ' * len(s1) - s += textbox.line(cols_1, marker = '+', indent = 1) - s += os.linesep - if profiles: - s += textbox.line(cols_1, line = '=', marker = '+', indent = 1) - profiles = sorted(self.profiles['profiles']) - archs = [] - bsps = [] - for profile in profiles: - archs += self.profiles[profile]['archs'] - for arch in sorted(self.profiles[profile]['archs']): - bsps += self.profiles[profile]['bsps_%s' % (arch)] - archs = len(set(archs)) - bsps = len(set(bsps)) - s += textbox.row(cols_1, - [' Profiles : %d (archs:%d, bsps:%d)' % \ - (len(profiles), archs, bsps)], - indent = 1) - for profile in profiles: - textbox.row(cols_2, - [profile, self.profiles[profile]['name']], - indent = 1) - s += textbox.line(cols_1, marker = '+', indent = 1) - for profile in profiles: - s += textbox.row(cols_1, [' %s' % (profile)], indent = 1) - profile = self.profiles[profile] - archs = sorted(profile['archs']) - for arch in archs: - arch_bsps = ', '.join(profile['bsps_%s' % (arch)]) - if len(arch_bsps) > 0: - s += textbox.line(cols_2, marker = '+', indent = 1) - s1 = ' ' + arch - for l in textwrap.wrap(arch_bsps, - width = cols_2[1] - 3): - s += textbox.row(cols_2, [s1, ' ' + l], indent = 1) - s1 = ' ' * len(s1) - s += textbox.line(cols_2, marker = '+', indent = 1) - s += os.linesep - if builds: - s += textbox.line(cols_1, line = '=', marker = '+', indent = 1) - s += textbox.row(cols_1, - [' Builds: %s (default)' % (self.builds_['default'])], - indent = 1) - builds = self.builds_['builds'] - bsize = 0 - for build in builds: - if len(build) > bsize: - bsize = len(build) - cols_b = [bsize + 2, width - bsize - 2] - s += textbox.line(cols_b, marker = '+', indent = 1) - for build in builds: - s1 = ' ' + build - for l in textwrap.wrap(', '.join(builds[build]), - width = cols_b[1] - 3): - s += textbox.row(cols_b, [s1, ' ' + l], indent = 1) - s1 = ' ' * len(s1) - s += textbox.line(cols_b, marker = '+', indent = 1) - configs = self.builds_['config'] - s += textbox.row(cols_1, - [' Configure Options: %d' % (len(configs))], - indent = 1) - csize = 0 - for config in configs: - if len(config) > csize: - csize = len(config) - cols_c = [csize + 3, width - csize - 3] - s += textbox.line(cols_c, marker = '+', indent = 1) - for config in configs: - s1 = ' ' + config - for l in textwrap.wrap(configs[config], width = cols_c[1] - 3): - s += textbox.row(cols_c, [s1, ' ' + l], indent = 1) - s1 = ' ' * len(s1) - s += textbox.line(cols_c, marker = '+', indent = 1) - s += os.linesep - if architectures: - s += textbox.line(cols_1, line = '=', marker = '+', indent = 1) - archs = sorted(self.archs.keys()) - bsps = 0 - asize = 0 - for arch in archs: - if len(arch) > asize: - asize = len(arch) - bsps += len(self.archs[arch]['bsps']) - s += textbox.row(cols_1, - [' Architectures : %d (bsps: %d)' % (len(archs), bsps)], - indent = 1) - cols_a = [asize + 2, width - asize - 2] - s += textbox.line(cols_a, marker = '+', indent = 1) - for arch in archs: - s += textbox.row(cols_a, - [' ' + arch, ' %d' % (len(self.archs[arch]['bsps']))], - indent = 1) - s += textbox.line(cols_a, marker = '+', indent = 1) - for archn in archs: - arch = self.archs[archn] - if len(arch['bsps']) > 0: - bsize = 0 - for bsp in arch['bsps']: - if len(bsp) > bsize: - bsize = len(bsp) - cols_b = [bsize + 3, width - bsize - 3] - s += textbox.row(cols_1, [' ' + archn + ':'], indent = 1) - s += textbox.line(cols_b, marker = '+', indent = 1) - for bsp in arch['bsps']: - s1 = ' ' + bsp - bspopts = ' '.join(arch[bsp]['bspopts']) - if len(bspopts): - for l in textwrap.wrap('bopt: ' + bspopts, - width = cols_b[1] - 3): - s += textbox.row(cols_b, [s1, ' ' + l], indent = 1) - s1 = ' ' * len(s1) - excludes = [] - for exclude in arch['excludes']: - if 'all' in arch['excludes'][exclude] or \ - bsp in arch['excludes'][exclude]: - excludes += [exclude] - excludes = ', '.join(excludes) - if len(excludes): - for l in textwrap.wrap('ex: ' + excludes, - width = cols_b[1] - 3): - s += textbox.row(cols_b, [s1, ' ' + l], indent = 1) - s1 = ' ' * len(s1) - if len(bspopts) == 0 and len(excludes) == 0: - s += textbox.row(cols_b, [s1, ' '], indent = 1) - s += textbox.line(cols_b, marker = '+', indent = 1) - s += os.linesep - return s - class build_jobs: def __init__(self, config, arch, bsp): @@ -1442,16 +1121,7 @@ def run_args(args): b = None ec = 0 try: - # - # On Windows MSYS2 prepends a path to itself to the environment - # path. This means the RTEMS specific automake is not found and which - # breaks the bootstrap. We need to remove the prepended path. Also - # remove any ACLOCAL paths from the environment. - # - if os.name == 'nt': - cspath = os.environ['PATH'].split(os.pathsep) - if 'msys' in cspath[0] and cspath[0].endswith('bin'): - os.environ['PATH'] = os.pathsep.join(cspath[1:]) + rtems.clean_windows_path() start = datetime.datetime.now() top = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0]))) @@ -1460,10 +1130,9 @@ def run_args(args): 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') + config_file = path.join(top, 'config', 'rtems-bsps.ini') if not path.exists(config_file): - config_file = path.join(top, 'tester', 'rtems', 'rtems-bsps.ini') + config_file = path.join(top, 'share', 'rtems', 'config', 'rtems-bsps.ini') argsp = argparse.ArgumentParser() argsp.add_argument('--prefix', help = 'Prefix to build the BSP.', @@ -1521,7 +1190,7 @@ def run_args(args): to_addr, smtp_host)) - config = configuration_() + config = rtems.configuration() config.load(config_file, opts.build) if opts.config_report: diff --git a/wscript b/wscript index 1716b90..c0286de 100644 --- a/wscript +++ b/wscript @@ -33,6 +33,7 @@ import os.path import wafwindows subdirs = ['rtemstoolkit', + 'config', 'linkers', 'misc', 'tester', -- 2.15.1 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel