diff options
-rw-r--r-- | __init__.py | 2 | ||||
-rw-r--r-- | dl.py | 33 | ||||
-rw-r--r-- | git.py | 226 | ||||
-rw-r--r-- | pkgconfig.py | 11 | ||||
-rw-r--r-- | rootfs.py | 71 | ||||
-rw-r--r-- | rtems.py | 389 | ||||
-rw-r--r-- | rtems_bsd.py | 75 | ||||
-rw-r--r-- | version.py | 272 |
8 files changed, 854 insertions, 225 deletions
diff --git a/__init__.py b/__init__.py index e60cc4d..35448e6 100644 --- a/__init__.py +++ b/__init__.py @@ -1,5 +1,5 @@ # Copyright 2013 Chris Johns (chrisj@rtems.org) -# +# # This file's license is 2-clause BSD as in this distribution's LICENSE.2 file. # @@ -26,6 +26,7 @@ import os + def _syms_rule(tsk): ''' A rule handler so 'no_errcheck_out' can be set. This avoids the @@ -34,13 +35,12 @@ def _syms_rule(tsk): setattr(tsk, 'no_errcheck_out', True) src = tsk.inputs[0].abspath() tgt = tsk.outputs[0].abspath() - cmd = '%s -e -C %s -c "%s" -o %s %s' % (' '.join(tsk.env.RTEMS_SYMS), - ' '.join(tsk.env.CC), - ' '.join(tsk.env.CFLAGS), - tgt, - src) + cmd = '%s -e -C %s -c "%s" -o %s %s' % (' '.join( + tsk.env.RTEMS_SYMS), ' '.join(tsk.env.CC), ' '.join( + tsk.env.CFLAGS), tgt, src) return tsk.exec_command(cmd) + def syms(ctx, target, source): ''' Create a symbols object file from a base kernel image. The object @@ -55,12 +55,10 @@ def syms(ctx, target, source): :param source: The kernel base image to generate the symbol table of ''' tgt = ctx.path.find_or_declare(target) - ctx(rule = _syms_rule, - target = tgt, - source = source, - color = 'CYAN') + ctx(rule=_syms_rule, target=tgt, source=source, color='CYAN') ctx.read_object(tgt) + def _strip_rule(tsk): ''' A rule handler so 'no_errcheck_out' can be set. We need this because @@ -73,6 +71,7 @@ def _strip_rule(tsk): cmd = '%s -d -o %s %s' % (' '.join(tsk.env.STRIP), tgt, src) return tsk.exec_command(cmd) + def strip_debug_info(ctx, *k, **kw): ''' Strip the source object file or archive of debug information @@ -95,11 +94,12 @@ def strip_debug_info(ctx, *k, **kw): ctx.fatal('No name and source is not a path') name = 'strip-%s' % (os.path.basename(source)) print(type(source), str(source), target) - ctx(rule = _strip_rule, - name = name, - target = target, - source = source, - color = 'CYAN') + ctx(rule=_strip_rule, + name=name, + target=target, + source=source, + color='CYAN') + def _ranlib_rule(tsk): ''' @@ -112,7 +112,6 @@ def _ranlib_rule(tsk): cmd = '%s -t %s' % (' '.join(tsk.env.RANLIB), tgt) return tsk.exec_command(cmd) + def ranlib(ctx, lib): - ctx(rule = _ranlib_rule, - name = 'ranlib-%s' % (lib), - source = lib) + ctx(rule=_ranlib_rule, name='ranlib-%s' % (lib), source=lib) @@ -0,0 +1,226 @@ +# +# RTEMS Tools Project (http://www.rtems.org/) +# Copyright 2010-2016, 2023 Chris Johns (chrisj@rtems.org) +# All rights reserved. +# +# This file is part of the RTEMS Tools package in 'rtems-tools'. +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +# +# Provide some basic access to the git command. +# + +from __future__ import print_function + +import os +import os.path + + +class repo: + """An object to manage a git repo.""" + def _git_exit_code(self, ec): + if ec: + raise self.ctx.fatal('git command failed (%s): %d' % + (self.git, ec)) + + def _run(self, args, check=False): + import waflib + if os.path.exists(self.path): + cwd = self.path + else: + cwd = None + cmd = [self.git] + args + exit_code = 0 + try: + output = self.ctx.cmd_and_log(cmd, + cwd=cwd, + output=waflib.Context.STDOUT, + quiet=waflib.Context.BOTH) + except waflib.Errors.WafError as e: + exit_code = e.returncode + output = e.stderr + if check: + self._git_exit_code(exit_code) + return exit_code, output + + def __init__(self, ctx, path): + self.ctx = ctx + self.path = path + self.git = 'git' + + def git_version(self): + ec, output = self._run(['--version'], True) + gvs = output.split() + if len(gvs) < 3: + raise self.ctx.fatal('invalid version string from git: %s' % + (output)) + vs = gvs[2].split('.') + if len(vs) not in [3, 4]: + raise self.ctx.fatal('invalid version number from git: %s' % + (gvs[2])) + return tuple(map(int, vs)) + + def clone(self, url, path): + ec, output = self._run(['clone', url, path], check=True) + + def fetch(self): + ec, output = self._run(['fetch'], check=True) + + def merge(self): + ec, output = self._run(['merge'], check=True) + + def pull(self): + ec, output = self._run(['pull'], check=True) + + def reset(self, args): + if type(args) == str: + args = [args] + ec, output = self._run(['reset'] + args, check=True) + + def branch(self): + ec, output = self._run(['branch']) + if ec == 0: + for b in output.split(os.linesep): + if b[0] == '*': + return b[2:] + return None + + def checkout(self, branch='master'): + ec, output = self._run(['checkout', branch], check=True) + + def submodule(self, module): + ec, output = self._run(['submodule', 'update', '--init', module], + check=True) + + def submodule_foreach(self, args=[]): + if type(args) == str: + args = [args.split(args)] + ec, output = self._run( + ['submodule', 'foreach', '--recursive', self.git] + args, + check=True) + + def submodules(self): + smodules = {} + ec, output = self._run(['submodule'], check=True) + if ec == 0: + for l in output.split(os.linesep): + ms = l.split() + if len(ms) == 3: + smodules[ms[1]] = (ms[0], ms[2][1:-1]) + return smodules + + def clean(self, args=[]): + if type(args) == str: + args = [args] + ec, output = self._run(['clean'] + args, check=True) + + def status(self, submodules_always_clean=False): + _status = {} + if os.path.exists(self.path): + if submodules_always_clean: + submodules = self.submodules() + else: + submodules = {} + ec, output = self._run(['status']) + if ec == 0: + state = 'none' + for l in output.split(os.linesep): + if l.startswith('# '): + l = l[2:] + if l.startswith('On branch '): + _status['branch'] = l[len('On branch '):] + elif l.startswith('Changes to be committed:'): + state = 'staged' + elif l.startswith('Changes not staged for commit:'): + state = 'unstaged' + elif l.startswith('Untracked files:'): + state = 'untracked' + elif l.startswith('HEAD detached'): + state = 'detached' + elif state != 'none' and len(l.strip()) != 0: + if l[0].isspace(): + l = l.strip() + if l[0] != '(': + if ':' in l: + l = l.split(':')[1] + if len(l.strip()) > 0: + l = l.strip() + ls = l.split() + if state != 'unstaged' or ls[ + 0] not in submodules: + if state not in _status: + _status[state] = [l] + else: + _status[state] += [l] + return _status + + def dirty(self): + _status = self.status() + _status.pop('untracked', None) + _status.pop('detached', None) + return not (len(_status) == 1 and 'branch' in _status) + + def valid(self): + if os.path.exists(self.path): + ec, output = self._run(['status']) + return ec == 0 + return False + + def remotes(self): + _remotes = {} + ec, output = self._run(['config', '--list']) + if ec == 0: + for l in output.split(os.linesep): + if l.startswith('remote'): + ls = l.split('=') + if len(ls) >= 2: + rs = ls[0].split('.') + if len(rs) == 3: + r_name = rs[1] + r_type = rs[2] + if r_name not in _remotes: + _remotes[r_name] = {} + if r_type not in _remotes[r_name]: + _remotes[r_name][r_type] = [] + _remotes[r_name][r_type] = '='.join(ls[1:]) + return _remotes + + def email(self): + _email = None + _name = None + ec, output = self._run(['config', '--list']) + if ec == 0: + for l in output.split(os.linesep): + if l.startswith('user.email'): + ls = l.split('=') + if len(ls) >= 2: + _email = ls[1] + elif l.startswith('user.name'): + ls = l.split('=') + if len(ls) >= 2: + _name = ls[1] + if _email is not None: + if _name is not None: + _email = '%s <%s>' % (_name, _email) + return _email + return None + + def head(self): + hash = '' + ec, output = self._run(['log', '-n', '1']) + if ec == 0: + l1 = output.split(os.linesep)[0] + if l1.startswith('commit '): + hash = l1[len('commit '):] + return hash diff --git a/pkgconfig.py b/pkgconfig.py index 382f4dc..673633a 100644 --- a/pkgconfig.py +++ b/pkgconfig.py @@ -1,5 +1,5 @@ # Copyright 2013 Chris Johns (chrisj@rtems.org) -# +# # This file's license is 2-clause BSD as in this distribution's LICENSE.2 file. # @@ -12,6 +12,7 @@ # import re + class error(Exception): def __init__(self, msg): self.msg = msg @@ -19,8 +20,9 @@ class error(Exception): def __str__(self): return self.msg + class package: - def __init__(self, file = None): + def __init__(self, file=None): self.defines = {} self.fields = {} if file: @@ -57,7 +59,8 @@ class package: rhs = l[d + 1:] if tm: - print('define: ' + str(define) + ', lhs: ' + lhs + ', ' + rhs) + print('define: ' + str(define) + ', lhs: ' + lhs + + ', ' + rhs) if define: self.defines[lhs] = rhs @@ -65,7 +68,7 @@ class package: self.fields[lhs] = rhs def get(self, label): - if label.lower() not in self.fields: + if label.lower() not in self.fields: raise error('Label not found: ' + label) mre = re.compile('\$\{[^\}]+\}') s = self.fields[label.lower()] @@ -26,38 +26,40 @@ import os + def join(*paths): path = '' for p in paths: path = os.path.join(path, str(p)) return path + def copy(ctx, name, root, target, source): '''Copy a file from the source to the target.''' if isinstance(target, str): target = ctx.path.make_node(target) #print('copy: name=%s source=%s target=%s' % (name, source, target)) - ctx(rule = 'cp ${SRC} ${TGT}', - name = name, - source = source, - target = target) + ctx(rule='cp ${SRC} ${TGT}', name=name, source=source, target=target) + def tar(ctx, name, root, target, source, depends_on): #print('tar: name=%s root=%s target=%r source=%r' % (name, root, target, source)) - ctx(rule = 'tar -C %s -cf ${TGT} .' % (root), - name = name, - target = target, - source = source, - root = join(ctx.path.get_bld(), root), - depends_on = depends_on, - color = 'CYAN') + ctx(rule='tar -C %s -cf ${TGT} .' % (root), + name=name, + target=target, + source=source, + root=join(ctx.path.get_bld(), root), + depends_on=depends_on, + color='CYAN') + def bin2c(ctx, name, target, source): - ctx(rule = '${RTEMS_BIN2C} ${SRC} ${TGT}', - name = name, - target = target, - source = source, - color = 'PINK') + ctx(rule='${RTEMS_BIN2C} ${SRC} ${TGT}', + name=name, + target=target, + source=source, + color='PINK') + def build(ctx, name, root, files): """The files are truples of the name, source and target files to put in the tar @@ -89,7 +91,9 @@ def build(ctx, name, root, files): if not isinstance(f, tuple): ctx.fatal('rootfs build file is not a tuple') if len(f) != 3: - ctx.fatal('rootfs build file tuple has 3 items (name, src, dst): %s' % (str(f))) + ctx.fatal( + 'rootfs build file tuple has 3 items (name, src, dst): %s' % + (str(f))) # # Copy the file as a build task. The file is copied to the tar file's # root. @@ -100,10 +104,10 @@ def build(ctx, name, root, files): else: source = f[1] copy(ctx, - name = f[0], - root = root, - target = ctx.path.make_node(join(root, f[2])).get_bld(), - source = source) + name=f[0], + root=root, + target=ctx.path.make_node(join(root, f[2])).get_bld(), + source=source) ctx.add_group() @@ -111,11 +115,11 @@ def build(ctx, name, root, files): # Tar build task. # tar(ctx, - name = name + '-tar', - root = join(ctx.path.get_bld(), root), - target = name + '.tar', - source = [join(root, f[2]) for f in files], - depends_on = [f[0] for f in files]) + name=name + '-tar', + root=join(ctx.path.get_bld(), root), + target=name + '.tar', + source=[join(root, f[2]) for f in files], + depends_on=[f[0] for f in files]) ctx.add_group() @@ -123,21 +127,18 @@ def build(ctx, name, root, files): # Binary to C build task. It converts the tar file to a C file. This uses # the RTEMS Tools Project's `bin2c` command. # - bin2c(ctx, - name = name, - target = name + '-tar.c', - source = name + '.tar') + bin2c(ctx, name=name, target=name + '-tar.c', source=name + '.tar') ctx.add_group() - ctx.objects(features = 'c', - target = name + '-obj', - source = name + '-tar.c') + ctx.objects(features='c', target=name + '-obj', source=name + '-tar.c') + def build_from_src_root(ctx, name, root): root_path = ctx.path.make_node(root) if not root_path.exists(): ctx.fatal('tar root not found: %s' % (root_path)) sources = [s.path_from(root_path) for s in root_path.ant_glob('**')] - build(ctx, name, root, [('%s-%s' % (name, os.path.basename(s)), - join(root, s), s) for s in sources]) + build(ctx, name, root, + [('%s-%s' % (name, os.path.basename(s)), join(root, s), s) + for s in sources]) @@ -1,4 +1,3 @@ - # Copyright 2012-2016 Chris Johns (chrisj@rtems.org) # # Redistribution and use in source and binary forms, with or without @@ -42,34 +41,38 @@ rtems_long_commands = False windows = os.name == 'nt' or sys.platform in ['msys', 'cygwin'] + def options(opt): - opt.add_option('--rtems', - default = None, - dest = 'rtems_path', - help = 'Path to an installed RTEMS (defaults to prefix).') - opt.add_option('--rtems-tools', - default = None, - dest = 'rtems_tools', - help = 'Path to RTEMS tools (defaults to path to installed RTEMS).') - opt.add_option('--rtems-version', - default = None, - dest = 'rtems_version', - help = 'RTEMS version (default is derived from prefix).') - opt.add_option('--rtems-archs', - default = 'all', - dest = 'rtems_archs', - help = 'List of RTEMS architectures to build.') - opt.add_option('--rtems-bsps', - default = 'all', - dest = 'rtems_bsps', - help = 'List of BSPs to build.') - opt.add_option('--show-commands', - action = 'store_true', - default = False, - dest = 'show_commands', - help = 'Print the commands as strings.') - -def init(ctx, filters = None, version = None, long_commands = False, bsp_init = None): + copts = opt.option_groups['configure options'] + copts.add_option('--rtems', + default=None, + dest='rtems_path', + help='Path to an installed RTEMS (defaults to prefix).') + copts.add_option( + '--rtems-tools', + default=None, + dest='rtems_tools', + help='Path to RTEMS tools (defaults to path to installed RTEMS).') + copts.add_option('--rtems-version', + default=None, + dest='rtems_version', + help='RTEMS version (default is derived from prefix).') + copts.add_option('--rtems-archs', + default='all', + dest='rtems_archs', + help='List of RTEMS architectures to build.') + copts.add_option('--rtems-bsps', + default='all', + dest='rtems_bsps', + help='List of BSPs to build.') + copts.add_option('--show-commands', + action='store_true', + default=False, + dest='show_commands', + help='Print the commands as strings.') + + +def init(ctx, filters=None, version=None, long_commands=False, bsp_init=None): global rtems_filters global rtems_default_version global rtems_long_commands @@ -119,11 +122,14 @@ def init(ctx, filters = None, version = None, long_commands = False, bsp_init = from waflib.Build import BuildContext, CleanContext, \ InstallContext, UninstallContext for x in arch_bsps: - for y in (BuildContext, CleanContext, InstallContext, UninstallContext): - name = y.__name__.replace('Context','').lower() + for y in (BuildContext, CleanContext, InstallContext, + UninstallContext): + name = y.__name__.replace('Context', '').lower() + class context(y): cmd = name + '-' + x variant = x + contexts += [context] # @@ -143,8 +149,9 @@ def init(ctx, filters = None, version = None, long_commands = False, bsp_init = if bsp_init: bsp_init(ctx, env, contexts) -def test_application(more = []): - code = ['#include <rtems.h>'] + +def test_application(more=[]): + code = ['#include <rtems.h>'] code += more code += ['void Init(rtems_task_argument arg) { (void)arg; }'] code += ['#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER'] @@ -154,15 +161,18 @@ def test_application(more = []): code += ['#include <rtems/confdefs.h>'] return os.linesep.join(code) -def configure(conf, bsp_configure = None): + +def configure(conf, bsp_configure=None): # # Check the environment for any flags. # - for f in ['CC', 'CXX', 'AS', 'LD', 'AR', 'LINK_CC', 'LINK_CXX', - 'CPPFLAGS', 'CFLAGS', 'CXXFLAGS', 'ASFLAGS', 'LINKFLAGS', 'LIB' - 'WFLAGS', 'RFLAGS', 'MFLAGS', 'IFLAGS']: + for f in [ + 'CC', 'CXX', 'AS', 'LD', 'AR', 'LINK_CC', 'LINK_CXX', 'CPPFLAGS', + 'CFLAGS', 'CXXFLAGS', 'ASFLAGS', 'LINKFLAGS', 'LIB' + 'WFLAGS', 'RFLAGS', 'MFLAGS', 'IFLAGS' + ]: if f in os.environ: - conf.msg('Environment variable set', f, color = 'RED') + conf.msg('Environment variable set', f, color='RED') # # Handle the configurable commands options. @@ -195,6 +205,7 @@ def configure(conf, bsp_configure = None): tools = {} env = conf.env.derive() + conf.env.RTEMS_ARCH_BSP_LIST = arch_bsps for ab in arch_bsps: conf.setenv(ab, env) @@ -211,7 +222,7 @@ def configure(conf, bsp_configure = None): conf.msg('Long commands', long_commands) arch = _arch_from_arch_bsp(ab) - bsp = _bsp_from_arch_bsp(ab) + bsp = _bsp_from_arch_bsp(ab) conf.env.ARCH_BSP = '%s/%s' % (arch.split('-')[0], bsp) @@ -229,7 +240,7 @@ def configure(conf, bsp_configure = None): conf.load('gcc') conf.load('g++') conf.load('gas') - conf.load('gccdeps', tooldir = os.path.dirname(__file__)) + conf.load('gccdeps', tooldir=os.path.dirname(__file__)) # # Get the version of the tools being used. @@ -238,7 +249,7 @@ def configure(conf, bsp_configure = None): try: import waflib.Context out = conf.cmd_and_log([rtems_cc, '--version'], - output = waflib.Context.STDOUT) + output=waflib.Context.STDOUT) except Exception as e: conf.fatal('CC version not found: %s' % (e.stderr)) # @@ -246,34 +257,34 @@ def configure(conf, bsp_configure = None): # vline = out.split('\n')[0] conf.msg('Compiler version (%s)' % (os.path.basename(rtems_cc)), - ' '.join(vline.split()[2:])) + ' '.join(vline.split()[2:])) flags = _load_flags(conf, ab, rtems_path) - cflags = _filter_flags('cflags', flags['CFLAGS'], - arch, rtems_path) - ldflags = _filter_flags('ldflags', flags['LDFLAGS'], - arch, rtems_path) - - conf.env.CFLAGS = cflags['cflags'] - conf.env.CXXFLAGS = cflags['cflags'] - conf.env.ASFLAGS = cflags['cflags'] - conf.env.WFLAGS = cflags['warnings'] - conf.env.RFLAGS = cflags['specs'] - conf.env.MFLAGS = cflags['machines'] - conf.env.IFLAGS = cflags['includes'] + cflags = _filter_flags('cflags', flags['CFLAGS'], arch, rtems_path) + ldflags = _filter_flags('ldflags', flags['LDFLAGS'], arch, rtems_path) + + conf.env.CFLAGS = cflags['cflags'] + conf.env.CXXFLAGS = cflags['cflags'] + conf.env.ASFLAGS = cflags['cflags'] + conf.env.WFLAGS = cflags['warnings'] + conf.env.RFLAGS = cflags['specs'] + conf.env.MFLAGS = cflags['machines'] + conf.env.IFLAGS = _filter_inc_opts(cflags['includes'], '-I') + conf.env.ISYSTEM = _filter_inc_opts(cflags['includes'], '-isystem') + conf.env.ISYSROOT = _filter_inc_opts(cflags['includes'], '-sysroot') conf.env.LINKFLAGS = cflags['cflags'] + ldflags['ldflags'] - conf.env.LIB = flags['LIB'] - conf.env.LIBPATH = ldflags['libpath'] + conf.env.LIB = flags['LIB'] + conf.env.LIBPATH = ldflags['libpath'] conf.env.RTRACE_WRAPPER_ST = '-W %s' # # Checks for various RTEMS features. # - conf.check_cc(fragment = test_application(), - execute = False, - msg = 'Checking for a valid RTEMS BSP installation') + conf.check_cc(fragment=test_application(), + execute=False, + msg='Checking for a valid RTEMS BSP installation') load_cpuopts(conf) # @@ -297,19 +308,19 @@ def configure(conf, bsp_configure = None): conf.env.SHOW_COMMANDS = show_commands conf.env.LONG_COMMANDS = long_commands + def build(bld): if bld.env.SHOW_COMMANDS == 'yes': output_command_line() if bld.env.LONG_COMMANDS == 'yes': long_command_line() + def load_cpuopts(conf): - options = ['RTEMS_DEBUG', - 'RTEMS_MULTIPROCESSING', - 'RTEMS_NEWLIB', - 'RTEMS_POSIX_API', - 'RTEMS_SMP', - 'RTEMS_NETWORKING'] + options = [ + 'RTEMS_DEBUG', 'RTEMS_MULTIPROCESSING', 'RTEMS_NEWLIB', + 'RTEMS_POSIX_API', 'RTEMS_SMP', 'RTEMS_NETWORKING' + ] for opt in options: enabled = check_cpuopt(conf, opt) if enabled: @@ -317,23 +328,24 @@ def load_cpuopts(conf): else: conf.env[opt] = 'No' + def check(conf, *k, **kw): if 'fragment' not in kw: kw['fragment'] = test_application() conf.check(k, kw) + def check_cc(conf, *k, **kw): if 'fragment' not in kw: kw['fragment'] = test_application() conf.check_cc(*k, **kw) -def check_lib_path(ctx, lib, libpath = [], mandatory = True): + +def check_lib_path(ctx, lib, libpath=[], mandatory=True): lib_lib = 'lib%s.a' % (lib) ctx.start_msg('Library %s' % (lib_lib)) - cmd = '%s %s %s -print-file-name=%s' % (' '.join(ctx.env.CC), - ' '.join(ctx.env.CFLAGS), - ' '.join(['-B' + l for l in libpath]), - lib_lib) + cmd = '%s %s %s -print-file-name=%s' % (' '.join(ctx.env.CC), ' '.join( + ctx.env.CFLAGS), ' '.join(['-B' + l for l in libpath]), lib_lib) out = ctx.cmd_and_log(cmd) out = os.path.normpath(out.strip()) if out == lib_lib: @@ -341,9 +353,11 @@ def check_lib_path(ctx, lib, libpath = [], mandatory = True): ctx.fatal('The library %s not found' % (lib_lib)) ctx.end_msg('not found') else: - ctx.env['LIBPATH_lib%s' % (lib)] = '..' + '/..' * (ctx.path.height() - 1) + out + ctx.env['LIBPATH_lib%s' % + (lib)] = '..' + '/..' * (ctx.path.height() - 1) + out ctx.end_msg('found') + def check_lib(ctx, libs): if not isinstance(libs, list): lib = [libs] @@ -352,8 +366,9 @@ def check_lib(ctx, libs): return False return True + def check_cpuopt(conf, opt): - code = ['#ifndef %s' % (opt)] + code = ['#ifndef %s' % (opt)] code += [' #error %s is not defined' % (opt)] code += ['#endif'] code += ['#if %s' % (opt)] @@ -362,13 +377,14 @@ def check_cpuopt(conf, opt): code += [' #error %s is false' % (opt)] code += ['#endif'] try: - conf.check_cc(fragment = test_application(code), - execute = False, - msg = 'Checking for %s' % (opt)) + conf.check_cc(fragment=test_application(code), + execute=False, + msg='Checking for %s' % (opt)) except conf.errors.WafError: - return False; + return False return True + def tweaks(conf, arch_bsp): # # Hack to work around NIOS2 naming. @@ -387,9 +403,11 @@ def tweaks(conf, arch_bsp): conf.env.LINKFLAGS += ['-Wl,-Ttext,0x00100000'] if '-ffunction-sections' in conf.env.CFLAGS: - conf.env.LINKFLAGS += ['-Wl,--gc-sections'] + conf.env.LINKFLAGS += ['-Wl,--gc-sections'] + -def check_options(ctx, prefix, rtems_tools, rtems_path, rtems_version, rtems_archs, rtems_bsps): +def check_options(ctx, prefix, rtems_tools, rtems_path, rtems_version, + rtems_archs, rtems_bsps): # # Set defaults # @@ -399,7 +417,8 @@ def check_options(ctx, prefix, rtems_tools, rtems_path, rtems_version, rtems_arc if m: rtems_version = m.group(1) else: - ctx.fatal('RTEMS version cannot derived from prefix: ' + prefix) + ctx.fatal('RTEMS version cannot derived from prefix: ' + + prefix) else: rtems_version = rtems_default_version if rtems_path is None: @@ -417,10 +436,13 @@ def check_options(ctx, prefix, rtems_tools, rtems_path, rtems_version, rtems_arc elif os.path.exists(os.path.join(rtems_path, 'rtems-config')): rtems_config = os.path.join(rtems_path, 'rtems-config') else: - ctx.fatal('RTEMS path is not valid. No lib/pkgconfig or rtems-config found.') - rtems_share_rtems_version = os.path.join(rtems_path, 'share', 'rtems' + rtems_version) + ctx.fatal( + 'RTEMS path is not valid. No lib/pkgconfig or rtems-config found.') + rtems_share_rtems_version = os.path.join(rtems_path, 'share', + 'rtems' + rtems_version) if not os.path.exists(os.path.join(rtems_share_rtems_version)): - ctx.fatal('RTEMS path is not valid, "%s" not found.' % (rtems_share_rtems_version)) + ctx.fatal('RTEMS path is not valid, "%s" not found.' % + (rtems_share_rtems_version)) # # We can more than one path to tools. This happens when testing different @@ -432,7 +454,9 @@ def check_options(ctx, prefix, rtems_tools, rtems_path, rtems_version, rtems_arc if not os.path.exists(path): ctx.fatal('RTEMS tools path not found: ' + path) if not os.path.exists(os.path.join(path, 'bin')): - ctx.fatal('RTEMS tools path does not contain a \'bin\' directory: ' + path) + ctx.fatal( + 'RTEMS tools path does not contain a \'bin\' directory: ' + + path) tools += [os.path.join(path, 'bin')] # @@ -447,7 +471,8 @@ def check_options(ctx, prefix, rtems_tools, rtems_path, rtems_version, rtems_arc if rtems_archs == 'all': archs = _find_installed_archs(rtems_config, rtems_path, rtems_version) else: - archs = _check_archs(rtems_config, rtems_archs, rtems_path, rtems_version) + archs = _check_archs(rtems_config, rtems_archs, rtems_path, + rtems_version) # # Filter the architectures. @@ -465,9 +490,11 @@ def check_options(ctx, prefix, rtems_tools, rtems_path, rtems_version, rtems_arc # to those referenced by the BSPs. # if rtems_bsps == 'all': - arch_bsps = _find_installed_arch_bsps(rtems_config, rtems_path, archs, rtems_version) + arch_bsps = _find_installed_arch_bsps(rtems_config, rtems_path, archs, + rtems_version) else: - arch_bsps = _check_arch_bsps(rtems_bsps, rtems_config, rtems_path, archs, rtems_version) + arch_bsps = _check_arch_bsps(rtems_bsps, rtems_config, rtems_path, + archs, rtems_version) if len(arch_bsps) == 0: ctx.fatal('No valid arch/bsps found') @@ -479,52 +506,69 @@ def check_options(ctx, prefix, rtems_tools, rtems_path, rtems_version, rtems_arc return rtems_version, rtems_path, tools, archs, arch_bsps + def check_env(ctx, *env_vars): for v in env_vars: if v not in ctx.env or len(ctx.env[v]) == 0: return False return True -def check(ctx, option, setting = 'Yes'): + +def check(ctx, option, setting='Yes'): if option in ctx.env: if isinstance(setting, bool): return True return ctx.env[option] == setting return False + def check_debug(ctx): return check(ctx, 'RTEMS_DEBUG') + def check_multiprocessing(ctx): return check(ctx, 'RTEMS_MULTIPROCESSING') + def check_newlib(ctx): return check(ctx, 'RTEMS_NEWLIB') + def check_posix(ctx): return check(ctx, 'RTEMS_POSIX_API') + def check_smp(ctx): return check(ctx, 'RTEMS_SMP') + def check_networking(ctx): return check(ctx, 'RTEMS_NETWORKING') + def arch(arch_bsp): """ Given an arch/bsp return the architecture.""" return _arch_from_arch_bsp(arch_bsp).split('-')[0] + def bsp(arch_bsp): """ Given an arch/bsp return the BSP.""" return _bsp_from_arch_bsp(arch_bsp) + +def arch_bsp_name(arch_bsp): + return arch(arch_bsp) + '/' + bsp(arch_bsp) + + def arch_bsps(ctx): """ Return the list of arch/bsps we are building.""" return ctx.env.ARCH_BSPS + def arch_bsp_env(ctx, arch_bsp): return ctx.env_of_name(arch_bsp).derive() + def filter(ctx, filter, items): if rtems_filters is None: return items @@ -560,22 +604,28 @@ def filter(ctx, filter, items): ctx.fatal('Following %s not found: %s' % (filter, ', '.join(items_in))) return sorted(filtered_items) + def arch_rtems_version(version, arch): """ Return the RTEMS architecture path, ie sparc-rtems4.11.""" return '%s-rtems%s' % (arch, version) + def arch_bsp_path(version, arch_bsp): """ Return the BSP path.""" - return '%s/%s' % (arch_rtems_version(version, arch(arch_bsp)), bsp(arch_bsp)) + return '%s/%s' % (arch_rtems_version(version, + arch(arch_bsp)), bsp(arch_bsp)) + def arch_bsp_include_path(version, arch_bsp): """ Return the BSP include path.""" return '%s/lib/include' % (arch_bsp_path(version, arch_bsp)) + def arch_bsp_lib_path(version, arch_bsp): """ Return the BSP library path. """ return '%s/lib' % (arch_bsp_path(version, arch_bsp)) + def library_path(library, cc, cflags): cmd = cc + cflags + ['-print-file-name=%s' % library] a = subprocess.check_output(cmd) @@ -584,18 +634,19 @@ def library_path(library, cc, cflags): return os.path.dirname(lib) return None + def root_filesystem(bld, name, files, tar, obj): tar_rule = 'tar -cf ${TGT} --format=ustar -C ../.. $(echo "${SRC}" | sed -e \'s/\.\.\/\.\.\///g\')' if windows: tar_rule = 'sh -c "%s"' % (tar_rule) - bld(name = name + '_tar', - target = tar, - source = files, - rule = tar_rule) - bld.objects(name = name, - target = obj, - source = tar, - rule = '${OBJCOPY} -I binary -B ${RTEMS_ARCH} ${OBJCOPY_FLAGS} ${SRC} ${TGT}') + bld(name=name + '_tar', target=tar, source=files, rule=tar_rule) + bld.objects( + name=name, + target=obj, + source=tar, + rule= + '${OBJCOPY} -I binary -B ${RTEMS_ARCH} ${OBJCOPY_FLAGS} ${SRC} ${TGT}') + def clone_tasks(bld): if bld.cmd == 'build': @@ -607,6 +658,7 @@ def clone_tasks(bld): cloned_obj.posted = True obj.posted = True + # # From the demos. Use this to get the command to cut+paste to play. # @@ -614,6 +666,7 @@ def output_command_line(): # first, display strings, people like them from waflib import Utils, Logs from waflib.Context import Context + def exec_command(self, cmd, **kw): subprocess = Utils.subprocess kw['shell'] = isinstance(cmd, str) @@ -621,7 +674,7 @@ def output_command_line(): Logs.info('%s' % cmd) else: cmdstr = ' '.join(cmd) - Logs.info('(%d) %s' % (len(cmdstr), cmdstr)) # here is the change + Logs.info('(%d) %s' % (len(cmdstr), cmdstr)) # here is the change if not isinstance(kw['cwd'], str): kw['cwd'] = str(kw['cwd']) Logs.debug('runner_env: kw=%s' % kw) @@ -632,28 +685,36 @@ def output_command_line(): p = subprocess.Popen(cmd, **kw) (out, err) = p.communicate() if out: - self.logger.debug('out: %s' % out.decode(sys.stdout.encoding or 'iso8859-1')) + self.logger.debug( + 'out: %s' % + out.decode(sys.stdout.encoding or 'iso8859-1')) if err: - self.logger.error('err: %s' % err.decode(sys.stdout.encoding or 'iso8859-1')) + self.logger.error( + 'err: %s' % + err.decode(sys.stdout.encoding or 'iso8859-1')) return p.returncode else: p = subprocess.Popen(cmd, **kw) return p.wait() except OSError: return -1 + Context.exec_command = exec_command # Change the outputs for tasks too from waflib.Task import Task + def display(self): - return '' # no output on empty strings + return '' # no output on empty strings Task.__str__ = display + # # From the extras. Use this to support long command lines. # def long_command_line(): + def exec_command(self, cmd, **kw): # workaround for command line length limit: # http://support.microsoft.com/kb/830473 @@ -661,8 +722,12 @@ def long_command_line(): tmp = None try: if not isinstance(cmd, str) and len(str(cmd)) > 8192: - (fd, tmp) = tempfile.mkstemp(dir=self.generator.bld.bldnode.abspath()) - flat = ['"%s"' % x.replace('\\', '\\\\').replace('"', '\\"') for x in cmd[1:]] + (fd, tmp) = tempfile.mkstemp( + dir=self.generator.bld.bldnode.abspath()) + flat = [ + '"%s"' % x.replace('\\', '\\\\').replace('"', '\\"') + for x in cmd[1:] + ] try: os.write(fd, ' '.join(flat).encode()) finally: @@ -676,42 +741,55 @@ def long_command_line(): if tmp: os.remove(tmp) return ret - for k in 'c cxx cprogram cxxprogram cshlib cxxshlib cstlib cxxstlib'.split(): + + for k in 'c cxx cprogram cxxprogram cshlib cxxshlib cstlib cxxstlib'.split( + ): cls = Task.classes.get(k) if cls: - derived_class = type(k, (cls,), {}) + derived_class = type(k, (cls, ), {}) derived_class.exec_command = exec_command if hasattr(cls, 'hcode'): derived_class.hcode = cls.hcode + def _find_tools(conf, arch, paths, tools): if arch not in tools: arch_tools = {} - arch_tools['CC'] = conf.find_program([arch + '-gcc'], path_list = paths) - arch_tools['CXX'] = conf.find_program([arch + '-g++'], path_list = paths) - arch_tools['LINK_CC'] = arch_tools['CC'] - arch_tools['LINK_CXX'] = arch_tools['CXX'] - arch_tools['AS'] = conf.find_program([arch + '-gcc'], path_list = paths) - arch_tools['LD'] = conf.find_program([arch + '-ld'], path_list = paths) - arch_tools['AR'] = conf.find_program([arch + '-ar'], path_list = paths) - arch_tools['NM'] = conf.find_program([arch + '-nm'], path_list = paths) - arch_tools['OBJDUMP'] = conf.find_program([arch + '-objdump'], path_list = paths) - arch_tools['OBJCOPY'] = conf.find_program([arch + '-objcopy'], path_list = paths) - arch_tools['READELF'] = conf.find_program([arch + '-readelf'], path_list = paths) - arch_tools['STRIP'] = conf.find_program([arch + '-strip'], path_list = paths) - arch_tools['RANLIB'] = conf.find_program([arch + '-ranlib'], path_list = paths) - arch_tools['RTEMS_LD'] = conf.find_program(['rtems-ld'], path_list = paths, - mandatory = False) - arch_tools['RTEMS_TLD'] = conf.find_program(['rtems-tld'], path_list = paths, - mandatory = False) - arch_tools['RTEMS_SYMS'] = conf.find_program(['rtems-syms'], path_list = paths, - mandatory = False) - arch_tools['RTEMS_BIN2C'] = conf.find_program(['rtems-bin2c'], path_list = paths, - mandatory = False) - arch_tools['TAR'] = conf.find_program(['tar'], mandatory = False) + arch_tools['CC'] = conf.find_program([arch + '-gcc'], path_list=paths) + arch_tools['CXX'] = conf.find_program([arch + '-g++'], path_list=paths) + arch_tools['LINK_CC'] = arch_tools['CC'] + arch_tools['LINK_CXX'] = arch_tools['CXX'] + arch_tools['AS'] = conf.find_program([arch + '-gcc'], path_list=paths) + arch_tools['LD'] = conf.find_program([arch + '-ld'], path_list=paths) + arch_tools['AR'] = conf.find_program([arch + '-ar'], path_list=paths) + arch_tools['NM'] = conf.find_program([arch + '-nm'], path_list=paths) + arch_tools['OBJDUMP'] = conf.find_program([arch + '-objdump'], + path_list=paths) + arch_tools['OBJCOPY'] = conf.find_program([arch + '-objcopy'], + path_list=paths) + arch_tools['READELF'] = conf.find_program([arch + '-readelf'], + path_list=paths) + arch_tools['STRIP'] = conf.find_program([arch + '-strip'], + path_list=paths) + arch_tools['RANLIB'] = conf.find_program([arch + '-ranlib'], + path_list=paths) + arch_tools['RTEMS_LD'] = conf.find_program(['rtems-ld'], + path_list=paths, + mandatory=False) + arch_tools['RTEMS_TLD'] = conf.find_program(['rtems-tld'], + path_list=paths, + mandatory=False) + arch_tools['RTEMS_SYMS'] = conf.find_program(['rtems-syms'], + path_list=paths, + mandatory=False) + arch_tools['RTEMS_BIN2C'] = conf.find_program(['rtems-bin2c'], + path_list=paths, + mandatory=False) + arch_tools['TAR'] = conf.find_program(['tar'], mandatory=False) tools[arch] = arch_tools return tools + def _find_installed_archs(config, path, version): archs = [] if config is None: @@ -726,6 +804,7 @@ def _find_installed_archs(config, path, version): archs.sort() return archs + def _check_archs(config, req, path, version): installed = _find_installed_archs(config, path, version) archs = [] @@ -736,6 +815,7 @@ def _check_archs(config, req, path, version): archs.sort() return archs + def _find_installed_arch_bsps(config, path, archs, version): arch_bsps = [] if config is None: @@ -751,6 +831,7 @@ def _find_installed_arch_bsps(config, path, archs, version): arch_bsps.sort() return arch_bsps + def _check_arch_bsps(req, config, path, archs, version): archs_bsps = [] for ab in req.split(','): @@ -776,15 +857,27 @@ def _check_arch_bsps(req, config, path, archs, version): bsps.sort() return bsps + def _arch_from_arch_bsp(arch_bsp): - return '-'.join(arch_bsp.split('-')[:2]) + fields = arch_bsp.split('-') + for i, field in enumerate(fields): + if field.startswith('rtems') and fields[:(i + 1)] is not None: + return '-'.join(fields[:(i + 1)]) + return None + def _bsp_from_arch_bsp(arch_bsp): - return '-'.join(arch_bsp.split('-')[2:]) + fields = arch_bsp.split('-') + for i, field in enumerate(fields): + if field.startswith('rtems') and fields[(i + 1):] is not None: + return '-'.join(fields[(i + 1):]) + return None + def _pkgconfig_path(path): return os.path.join(path, 'lib', 'pkgconfig') + def _load_flags(conf, arch_bsp, path): if not os.path.exists(path): ctx.fatal('RTEMS path not found.') @@ -808,6 +901,7 @@ def _load_flags(conf, arch_bsp, path): flags['CFLAGS'] += ['-MMD'] return flags + def _load_flags_set(flags, arch_bsp, conf, config, pkg): conf.to_log('%s ->' % flags) if pkg is not None: @@ -818,9 +912,11 @@ def _load_flags_set(flags, arch_bsp, conf, config, pkg): conf.to_log('pkconfig warning: ' + e.msg) conf.to_log(' ' + flagstr) else: - flags_map = { 'CFLAGS': '--cflags', - 'LDFLAGS': '--ldflags', - 'LIB': '--libs' } + flags_map = { + 'CFLAGS': '--cflags', + 'LDFLAGS': '--ldflags', + 'LIB': '--libs' + } ab = arch_bsp.split('-') #conf.check_cfg(path = config, # package = '', @@ -829,7 +925,9 @@ def _load_flags_set(flags, arch_bsp, conf, config, pkg): #print conf.env #print '%r' % conf #flagstr = '-l -c' - flagstr = subprocess.check_output([config, '--bsp', '%s/%s' % (ab[0], ab[2]), flags_map[flags]]) + flagstr = subprocess.check_output( + [config, '--bsp', + '%s/%s' % (ab[0], ab[2]), flags_map[flags]]) #print flags, ">>>>", flagstr if flags == 'CFLAGS': flagstr += ' -DWAF_BUILD=1' @@ -837,6 +935,16 @@ def _load_flags_set(flags, arch_bsp, conf, config, pkg): flagstr = 'rtemscpu rtemsbsp c rtemscpu rtemsbsp' return flagstr.split() + +def _filter_inc_opts(incpaths, incopt): + paths = [] + for ip in incpaths: + if ip.startswith(incopt): + paths += [ip[len(incopt):]] + break + return paths + + def _filter_flags(label, flags, arch, rtems_path): flag_groups = \ @@ -849,7 +957,7 @@ def _filter_flags(label, flags, arch, rtems_path): flags = _strip_cflags(flags) - _flags = { label: [] } + _flags = {label: []} for fg in flag_groups: _flags[fg['key']] = [] @@ -883,6 +991,7 @@ def _filter_flags(label, flags, arch, rtems_path): _flags[label] += opts return _flags + def _strip_cflags(cflags): _cflags = [] for o in cflags: @@ -894,9 +1003,11 @@ def _strip_cflags(cflags): _cflags += [o] return _cflags + def _log_header(conf): conf.to_log('-----------------------------------------') + def _get_dir_hash(bld): from waflib import ConfigSet, Options import hashlib @@ -923,6 +1034,7 @@ def _get_dir_hash(bld): f1.close() return shahash.hexdigest() + def test_uninstall(bld): from os import sys @@ -943,6 +1055,7 @@ def test_uninstall(bld): else: print("Test failed") + from waflib import Task from waflib import TaskGen from waflib import Utils @@ -950,19 +1063,25 @@ from waflib import Node from waflib.Tools.ccroot import link_task, USELIB_VARS USELIB_VARS['rap'] = set(['RTEMS_LINKFLAGS']) -USELIB_VARS['rtrace'] = set(['RTRACE_FLAGS', 'RTRACE_CFG', 'RTRACE_WRAPPER', 'RTRACE_LINKCMDS']) +USELIB_VARS['rtrace'] = set( + ['RTRACE_FLAGS', 'RTRACE_CFG', 'RTRACE_WRAPPER', 'RTRACE_LINKCMDS']) + class rap(link_task): "Link object files into a RTEMS application" run_str = '${RTEMS_LD} ${RTEMS_LINKFLAGS} --cc ${CC} ${SRC} -o ${TGT[0].abspath()} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB}' ext_out = ['.rap'] - vars = ['RTEMS_LINKFLAGS', 'LINKDEPS'] + vars = ['RTEMS_LINKFLAGS', 'LINKDEPS'] inst_to = '${BINDIR}' + class rtrace(link_task): "Link object files into a RTEMS trace application" run_str = '${RTEMS_TLD} ${RTACE_FLAGS} ${RTRACE_WRAPPER_ST:RTRACE_WRAPPER} -C ${RTRACE_CFG} -r ${RTEMS_PATH} -B ${ARCH_BSP} -c ${CC} -l ${CC} -- ${SRC} ${LINKFLAGS} ${RTRACE_LINKFLAGS} -o ${TGT[0].abspath()} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB}' ext_out = ['.texe'] - vars = ['RTRACE_FLAGS', 'RTRACE_CFG', 'RTRACE_WRAPER', 'RTRACE_LINKFLAGS', 'LINKDEPS'] + vars = [ + 'RTRACE_FLAGS', 'RTRACE_CFG', 'RTRACE_WRAPER', 'RTRACE_LINKFLAGS', + 'LINKDEPS' + ] inst_to = '${BINDIR}' color = 'PINK' diff --git a/rtems_bsd.py b/rtems_bsd.py index f28ef1c..8faae10 100644 --- a/rtems_bsd.py +++ b/rtems_bsd.py @@ -35,21 +35,24 @@ except: import sys sys.exit(1) + def init(ctx): pass + def options(opt): opt.add_option('--net-config', - default = 'config.inc', - dest = 'net_config', - help = 'Network test configuration.') + default='config.inc', + dest='net_config', + help='Network test configuration.') opt.add_option('--rtems-libbsd', - action = 'store', - default = None, - dest = 'rtems_libbsd', - help = 'Path to install RTEMS LibBSD (defauls to prefix).') + action='store', + default=None, + dest='rtems_libbsd', + help='Path to install RTEMS LibBSD (defauls to prefix).') -def bsp_configure(conf, arch_bsp, mandatory = True): + +def bsp_configure(conf, arch_bsp, mandatory=True): configure = mandatory if not mandatory and conf.options.rtems_libbsd is not None: @@ -57,10 +60,9 @@ def bsp_configure(conf, arch_bsp, mandatory = True): if configure: conf.msg('RTEMS LibBSD', - rtems.arch(arch_bsp) + '/' + rtems.bsp(arch_bsp), - 'YELLOW') + rtems.arch(arch_bsp) + '/' + rtems.bsp(arch_bsp), 'YELLOW') - conf.check(header_name = 'dlfcn.h', features = 'c') + conf.check(header_name='dlfcn.h', features='c') if not rtems.check_posix(conf): conf.fatal('RTEMS kernel POSIX support is disabled; ' + 'configure RTEMS with --enable-posix') @@ -69,25 +71,27 @@ def bsp_configure(conf, arch_bsp, mandatory = True): 'configure RTEMS with --disable-networking') rtems_libbsd_path = conf.options.rtems_libbsd if rtems_libbsd_path is None: - if conf.options.rtems is None: - rtems_libbsd_path = conf.options.rtems + if conf.options.rtems_path is not None: + rtems_libbsd_path = conf.options.rtems_path else: rtems_libbsd_path = conf.env.PREFIX if not os.path.exists(rtems_libbsd_path): - conf.fatal('RTEMS LibBSD path not found: %s' % (rtems_libbsd_path)) + conf.fatal('RTEMS LibBSD path not found: %s' % (rtems_libbsd_path)) - rtems_libbsd_inc_path = os.path.join(rtems_libbsd_path, - rtems.arch_bsp_include_path(conf.env.RTEMS_VERSION, - conf.env.RTEMS_ARCH_BSP)) - rtems_libbsd_lib_path = os.path.join(rtems_libbsd_path, - rtems.arch_bsp_lib_path(conf.env.RTEMS_VERSION, - conf.env.RTEMS_ARCH_BSP)) + rtems_libbsd_inc_path = os.path.join( + rtems_libbsd_path, + rtems.arch_bsp_include_path(conf.env.RTEMS_VERSION, + conf.env.RTEMS_ARCH_BSP)) + rtems_libbsd_lib_path = os.path.join( + rtems_libbsd_path, + rtems.arch_bsp_lib_path(conf.env.RTEMS_VERSION, + conf.env.RTEMS_ARCH_BSP)) conf.env.IFLAGS += [rtems_libbsd_inc_path] - conf.check(header_name = 'machine/rtems-bsd-sysinit.h', - features = 'c', - includes = conf.env.IFLAGS) + conf.check(header_name='machine/rtems-bsd-sysinit.h', + features='c', + includes=conf.env.IFLAGS) conf.env.RTEMS_LIBBSD = 'Yes' conf.env.INCLUDES = conf.env.IFLAGS @@ -96,6 +100,7 @@ def bsp_configure(conf, arch_bsp, mandatory = True): configure_net_config(conf, arch_bsp) + def configure_net_config(conf, arch_bsp): if check_libbsd(conf) and conf.options.net_config is not None: net_config = conf.options.net_config @@ -106,12 +111,13 @@ def configure_net_config(conf, arch_bsp): try: net_cfg_lines = open(net_config).readlines() except: - conf.fatal('network configuraiton \'%s\' read failed' % (net_config)) + conf.fatal('network configuraiton \'%s\' read failed' % + (net_config)) - tags = [ 'NET_CFG_SELF_IP', - 'NET_CFG_NETMASK', - 'NET_CFG_PEER_IP', - 'NET_CFG_GATEWAY_IP' ] + tags = [ + 'NET_CFG_SELF_IP', 'NET_CFG_NETMASK', 'NET_CFG_PEER_IP', + 'NET_CFG_GATEWAY_IP' + ] lc = 0 sed = 'sed ' @@ -137,14 +143,17 @@ def configure_net_config(conf, arch_bsp): conf.msg('Net Config', 'found', 'YELLOW') + def check_libbsd(ctx): return rtems.check(ctx, 'RTEMS_LIBBSD') + def check_net_config(ctx): - return rtems.check(ctx, 'NET_CONFIG', setting = True) + return rtems.check(ctx, 'NET_CONFIG', setting=True) + def net_config_header(ctx, target): - ctx(target = target, - source = "rtems_waf/network-config.h.in", - rule = sed + " < ${SRC} > ${TGT}", - update_outputs = True) + ctx(target=target, + source="rtems_waf/network-config.h.in", + rule=sed + " < ${SRC} > ${TGT}", + update_outputs=True) diff --git a/version.py b/version.py new file mode 100644 index 0000000..6565074 --- /dev/null +++ b/version.py @@ -0,0 +1,272 @@ +# +# RTEMS Tools Project (http://www.rtems.org/) +# Copyright 2010-2018,2023 Chris Johns (chrisj@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. +# + +# +# Releasing RTEMS Tools +# --------------------- +# +# Format: +# +# The format is INI. The file requires a `[version`] section and a `revision` +# option: +# +# [version] +# revision = <version-string> +# +# The `<version-string>` has the `version` and `revision` delimited by a +# single `.`. An example file is: +# +# [version] +# revision = 5.0.not_released +# +# where the `version` is `5` and the revision is `0` and the package is not +# released. The label `not_released` is reversed to mean the package is not +# released. A revision string can contain extra characters after the +# `revision` number for example `5.0-rc1` or is deploying a package +# `5.0-nasa-cfs` +# +# Packages can optionally add specialised sections to a version configuration +# files. These can be accessed via the: +# +# load_release_settings: Return the items in a section +# load_release_setting: Return an item from a section +# +# User deployment: +# +# Create a git archive and then add a suitable VERSION file to the top +# directory of the package. The package assumes your python executable is +# location in `bin` directory which is one below the top of the package's +# install prefix. +# +# RTEMS Release: +# +# Set the values in the `rtems-version.ini` file. This is a shared file so +# packages and encouraged to add specific settings to other configuration +# files. +# +# Notes: +# +# This module uses os.apth for paths and assumes all paths are in the host +# format. +# + +from __future__ import print_function + +import itertools +import os +import sys + +try: + import configparser +except ImportError: + import ConfigParser as configparser + +from . import git +from . import rtems + +# +# Default to an internal string. +# +_version = 'undefined' +_revision = 'not_released' +_version_str = '%s.%s' % (_version, _revision) +_released = False +_git = False +_is_loaded = False + + +def _top(ctx): + top = ctx.path + if top == None: + cts.fatal('no top path found') + return str(top) + + +def _load_released_version_config(ctx): + '''Local worker to load a configuration file.''' + top = _top(ctx) + for ver in [os.path.join(top, 'VERSION')]: + if os.path.exists(os.path.join(ver)): + v = configparser.SafeConfigParser() + try: + v.read(os.path.host(ver)) + except Exception as e: + raise ctx.fatal('invalid version config format: %s: %s' % + (ver, e)) + return ver, v + return None, None + + +def _load_released_version(ctx): + '''Load the release data if present. If not found the package is not + released. + + A release can be made by adding a file called `VERSION` to the top level + directory of a package. This is useful for user deploying a package and + making custom releases. + ''' + global _version + global _revision + global _released + global _version_str + global _is_loaded + + if not _is_loaded: + vc, v = _load_released_version_config(ctx) + if v is not None: + try: + ver_str = v.get('version', 'revision') + except Exception as e: + raise ctx.fatal('invalid version file: %s: %s' % (vc, e)) + ver_split = ver_str.split('.') + if len(ver_split) < 2: + raise ctx.fatal('invalid version release value: %s: %s' % + (vc, ver_str)) + ver = ver_split[0] + rev = '.'.join(ver_split[1:]) + try: + _version = int(ver) + except: + raise ctx.fatal('invalid version config value: %s: %s' % + (vc, ver)) + try: + _revision = int(''.join( + itertools.takewhile(str.isdigit, str(rev)))) + except Exception as e: + raise ctx.fatal('Invalid revision config value: %s: %s: %s' % + (vc, rev, e)) + if not 'not_released' in ver: + _released = True + _version_str = ver_str + _is_loaded = True + return _released + + +def _load_git_version(ctx): + global _version + global _revision + global _git + global _version_str + repo = git.repo(ctx, _top(ctx)) + if repo.valid(): + head = repo.head() + if repo.dirty(): + modified = 'modified' + revision_sep = '-' + sep = ' ' + else: + modified = '' + revision_sep = '' + sep = '' + _revision = '%s%s%s' % (head[0:12], revision_sep, modified) + _version_str += ' (%s%s%s)' % (head[0:12], sep, modified) + _git = True + return _git + + +def load_release_settings(ctx, section, error=False): + vc, v = _load_released_version_config(ctx) + items = [] + if v is not None: + try: + items = v.items(section) + except Exception as e: + if not isinstance(error, bool): + error(e) + elif error: + raise ctx.fatal('Invalid config section: %s: %s: %s' % + (vc, section, e)) + return items + + +def load_release_setting(ctx, section, option, raw=False, error=False): + vc, v = _load_released_version_config() + value = None + if v is not None: + try: + value = v.get(section, option, raw=raw) + except Exception as e: + if not isinstance(error, bool): + error(e) + elif error: + raise ctx.fatal('Invalid config section: %s: %s: %s.%s' % + (vc, section, option, e)) + return value + + +def load_rtems_version_header(ctx, rtems_version, arch_bsp, incpaths): + global _version + global _revision + global _version_str + for inc in incpaths: + header = os.path.join(inc, 'rtems/score/cpuopts.h') + if os.path.exists(header): + try: + with open(header, 'r') as h: + text = h.readlines() + except: + ctx.fatal('cannot read: ' + header) + for l in text: + ls = l.split() + if len(ls) == 3: + if ls[1] == '__RTEMS_MAJOR__': + _version = int(ls[2]) + elif ls[1] == '__RTEMS_REVISION__': + _revision = int(ls[2]) + elif ls[1] == 'RTEMS_VERSION': + _version_str = ls[2][1:-1] + _is_loaded = True + break + + +def released(ctx): + return _load_released_version(ctx) + + +def version_control(ctx): + return _load_git_version(ctx) + + +def string(ctx): + _load_released_version(ctx) + _load_git_version(ctx) + return _version_str + + +def version(ctx): + _load_released_version(ctx) + _load_git_version(ctx) + return _version + + +def revision(ctx): + _load_released_version(ctx) + _load_git_version(ctx) + return _revision |