source: rtems_waf/rtems.py @ b0afac0

Last change on this file since b0afac0 was b0afac0, checked in by Chris Johns <chrisj@…>, on Jun 15, 2016 at 1:14:16 AM

Add root_filesystem support to create a root file system.

To use add to your wscript file:

rtems.root_filesystem(bld, 'rootfs',

etc/rc.conf?,
'rootfs.tar', 'rootfs-tar.o')

to create a rootfs-tar.o which you add to your executable's list of
sources.

In your main or Init function add:

#include <rtems/untar.h>
extern int _binary_rootfs_tar_start;
extern int _binary_rootfs_tar_size;
static void expand_rootfs_tarfile(void)
{

rtems_status_code sc;
rtems_printer printer;
rtems_print_printer_printf(&printer);
sc = Untar_FromMemory_Print((void *)(&_binary_rootfs_tar_start),

(size_t)&_binary_rootfs_tar_size,
&printer);

if (sc != RTEMS_SUCCESSFUL)

fprintf(stderr, "error: untar failed: %s\n", rtems_status_text(sc));

}

Note, some arch's may not need the '_' at the start of the tar symbols.

  • Property mode set to 100644
File size: 27.6 KB
Line 
1#
2# Copyright 2012-2016 Chris Johns (chrisj@rtems.org)
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are met:
6
7# 1. Redistributions of source code must retain the above copyright notice, this
8# list of conditions and the following disclaimer.
9
10# 2. Redistributions in binary form must reproduce the above copyright notice,
11# this list of conditions and the following disclaimer in the documentation
12# and/or other materials provided with the distribution.
13
14# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25#
26# RTEMS support for applications.
27#
28
29import copy
30import os
31import os.path
32from . import pkgconfig
33import re
34import subprocess
35
36rtems_default_version = None
37rtems_filters = None
38
39def options(opt):
40    opt.add_option('--rtems',
41                   default = None,
42                   dest = 'rtems_path',
43                   help = 'Path to an installed RTEMS (defaults to prefix).')
44    opt.add_option('--rtems-tools',
45                   default = None,
46                   dest = 'rtems_tools',
47                   help = 'Path to RTEMS tools (defaults to path to installed RTEMS).')
48    opt.add_option('--rtems-version',
49                   default = None,
50                   dest = 'rtems_version',
51                   help = 'RTEMS version (default is derived from prefix).')
52    opt.add_option('--rtems-archs',
53                   default = 'all',
54                   dest = 'rtems_archs',
55                   help = 'List of RTEMS architectures to build.')
56    opt.add_option('--rtems-bsps',
57                   default = 'all',
58                   dest = 'rtems_bsps',
59                   help = 'List of BSPs to build.')
60    opt.add_option('--show-commands',
61                   action = 'store_true',
62                   default = False,
63                   dest = 'show_commands',
64                   help = 'Print the commands as strings.')
65
66def init(ctx, filters = None, version = None):
67    global rtems_filters
68    global rtems_default_version
69
70    #
71    # Set the RTEMS filter to the context.
72    #
73    rtems_filters = filters
74
75    #
76    # Set the default version, can be overridden.
77    #
78    rtems_default_version = version
79
80    try:
81        import waflib.Options
82        import waflib.ConfigSet
83
84        #
85        # Load the configuation set from the lock file.
86        #
87        env = waflib.ConfigSet.ConfigSet()
88        env.load(waflib.Options.lockfile)
89
90        #
91        # Check the tools, architectures and bsps.
92        #
93        rtems_version, rtems_path, rtems_bin, rtems_tools, archs, arch_bsps = \
94            check_options(ctx,
95                          env.options['prefix'],
96                          env.options['rtems_tools'],
97                          env.options['rtems_path'],
98                          env.options['rtems_version'],
99                          env.options['rtems_archs'],
100                          env.options['rtems_bsps'])
101
102        #
103        # Update the contextes for all the bsps.
104        #
105        from waflib.Build import BuildContext, CleanContext, \
106            InstallContext, UninstallContext
107        for x in arch_bsps:
108            for y in (BuildContext, CleanContext, InstallContext, UninstallContext):
109                name = y.__name__.replace('Context','').lower()
110                class context(y):
111                    cmd = name + '-' + x
112                    variant = x
113
114        #
115        # Transform the command to per BSP commands.
116        #
117        commands = []
118        for cmd in waflib.Options.commands:
119            if cmd in ['build', 'clean', 'install']:
120                for x in arch_bsps:
121                    commands += [cmd + '-' + x]
122            else:
123                commands += [cmd]
124        waflib.Options.commands = commands
125    except:
126        pass
127
128def configure(conf, bsp_configure = None):
129    #
130    # Check the environment for any flags.
131    #
132    for f in ['CC', 'CXX', 'AS', 'LD', 'AR', 'LINK_CC', 'LINK_CXX',
133              'CPPFLAGS', 'CFLAGS', 'CXXFLAGS', 'ASFLAGS', 'LINKFLAGS', 'LIB'
134              'WFLAGS', 'RFLAGS', 'MFLAGS', 'IFLAGS']:
135        if f in os.environ:
136            conf.msg('Environment variable set', f, color = 'RED')
137
138    #
139    # Handle the show commands option.
140    #
141    if conf.options.show_commands:
142        show_commands = 'yes'
143    else:
144        show_commands = 'no'
145
146    rtems_version, rtems_path, rtems_bin, rtems_tools, archs, arch_bsps = \
147        check_options(conf,
148                      conf.options.prefix,
149                      conf.options.rtems_tools,
150                      conf.options.rtems_path,
151                      conf.options.rtems_version,
152                      conf.options.rtems_archs,
153                      conf.options.rtems_bsps)
154
155    if rtems_tools is None:
156        conf.fatal('RTEMS tools not found.')
157
158    _log_header(conf)
159
160    conf.msg('RTEMS Version', rtems_version, 'YELLOW')
161    conf.msg('Architectures', ', '.join(archs), 'YELLOW')
162
163    tools = {}
164    env = conf.env.derive()
165
166    for ab in arch_bsps:
167        conf.setenv(ab, env)
168
169        conf.msg('Board Support Package', ab, 'YELLOW')
170
171        arch = _arch_from_arch_bsp(ab)
172        bsp  = _bsp_from_arch_bsp(ab)
173
174        conf.env.ARCH_BSP = '%s/%s' % (arch.split('-')[0], bsp)
175
176        conf.env.RTEMS_PATH = rtems_path
177        conf.env.RTEMS_VERSION = rtems_version
178        conf.env.RTEMS_ARCH_BSP = ab
179        conf.env.RTEMS_ARCH = arch.split('-')[0]
180        conf.env.RTEMS_ARCH_RTEMS = arch
181        conf.env.RTEMS_BSP = bsp
182
183        tools = _find_tools(conf, arch, [rtems_bin] + rtems_tools, tools)
184        for t in tools[arch]:
185            conf.env[t] = tools[arch][t]
186
187        conf.load('gcc')
188        conf.load('g++')
189        conf.load('gas')
190
191        #
192        # Get the version of the tools being used.
193        #
194        rtems_cc = conf.env.CC[0]
195        try:
196            import waflib.Context
197            out = conf.cmd_and_log([rtems_cc, '--version'],
198                                   output = waflib.Context.STDOUT)
199        except Exception as e:
200            conf.fatal('CC version not found: %s' % (e.stderr))
201        #
202        # First line is the version
203        #
204        vline = out.split('\n')[0]
205        conf.msg('Compiler version (%s)' % (os.path.basename(rtems_cc)),
206                                            ' '.join(vline.split()[2:]))
207
208        flags = _load_flags(conf, ab, rtems_path)
209
210        cflags = _filter_flags('cflags', flags['CFLAGS'],
211                               arch, rtems_path)
212        ldflags = _filter_flags('ldflags', flags['LDFLAGS'],
213                               arch, rtems_path)
214
215        conf.env.CFLAGS    = cflags['cflags']
216        conf.env.CXXFLAGS  = conf.env.CFLAGS
217        conf.env.ASFLAGS   = cflags['cflags']
218        conf.env.WFLAGS    = cflags['warnings']
219        conf.env.RFLAGS    = cflags['specs']
220        conf.env.MFLAGS    = cflags['machines']
221        conf.env.IFLAGS    = cflags['includes']
222        conf.env.LINKFLAGS = cflags['cflags'] + ldflags['ldflags']
223        conf.env.LIB       = flags['LIB']
224        conf.env.LIBPATH   = ldflags['libpath']
225
226        conf.env.RTRACE_WRAPPER_ST = '-W %s'
227
228        #
229        # Checks for various RTEMS features.
230        #
231        conf.multicheck({ 'header_name': 'rtems/score/cpuopts.h'},
232                        msg = 'Checking for RTEMS CPU options header',
233                        mandatory = True)
234        load_cpuopts(conf, ab, rtems_path)
235        if conf.env['RTEMS_SMP'] == 'Yes':
236            conf.env.CXXFLAGS += ['-std=gnu++11']
237        conf.multicheck({ 'header_name': 'rtems.h'},
238                        msg = 'Checking for RTEMS header',
239                        mandatory = True)
240
241        #
242        # Add tweaks.
243        #
244        tweaks(conf, ab)
245
246        #
247        # If the user has supplied a BSP specific configure function
248        # call it.
249        #
250        if bsp_configure:
251            bsp_configure(conf, ab)
252
253        #
254        # Show commands support the user can supply.
255        #
256        conf.env.SHOW_COMMANDS = show_commands
257
258        conf.setenv('', env)
259
260    conf.env.RTEMS_TOOLS = rtems_tools
261    conf.env.ARCHS = archs
262    conf.env.ARCH_BSPS = arch_bsps
263
264    conf.env.SHOW_COMMANDS = show_commands
265
266def build(bld):
267    if bld.env.SHOW_COMMANDS == 'yes':
268        output_command_line()
269
270def load_cpuopts(conf, arch_bsp, rtems_path):
271    options = ['RTEMS_DEBUG',
272               'RTEMS_MULTIPROCESSING',
273               'RTEMS_NEWLIB',
274               'RTEMS_POSIX_API',
275               'RTEMS_SMP',
276               'RTEMS_NETWORKING']
277    for opt in options:
278        enabled = check_opt(conf, opt, 'rtems/score/cpuopts.h', arch_bsp, rtems_path)
279        if enabled:
280            conf.env[opt] = 'Yes'
281        else:
282            conf.env[opt] = 'No'
283
284def check_opt(conf, opt, header, arch_bsp, rtems_path):
285    code  = '#include <%s>%s' % (header, os.linesep)
286    code += '#ifndef %s%s' % (opt, os.linesep)
287    code += ' #error %s is not defined%s' % (opt, os.linesep)
288    code += '#endif%s' % (os.linesep)
289    code += '#if %s%s' % (opt, os.linesep)
290    code += ' /* %s is true */%s' % (opt, os.linesep)
291    code += '#else%s' % (os.linesep)
292    code += ' #error %s is false%s' % (opt, os.linesep)
293    code += '#endif%s' % (os.linesep)
294    code += 'int main() { return 0; }%s' % (os.linesep)
295    try:
296        conf.check_cc(fragment = code,
297                      execute = False,
298                      define_ret = False,
299                      msg = 'Checking for %s' % (opt))
300    except conf.errors.WafError:
301        return False;
302    return True
303
304def tweaks(conf, arch_bsp):
305    #
306    # Hack to work around NIOS2 naming.
307    #
308    if conf.env.RTEMS_ARCH in ['nios2']:
309        conf.env.OBJCOPY_FLAGS = ['-O', 'elf32-littlenios2']
310    elif conf.env.RTEMS_ARCH in ['arm']:
311        conf.env.OBJCOPY_FLAGS = ['-I', 'binary', '-O', 'elf32-littlearm']
312    else:
313        conf.env.OBJCOPY_FLAGS = ['-O', 'elf32-' + conf.env.RTEMS_ARCH]
314
315    #
316    # Check for a i386 PC bsp.
317    #
318    if re.match('i386-.*-pc[3456]86', arch_bsp) is not None:
319        conf.env.LINKFLAGS += ['-Wl,-Ttext,0x00100000']
320
321    if '-ffunction-sections' in conf.env.CFLAGS:
322      conf.env.LINKFLAGS += ['-Wl,--gc-sections']
323
324def check_options(ctx, prefix, rtems_tools, rtems_path, rtems_version, rtems_archs, rtems_bsps):
325    #
326    # Set defaults
327    #
328    if rtems_version is None:
329        if rtems_default_version is None:
330            m = re.compile('[^0-9.]*([0-9.]+)$').match(prefix)
331            if m:
332                rtems_version = m.group(1)
333            else:
334                ctx.fatal('RTEMS version cannot derived from prefix: ' + prefix)
335        else:
336            rtems_version = rtems_default_version
337    if rtems_path is None:
338        rtems_path = prefix
339    if rtems_tools is None:
340        rtems_tools = rtems_path
341
342    #
343    # Check the paths are valid.
344    #
345    if not os.path.exists(rtems_path):
346        ctx.fatal('RTEMS path not found.')
347    if os.path.exists(os.path.join(rtems_path, 'lib', 'pkgconfig')):
348        rtems_config = None
349    elif os.path.exists(os.path.join(rtems_path, 'rtems-config')):
350        rtems_config = os.path.join(rtems_path, 'rtems-config')
351    else:
352        ctx.fatal('RTEMS path is not valid. No lib/pkgconfig or rtems-config found.')
353    if os.path.exists(os.path.join(rtems_path, 'bin')):
354        rtems_bin = os.path.join(rtems_path, 'bin')
355    else:
356        ctx.fatal('RTEMS path is not valid. No bin directory found.')
357
358    #
359    # We can more than one path to tools. This happens when testing different
360    # versions.
361    #
362    rt = rtems_tools.split(',')
363    tools = []
364    for path in rt:
365        if not os.path.exists(path):
366            ctx.fatal('RTEMS tools path not found: ' + path)
367        if not os.path.exists(os.path.join(path, 'bin')):
368            ctx.fatal('RTEMS tools path does not contain a \'bin\' directory: ' + path)
369        tools += [os.path.join(path, 'bin')]
370
371    #
372    # Filter the tools.
373    #
374    tools = filter(ctx, 'tools', tools)
375
376    #
377    # Match the archs requested against the ones found. If the user
378    # wants all (default) set all used.
379    #
380    if rtems_archs == 'all':
381        archs = _find_installed_archs(rtems_config, rtems_path, rtems_version)
382    else:
383        archs = _check_archs(rtems_config, rtems_archs, rtems_path, rtems_version)
384
385    #
386    # Filter the architectures.
387    #
388    archs = filter(ctx, 'archs', archs)
389
390    #
391    # We some.
392    #
393    if len(archs) == 0:
394        ctx.fatal('Could not find any architectures')
395
396    #
397    # Get the list of valid BSPs. This process filters the architectures
398    # to those referenced by the BSPs.
399    #
400    if rtems_bsps == 'all':
401        arch_bsps = _find_installed_arch_bsps(rtems_config, rtems_path, archs, rtems_version)
402    else:
403        arch_bsps = _check_arch_bsps(rtems_bsps, rtems_config, rtems_path, archs, rtems_version)
404
405    if len(arch_bsps) == 0:
406        ctx.fatal('No valid arch/bsps found')
407
408    #
409    # Filter the bsps.
410    #
411    arch_bsps = filter(ctx, 'bsps', arch_bsps)
412
413    return rtems_version, rtems_path, rtems_bin, tools, archs, arch_bsps
414
415def check_env(ctx, var):
416    if var in ctx.env and len(ctx.env[var]) != 0:
417        return True
418    return False
419
420def check(ctx, option):
421    if option in ctx.env:
422        return ctx.env[option] == 'Yes'
423    return False
424
425def check_debug(ctx):
426    return check(ctx, 'RTEMS_DEBUG')
427
428def check_multiprocessing(ctx):
429    return check(ctx, 'RTEMS_MULTIPROCESSING')
430
431def check_newlib(ctx):
432    return check(ctx, 'RTEMS_NEWLIB')
433
434def check_posix(ctx):
435    return check(ctx, 'RTEMS_POSIX_API')
436
437def check_smp(ctx):
438    return check(ctx, 'RTEMS_SMP')
439
440def check_networking(ctx):
441    return check(ctx, 'RTEMS_NETWORKING')
442
443def arch(arch_bsp):
444    """ Given an arch/bsp return the architecture."""
445    return _arch_from_arch_bsp(arch_bsp).split('-')[0]
446
447def bsp(arch_bsp):
448    """ Given an arch/bsp return the BSP."""
449    return _bsp_from_arch_bsp(arch_bsp)
450
451def arch_bsps(ctx):
452    """ Return the list of arch/bsps we are building."""
453    return ctx.env.ARCH_BSPS
454
455def arch_bsp_env(ctx, arch_bsp):
456    return ctx.env_of_name(arch_bsp).derive()
457
458def filter(ctx, filter, items):
459    if rtems_filters is None:
460        return items
461    if type(rtems_filters) is not dict:
462        ctx.fatal("Invalid RTEMS filter type, " \
463                  "ie { 'tools': { 'in': [], 'out': [] }, 'arch': {}, 'bsps': {} }")
464    if filter not in rtems_filters:
465        return items
466    items_in = []
467    items_out = []
468    if 'in' in rtems_filters[filter]:
469        items_in = copy.copy(rtems_filters[filter]['in'])
470    if 'out' in rtems_filters[filter]:
471        items_out = copy.copy(rtems_filters[filter]['out'])
472    filtered_items = []
473    for i in items:
474        item = i
475        ab = '%s/%s' % (arch(item), bsp(item))
476        for inre in items_in:
477            if re.compile(inre).match(ab):
478                items_in.remove(inre)
479                filtered_items += [item]
480                item = None
481                break
482        if item is not None:
483            for outre in items_out:
484                if re.compile(outre).match(ab):
485                    item = None
486                    break
487        if item is not None:
488            filtered_items += [item]
489    if len(items_in) != 0:
490        ctx.fatal('Following %s not found: %s' % (filter, ', '.join(items_in)))
491    return sorted(filtered_items)
492
493def arch_rtems_version(version, arch):
494    """ Return the RTEMS architecture path, ie sparc-rtems4.11."""
495    return '%s-rtems%s' % (arch, version)
496
497def arch_bsp_path(version, arch_bsp):
498    """ Return the BSP path."""
499    return '%s/%s' % (arch_rtems_version(version, arch(arch_bsp)), bsp(arch_bsp))
500
501def arch_bsp_include_path(version, arch_bsp):
502    """ Return the BSP include path."""
503    return '%s/lib/include' % (arch_bsp_path(version, arch_bsp))
504
505def arch_bsp_lib_path(version, arch_bsp):
506    """ Return the BSP library path. """
507    return '%s/lib' % (arch_bsp_path(version, arch_bsp))
508
509def library_path(library, cc, cflags):
510    cmd = cc + cflags + ['-print-file-name=%s' % library]
511    a = subprocess.check_output(cmd)
512    lib = os.path.abspath(a.strip())
513    if os.path.exists(lib):
514        return os.path.dirname(lib)
515    return None
516
517def root_filesystem(bld, name, files, tar, obj):
518    bld(name = name + '_tar',
519        target = tar,
520        source = files,
521        rule = 'SDIR=$PWD && cd ../.. && tar --format=ustar -cf $SDIR/${TGT} $(echo "${SRC}" | sed -e "s/\.\.\/\.\.\///\")')
522    bld.objects(name = name,
523                target = obj,
524                source = tar,
525                rule = '${OBJCOPY} -I binary -B ${RTEMS_ARCH} ${OBJCOPY_FLAGS} ${SRC} ${TGT}')
526
527def clone_tasks(bld):
528    if bld.cmd == 'build':
529        for obj in bld.all_task_gen[:]:
530            for x in arch_bsp:
531                cloned_obj = obj.clone(x)
532                kind = Options.options.build_kind
533                if kind.find(x) < 0:
534                    cloned_obj.posted = True
535            obj.posted = True
536
537#
538# From the demos. Use this to get the command to cut+paste to play.
539#
540def output_command_line():
541    # first, display strings, people like them
542    from waflib import Utils, Logs
543    from waflib.Context import Context
544    def exec_command(self, cmd, **kw):
545        subprocess = Utils.subprocess
546        kw['shell'] = isinstance(cmd, str)
547        if isinstance(cmd, str):
548            Logs.info('%s' % cmd)
549        else:
550            Logs.info('%s' % ' '.join(cmd)) # here is the change
551        Logs.debug('runner_env: kw=%s' % kw)
552        try:
553            if self.logger:
554                self.logger.info(cmd)
555                kw['stdout'] = kw['stderr'] = subprocess.PIPE
556                p = subprocess.Popen(cmd, **kw)
557                (out, err) = p.communicate()
558                if out:
559                    self.logger.debug('out: %s' % out.decode(sys.stdout.encoding or 'iso8859-1'))
560                if err:
561                    self.logger.error('err: %s' % err.decode(sys.stdout.encoding or 'iso8859-1'))
562                return p.returncode
563            else:
564                p = subprocess.Popen(cmd, **kw)
565                return p.wait()
566        except OSError:
567            return -1
568    Context.exec_command = exec_command
569
570    # Change the outputs for tasks too
571    from waflib.Task import Task
572    def display(self):
573        return '' # no output on empty strings
574
575    Task.__str__ = display
576
577def _find_tools(conf, arch, paths, tools):
578    if arch not in tools:
579        arch_tools = {}
580        arch_tools['CC']          = conf.find_program([arch + '-gcc'], path_list = paths)
581        arch_tools['CXX']         = conf.find_program([arch + '-g++'], path_list = paths)
582        arch_tools['LINK_CC']     = arch_tools['CC']
583        arch_tools['LINK_CXX']    = arch_tools['CXX']
584        arch_tools['AS']          = conf.find_program([arch + '-gcc'], path_list = paths)
585        arch_tools['LD']          = conf.find_program([arch + '-ld'],  path_list = paths)
586        arch_tools['AR']          = conf.find_program([arch + '-ar'], path_list = paths)
587        arch_tools['NM']          = conf.find_program([arch + '-nm'], path_list = paths)
588        arch_tools['OBJDUMP']     = conf.find_program([arch + '-objdump'], path_list = paths)
589        arch_tools['OBJCOPY']     = conf.find_program([arch + '-objcopy'], path_list = paths)
590        arch_tools['READELF']     = conf.find_program([arch + '-readelf'], path_list = paths)
591        arch_tools['STRIP']       = conf.find_program([arch + '-strip'], path_list = paths)
592        arch_tools['RTEMS_LD']    = conf.find_program(['rtems-ld'], path_list = paths,
593                                                      mandatory = False)
594        arch_tools['RTEMS_TLD']   = conf.find_program(['rtems-tld'], path_list = paths,
595                                                      mandatory = False)
596        arch_tools['RTEMS_BIN2C'] = conf.find_program(['rtems-bin2c'], path_list = paths,
597                                                      mandatory = False)
598        arch_tools['TAR']         = conf.find_program(['tar'], mandatory = False)
599        tools[arch] = arch_tools
600    return tools
601
602def _find_installed_archs(config, path, version):
603    archs = []
604    if config is None:
605        for d in os.listdir(path):
606            if d.endswith('-rtems' + version):
607                archs += [d]
608    else:
609        a = subprocess.check_output([config, '--list-format', '"%(arch)s"'])
610        a = a[:-1].replace('"', '')
611        archs = set(a.split())
612        archs = ['%s-rtems%s' % (x, version) for x in archs]
613    archs.sort()
614    return archs
615
616def _check_archs(config, req, path, version):
617    installed = _find_installed_archs(config, path, version)
618    archs = []
619    for a in req.split(','):
620        arch = a + '-rtems' + version
621        if arch in installed:
622            archs += [arch]
623    archs.sort()
624    return archs
625
626def _find_installed_arch_bsps(config, path, archs, version):
627    arch_bsps = []
628    if config is None:
629        for f in os.listdir(_pkgconfig_path(path)):
630            if f.endswith('.pc'):
631                if _arch_from_arch_bsp(f[:-3]) in archs:
632                    arch_bsps += [f[:-3]]
633    else:
634        ab = subprocess.check_output([config, '--list-format'])
635        ab = ab[:-1].replace('"', '')
636        ab = ab.replace('/', '-rtems%s-' % (version))
637        arch_bsps = [x for x in set(ab.split())]
638    arch_bsps.sort()
639    return arch_bsps
640
641def _check_arch_bsps(req, config, path, archs, version):
642    archs_bsps = []
643    for ab in req.split(','):
644        abl = ab.split('/')
645        if len(abl) != 2:
646            return []
647        found = False
648        for arch in archs:
649            a = '%s-rtems%s' % (abl[0], version)
650            if a == arch:
651                found = True
652                break
653        if not found:
654            return []
655        archs_bsps += ['%s-%s' % (a, abl[1])]
656    if len(archs_bsps) == 0:
657        return []
658    installed = _find_installed_arch_bsps(config, path, archs, version)
659    bsps = []
660    for b in archs_bsps:
661        if b in installed:
662            bsps += [b]
663    bsps.sort()
664    return bsps
665
666def _arch_from_arch_bsp(arch_bsp):
667    return '-'.join(arch_bsp.split('-')[:2])
668
669def _bsp_from_arch_bsp(arch_bsp):
670    return '-'.join(arch_bsp.split('-')[2:])
671
672def _pkgconfig_path(path):
673    return os.path.join(path, 'lib', 'pkgconfig')
674
675def _load_flags(conf, arch_bsp, path):
676    if not os.path.exists(path):
677        ctx.fatal('RTEMS path not found.')
678    if os.path.exists(_pkgconfig_path(path)):
679        pc = os.path.join(_pkgconfig_path(path), arch_bsp + '.pc')
680        conf.to_log('Opening and load pkgconfig: ' + pc)
681        pkg = pkgconfig.package(pc)
682        config = None
683    elif os.path.exists(os.path.join(path, 'rtems-config')):
684        config = os.path.join(path, 'rtems-config')
685        pkg = None
686    flags = {}
687    _log_header(conf)
688    flags['CFLAGS'] = _load_flags_set('CFLAGS', arch_bsp, conf, config, pkg)
689    flags['LDFLAGS'] = _load_flags_set('LDFLAGS', arch_bsp, conf, config, pkg)
690    flags['LIB'] = _load_flags_set('LIB', arch_bsp, conf, config, pkg)
691    return flags
692
693def _load_flags_set(flags, arch_bsp, conf, config, pkg):
694    conf.to_log('%s ->' % flags)
695    if pkg is not None:
696        flagstr = ''
697        try:
698            flagstr = pkg.get(flags)
699        except pkgconfig.error as e:
700            conf.to_log('pkconfig warning: ' + e.msg)
701        conf.to_log('  ' + flagstr)
702    else:
703        flags_map = { 'CFLAGS': '--cflags',
704                      'LDFLAGS': '--ldflags',
705                      'LIB': '--libs' }
706        ab = arch_bsp.split('-')
707        #conf.check_cfg(path = config,
708        #               package = '',
709        #               uselib_store = 'rtems',
710        #               args = '--bsp %s/%s %s' % (ab[0], ab[2], flags_map[flags]))
711        #print conf.env
712        #print '%r' % conf
713        #flagstr = '-l -c'
714        flagstr = subprocess.check_output([config, '--bsp', '%s/%s' % (ab[0], ab[2]), flags_map[flags]])
715        #print flags, ">>>>", flagstr
716        if flags == 'CFLAGS':
717            flagstr += ' -DWAF_BUILD=1'
718        if flags == 'LIB':
719            flagstr = 'rtemscpu rtemsbsp c rtemscpu rtemsbsp'
720    return flagstr.split()
721
722def _filter_flags(label, flags, arch, rtems_path):
723
724    flag_groups = \
725        [ { 'key': 'warnings', 'path': False, 'flags': { '-W': 1 }, 'cflags': False, 'lflags': False },
726          { 'key': 'includes', 'path': True,  'flags': { '-I': 1, '-isystem': 2, '-sysroot': 2 } },
727          { 'key': 'libpath',  'path': True,  'flags': { '-L': 1 } },
728          { 'key': 'machines', 'path': True,  'flags': { '-O': 1, '-m': 1, '-f': 1 } },
729          { 'key': 'specs',    'path': True,  'flags': { '-q': 1, '-B': 2, '--specs': 2 } } ]
730
731    flags = _strip_cflags(flags)
732
733    _flags = { label: [] }
734    for fg in flag_groups:
735        _flags[fg['key']] = []
736
737    iflags = iter(flags)
738    for opt in iflags:
739        in_label = True
740        opts = []
741        for fg in flag_groups:
742            key = fg['key']
743            for flag in fg['flags']:
744                if opt.startswith(flag):
745                    opt_count = fg['flags'][flag]
746                    if opt_count > 1:
747                        if opt != flag:
748                            opt_count -= 1
749                            if fg['path'] and arch in opt:
750                                opt = '%s%s/%s' % (flag, rtems_path,
751                                                   opt[opt.find(arch):])
752                    opts += [opt]
753                    for c in range(1, opt_count):
754                        opt = next(iflags)
755                        if fg['path'] and arch in opt:
756                            opt = '%s%s/%s' % (f, rtems_path,
757                                               opt[opt.find(arch):])
758                        opts += [opt]
759                    _flags[key] += opts
760                    if label in fg and not fg[label]:
761                        in_label = False
762                    break
763            if in_label:
764                _flags[label] += opts
765    return _flags
766
767def _strip_cflags(cflags):
768    _cflags = []
769    for o in cflags:
770        if o.startswith('-O'):
771            pass
772        elif o.startswith('-g'):
773            pass
774        else:
775            _cflags += [o]
776    return _cflags
777
778def _log_header(conf):
779    conf.to_log('-----------------------------------------')
780
781from waflib import Task
782from waflib import TaskGen
783from waflib import Utils
784from waflib import Node
785from waflib.Tools.ccroot import link_task, USELIB_VARS
786
787USELIB_VARS['rap'] = set(['RTEMS_LINKFLAGS'])
788USELIB_VARS['rtrace'] = set(['RTRACE_FLAGS', 'RTRACE_CFG', 'RTRACE_WRAPPER', 'RTRACE_LINKCMDS'])
789
790class rap(link_task):
791    "Link object files into a RTEMS application"
792    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}'
793    ext_out = ['.rap']
794    vars    = ['RTEMS_LINKFLAGS', 'LINKDEPS']
795    inst_to = '${BINDIR}'
796
797class rtrace(link_task):
798    "Link object files into a RTEMS trace application"
799    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}'
800    ext_out = ['.texe']
801    vars    = ['RTRACE_FLAGS', 'RTRACE_CFG', 'RTRACE_WRAPER', 'RTRACE_LINKFLAGS', 'LINKDEPS']
802    inst_to = '${BINDIR}'
803    color = 'PINK'
Note: See TracBrowser for help on using the repository browser.