# Copyright 2012-2016 Chris Johns (chrisj@rtems.org) # # 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 # # RTEMS support for applications. # import copy import os import os.path from . import pkgconfig import re import subprocess import sys rtems_default_version = None rtems_filters = None 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): global rtems_filters global rtems_default_version global rtems_long_commands # # Set the RTEMS filter to the context. # rtems_filters = filters # # Set the default version, can be overridden. # rtems_default_version = version # # Set the long commands option. # rtems_long_commands = long_commands try: import waflib.Options import waflib.ConfigSet # # Load the configuation set from the lock file. # env = waflib.ConfigSet.ConfigSet() env.load(waflib.Options.lockfile) # # Check the tools, architectures and bsps. # rtems_version, rtems_path, rtems_bin, rtems_tools, archs, arch_bsps = \ check_options(ctx, env.options['prefix'], env.options['rtems_tools'], env.options['rtems_path'], env.options['rtems_version'], env.options['rtems_archs'], env.options['rtems_bsps']) # # Update the contexts for all the bsps. # from waflib.Build import BuildContext, CleanContext, \ InstallContext, UninstallContext contexts = [] for x in arch_bsps: for y in (BuildContext, CleanContext, InstallContext, UninstallContext): name = y.__name__.replace('Context','').lower() class context(y): cmd = name + '-' + x variant = x contexts += [context] # # Transform the command to per BSP commands. # commands = [] for cmd in waflib.Options.commands: if cmd in ['build', 'clean', 'install']: for x in arch_bsps: commands += [cmd + '-' + x] else: commands += [cmd] waflib.Options.commands = commands except: pass if bsp_init: bsp_init(ctx, env, contexts) 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']: if f in os.environ: conf.msg('Environment variable set', f, color = 'RED') # # Handle the configurable commands options. # if conf.options.show_commands: show_commands = 'yes' else: show_commands = 'no' if rtems_long_commands and windows: long_commands = 'yes' else: long_commands = 'no' rtems_version, rtems_path, rtems_bin, rtems_tools, archs, arch_bsps = \ check_options(conf, conf.options.prefix, conf.options.rtems_tools, conf.options.rtems_path, conf.options.rtems_version, conf.options.rtems_archs, conf.options.rtems_bsps) if rtems_tools is None: conf.fatal('RTEMS tools not found.') _log_header(conf) conf.msg('RTEMS Version', rtems_version, 'YELLOW') conf.msg('Architectures', ', '.join(archs), 'YELLOW') tools = {} env = conf.env.derive() for ab in arch_bsps: conf.setenv(ab, env) conf.msg('Board Support Package', ab, 'YELLOW') # # Show and long commands support. # conf.env.SHOW_COMMANDS = show_commands conf.env.LONG_COMMANDS = long_commands conf.msg('Show commands', show_commands) conf.msg('Long commands', long_commands) arch = _arch_from_arch_bsp(ab) bsp = _bsp_from_arch_bsp(ab) conf.env.ARCH_BSP = '%s/%s' % (arch.split('-')[0], bsp) conf.env.RTEMS_PATH = rtems_path conf.env.RTEMS_VERSION = rtems_version conf.env.RTEMS_ARCH_BSP = ab conf.env.RTEMS_ARCH = arch.split('-')[0] conf.env.RTEMS_ARCH_RTEMS = arch conf.env.RTEMS_BSP = bsp tools = _find_tools(conf, arch, [rtems_bin] + rtems_tools, tools) for t in tools[arch]: conf.env[t] = tools[arch][t] conf.load('gcc') conf.load('g++') conf.load('gas') # # Get the version of the tools being used. # rtems_cc = conf.env.CC[0] try: import waflib.Context out = conf.cmd_and_log([rtems_cc, '--version'], output = waflib.Context.STDOUT) except Exception as e: conf.fatal('CC version not found: %s' % (e.stderr)) # # First line is the version # vline = out.split('\n')[0] conf.msg('Compiler version (%s)' % (os.path.basename(rtems_cc)), ' '.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'] conf.env.LINKFLAGS = cflags['cflags'] + ldflags['ldflags'] conf.env.LIB = flags['LIB'] conf.env.LIBPATH = ldflags['libpath'] conf.env.RTRACE_WRAPPER_ST = '-W %s' # # Checks for various RTEMS features. # conf.multicheck({ 'header_name': 'rtems/score/cpuopts.h'}, msg = 'Checking for RTEMS CPU options header', mandatory = True) load_cpuopts(conf, ab, rtems_path) conf.multicheck({ 'header_name': 'rtems.h'}, msg = 'Checking for RTEMS header', mandatory = True) # # Add tweaks. # tweaks(conf, ab) # # If the user has supplied a BSP specific configure function # call it. # if bsp_configure: bsp_configure(conf, ab) conf.setenv('', env) conf.env.RTEMS_TOOLS = rtems_tools conf.env.ARCHS = archs conf.env.ARCH_BSPS = arch_bsps 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, arch_bsp, rtems_path): options = ['RTEMS_DEBUG', 'RTEMS_MULTIPROCESSING', 'RTEMS_NEWLIB', 'RTEMS_POSIX_API', 'RTEMS_SMP', 'RTEMS_NETWORKING'] for opt in options: enabled = check_opt(conf, opt, 'rtems/score/cpuopts.h', arch_bsp, rtems_path) if enabled: conf.env[opt] = 'Yes' else: conf.env[opt] = 'No' def check_opt(conf, opt, header, arch_bsp, rtems_path): code = '#include <%s>%s' % (header, os.linesep) code += '#ifndef %s%s' % (opt, os.linesep) code += ' #error %s is not defined%s' % (opt, os.linesep) code += '#endif%s' % (os.linesep) code += '#if %s%s' % (opt, os.linesep) code += ' /* %s is true */%s' % (opt, os.linesep) code += '#else%s' % (os.linesep) code += ' #error %s is false%s' % (opt, os.linesep) code += '#endif%s' % (os.linesep) code += 'int main() { return 0; }%s' % (os.linesep) try: conf.check_cc(fragment = code, execute = False, define_ret = False, msg = 'Checking for %s' % (opt)) except conf.errors.WafError: return False; return True def tweaks(conf, arch_bsp): # # Hack to work around NIOS2 naming. # if conf.env.RTEMS_ARCH in ['nios2']: conf.env.OBJCOPY_FLAGS = ['-O', 'elf32-littlenios2'] elif conf.env.RTEMS_ARCH in ['arm']: conf.env.OBJCOPY_FLAGS = ['-I', 'binary', '-O', 'elf32-littlearm'] else: conf.env.OBJCOPY_FLAGS = ['-O', 'elf32-' + conf.env.RTEMS_ARCH] # # Check for a i386 PC bsp. # if re.match('i386-.*-pc[3456]86', arch_bsp) is not None: conf.env.LINKFLAGS += ['-Wl,-Ttext,0x00100000'] if '-ffunction-sections' in conf.env.CFLAGS: conf.env.LINKFLAGS += ['-Wl,--gc-sections'] def check_options(ctx, prefix, rtems_tools, rtems_path, rtems_version, rtems_archs, rtems_bsps): # # Set defaults # if rtems_version is None: if rtems_default_version is None: m = re.compile('[^0-9.]*([0-9.]+)$').match(prefix) if m: rtems_version = m.group(1) else: ctx.fatal('RTEMS version cannot derived from prefix: ' + prefix) else: rtems_version = rtems_default_version if rtems_path is None: rtems_path = prefix if rtems_tools is None: rtems_tools = rtems_path # # Check the paths are valid. # if not os.path.exists(rtems_path): ctx.fatal('RTEMS path not found.') if os.path.exists(os.path.join(rtems_path, 'lib', 'pkgconfig')): rtems_config = None 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.') if os.path.exists(os.path.join(rtems_path, 'bin')): rtems_bin = os.path.join(rtems_path, 'bin') else: ctx.fatal('RTEMS path is not valid. No bin directory found.') # # We can more than one path to tools. This happens when testing different # versions. # rt = rtems_tools.split(',') tools = [] for path in rt: 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) tools += [os.path.join(path, 'bin')] # # Filter the tools. # tools = filter(ctx, 'tools', tools) # # Match the archs requested against the ones found. If the user # wants all (default) set all used. # 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) # # Filter the architectures. # archs = filter(ctx, 'archs', archs) # # We some. # if len(archs) == 0: ctx.fatal('Could not find any architectures') # # Get the list of valid BSPs. This process filters the architectures # to those referenced by the BSPs. # if rtems_bsps == 'all': 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) if len(arch_bsps) == 0: ctx.fatal('No valid arch/bsps found') # # Filter the bsps. # arch_bsps = filter(ctx, 'bsps', arch_bsps) return rtems_version, rtems_path, rtems_bin, tools, archs, arch_bsps def check_env(ctx, var): if var in ctx.env and len(ctx.env[var]) != 0: return True return False def check(ctx, option): if option in ctx.env: return ctx.env[option] == 'Yes' 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_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 if type(rtems_filters) is not dict: ctx.fatal("Invalid RTEMS filter type, " \ "ie { 'tools': { 'in': [], 'out': [] }, 'arch': {}, 'bsps': {} }") if filter not in rtems_filters: return items items_in = [] items_out = [] if 'in' in rtems_filters[filter]: items_in = copy.copy(rtems_filters[filter]['in']) if 'out' in rtems_filters[filter]: items_out = copy.copy(rtems_filters[filter]['out']) filtered_items = [] for i in items: item = i ab = '%s/%s' % (arch(item), bsp(item)) for inre in items_in: if re.compile(inre).match(ab): items_in.remove(inre) filtered_items += [item] item = None break if item is not None: for outre in items_out: if re.compile(outre).match(ab): item = None break if item is not None: filtered_items += [item] if len(items_in) != 0: 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)) 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) lib = os.path.abspath(a.strip()) if os.path.exists(lib): 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}') def clone_tasks(bld): if bld.cmd == 'build': for obj in bld.all_task_gen[:]: for x in arch_bsp: cloned_obj = obj.clone(x) kind = Options.options.build_kind if kind.find(x) < 0: cloned_obj.posted = True obj.posted = True # # From the demos. Use this to get the command to cut+paste to play. # 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) if isinstance(cmd, str): Logs.info('%s' % cmd) else: cmdstr = ' '.join(cmd) Logs.info('(%d) %s' % (len(cmdstr), cmdstr)) # here is the change Logs.debug('runner_env: kw=%s' % kw) try: if self.logger: self.logger.info(cmd) kw['stdout'] = kw['stderr'] = subprocess.PIPE p = subprocess.Popen(cmd, **kw) (out, err) = p.communicate() if out: 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')) 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 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 import tempfile 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:]] try: os.write(fd, ' '.join(flat).encode()) finally: if tmp: os.close(fd) # Line may be very long: # Logs.debug('runner:' + ' '.join(flat)) cmd = [cmd[0], '@' + tmp] ret = super(self.__class__, self).exec_command(cmd, **kw) finally: if tmp: os.remove(tmp) return ret 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.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['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_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: for d in os.listdir(path): if d.endswith('-rtems' + version): archs += [d] else: a = subprocess.check_output([config, '--list-format', '"%(arch)s"']) a = a[:-1].replace('"', '') archs = set(a.split()) archs = ['%s-rtems%s' % (x, version) for x in archs] archs.sort() return archs def _check_archs(config, req, path, version): installed = _find_installed_archs(config, path, version) archs = [] for a in req.split(','): arch = a + '-rtems' + version if arch in installed: archs += [arch] archs.sort() return archs def _find_installed_arch_bsps(config, path, archs, version): arch_bsps = [] if config is None: for f in os.listdir(_pkgconfig_path(path)): if f.endswith('.pc'): if _arch_from_arch_bsp(f[:-3]) in archs: arch_bsps += [f[:-3]] else: ab = subprocess.check_output([config, '--list-format']) ab = ab[:-1].replace('"', '') ab = ab.replace('/', '-rtems%s-' % (version)) arch_bsps = [x for x in set(ab.split())] arch_bsps.sort() return arch_bsps def _check_arch_bsps(req, config, path, archs, version): archs_bsps = [] for ab in req.split(','): abl = ab.split('/') if len(abl) != 2: return [] found = False for arch in archs: a = '%s-rtems%s' % (abl[0], version) if a == arch: found = True break if not found: return [] archs_bsps += ['%s-%s' % (a, abl[1])] if len(archs_bsps) == 0: return [] installed = _find_installed_arch_bsps(config, path, archs, version) bsps = [] for b in archs_bsps: if b in installed: bsps += [b] bsps.sort() return bsps def _arch_from_arch_bsp(arch_bsp): return '-'.join(arch_bsp.split('-')[:2]) def _bsp_from_arch_bsp(arch_bsp): return '-'.join(arch_bsp.split('-')[2:]) 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.') if os.path.exists(_pkgconfig_path(path)): pc = os.path.join(_pkgconfig_path(path), arch_bsp + '.pc') conf.to_log('Opening and load pkgconfig: ' + pc) pkg = pkgconfig.package(pc) config = None elif os.path.exists(os.path.join(path, 'rtems-config')): config = os.path.join(path, 'rtems-config') pkg = None flags = {} _log_header(conf) flags['CFLAGS'] = _load_flags_set('CFLAGS', arch_bsp, conf, config, pkg) flags['LDFLAGS'] = _load_flags_set('LDFLAGS', arch_bsp, conf, config, pkg) flags['LIB'] = _load_flags_set('LIB', arch_bsp, conf, config, pkg) return flags def _load_flags_set(flags, arch_bsp, conf, config, pkg): conf.to_log('%s ->' % flags) if pkg is not None: flagstr = '' try: flagstr = pkg.get(flags) except pkgconfig.error as e: conf.to_log('pkconfig warning: ' + e.msg) conf.to_log(' ' + flagstr) else: flags_map = { 'CFLAGS': '--cflags', 'LDFLAGS': '--ldflags', 'LIB': '--libs' } ab = arch_bsp.split('-') #conf.check_cfg(path = config, # package = '', # uselib_store = 'rtems', # args = '--bsp %s/%s %s' % (ab[0], ab[2], flags_map[flags])) #print conf.env #print '%r' % conf #flagstr = '-l -c' 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' if flags == 'LIB': flagstr = 'rtemscpu rtemsbsp c rtemscpu rtemsbsp' return flagstr.split() def _filter_flags(label, flags, arch, rtems_path): flag_groups = \ [ { 'key': 'warnings', 'path': False, 'flags': { '-W': 1 }, 'cflags': False, 'lflags': False }, { 'key': 'includes', 'path': True, 'flags': { '-I': 1, '-isystem': 2, '-sysroot': 2 } }, { 'key': 'libpath', 'path': True, 'flags': { '-L': 1 } }, { 'key': 'machines', 'path': True, 'flags': { '-O': 1, '-m': 1, '-f': 1 } }, { 'key': 'specs', 'path': True, 'flags': { '-q': 1, '-B': 2, '--specs': 2 } } ] flags = _strip_cflags(flags) _flags = { label: [] } for fg in flag_groups: _flags[fg['key']] = [] iflags = iter(flags) for opt in iflags: in_label = True opts = [] for fg in flag_groups: key = fg['key'] for flag in fg['flags']: if opt.startswith(flag): opt_count = fg['flags'][flag] if opt_count > 1: if opt != flag: opt_count -= 1 if fg['path'] and arch in opt: opt = '%s%s/%s' % (flag, rtems_path, opt[opt.find(arch):]) opts += [opt] for c in range(1, opt_count): opt = next(iflags) if fg['path'] and arch in opt: opt = '%s%s/%s' % (f, rtems_path, opt[opt.find(arch):]) opts += [opt] _flags[key] += opts if label in fg and not fg[label]: in_label = False break if in_label: _flags[label] += opts return _flags def _strip_cflags(cflags): _cflags = [] for o in cflags: if o.startswith('-O'): pass elif o.startswith('-g'): pass else: _cflags += [o] return _cflags def _log_header(conf): conf.to_log('-----------------------------------------') from waflib import Task from waflib import TaskGen from waflib import Utils 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']) 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'] 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'] inst_to = '${BINDIR}' color = 'PINK'