source: rtems_waf/rtems.py @ db8c6f0

Last change on this file since db8c6f0 was db8c6f0, checked in by Chris Johns <chrisj@…>, on Sep 20, 2014 at 11:00:15 PM

Clean up the rtems-tld support.

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