source: rtems-source-builder/source-builder/sb/rtemsconfig.py @ e8f5111

4.11
Last change on this file since e8f5111 was e8f5111, checked in by Chris Johns <chrisj@…>, on Dec 3, 2015 at 11:22:17 AM

sb. Add VERSION support for releasing the RSB.

Add support to release the RSB by adding the VERSION file. The file
is a single line with the version.

Fix the reports to include the version. Update the INI file
support to include the details of the build.

Show the GIT or released version when the command starts.

Closes #2480.

  • Property mode set to 100644
File size: 7.0 KB
Line 
1#
2# RTEMS Tools Project (http://www.rtems.org/)
3# Copyright 2013 Chris Johns (chrisj@rtems.org)
4# All rights reserved.
5#
6# This file is part of the RTEMS Tools package in 'rtems-tools'.
7#
8# Permission to use, copy, modify, and/or distribute this software for any
9# purpose with or without fee is hereby granted, provided that the above
10# copyright notice and this permission notice appear in all copies.
11#
12# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19#
20
21import datetime
22import operator
23import os
24import re
25import sys
26import threading
27import time
28
29import error
30import log
31import options
32import path
33import version
34
35def _collect(path_, file):
36    confs = []
37    for root, dirs, files in os.walk(path.host(path_), topdown = True):
38        for f in files:
39            if f == file:
40                confs += [path.shell(path.join(root, f))]
41    return confs
42
43def _grep(file, pattern):
44    rege = re.compile(pattern)
45    try:
46        f = open(path.host(file), 'r')
47        matches = [rege.match(l) != None for l in f.readlines()]
48        f.close()
49    except IOError, err:
50        raise error.general('error reading: %s' % (file))
51    return True in matches
52
53class command:
54
55    def __init__(self, opts, cmd, cwd = None):
56        self.exit_code = 0
57        self.output = None
58        self.opts = opts
59        self.cmd = cmd
60        self.cwd = cwd
61
62    def run(self):
63
64        import subprocess
65
66        #
67        # Support Python 2.6
68        #
69        if "check_output" not in dir(subprocess):
70            def f(*popenargs, **kwargs):
71                if 'stdout' in kwargs:
72                    raise ValueError('stdout argument not allowed, it will be overridden.')
73                process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
74                output, unused_err = process.communicate()
75                retcode = process.poll()
76                if retcode:
77                    cmd = kwargs.get("args")
78                    if cmd is None:
79                        cmd = popenargs[0]
80                    raise subprocess.CalledProcessError(retcode, cmd)
81                return output
82            subprocess.check_output = f
83
84        self.start_time = datetime.datetime.now()
85        self.exit_code = 0
86        try:
87            cmd = [self.opts.defaults.expand(c) for c in self.cmd]
88            self.output = subprocess.check_output(cmd, cwd = self.cwd)
89        except subprocess.CalledProcessError, cpe:
90            self.exit_code = cpe.returncode
91            self.output = cpe.output
92        self.end_time = datetime.datetime.now()
93
94class bsp_config:
95
96    filter_out = ['as', 'cc', 'ld', 'objcopy', 'size' ]
97
98    def __init__(self, opts, prefix, arch_bsp):
99        self.opts = opts
100        self.prefix = prefix
101        if not path.exists(prefix):
102            raise error.general('RTEMS prefix path not found: %s' % (prefix))
103        self.makefile_inc = None
104        if '/' in arch_bsp:
105            arch, bsp = arch_bsp.split('/', 1)
106        else:
107            arch = None
108            bsp = arch_bsp
109        makefile_incs = _collect(prefix, 'Makefile.inc')
110        for mi in makefile_incs:
111            found = True
112            if arch is not None and arch not in mi:
113                found = False
114            if bsp not in mi:
115                found = False
116            if found:
117                self.makefile_inc = mi
118                break
119        if self.makefile_inc is None:
120            raise error.general('RTEMS BSP not found: %s' % (arch_bsp))
121        if not path.exists(self.makefile_inc):
122            raise error.general('RTEMS BSP configuration not found: %s: %s' % \
123                                    (arch_bsp, self.makefile_inc))
124        self.command = command(opts, ['%{__make}',
125                                      '-f' '%{_sbdir}/sb/rtemsconfig.mk',
126                                      'makefile_inc=%s' % (self.makefile_inc)])
127        self.command.run()
128        self.parse(self.command.output)
129
130    def __str__(self):
131        s = None
132        for c in sorted(self.configs.keys()):
133            if s is None:
134                s = ''
135            else:
136                s += os.linesep
137            s += '%s = %s' % (c, self.configs[c])
138        return s
139
140    def parse(self, text):
141        self.configs = {}
142        lines = text.splitlines()
143        lc = 0
144        while lc < len(lines):
145            l = lines[lc].strip()
146            lc += 1
147            if len(l) == 0 or l[0] == '#' or '=' not in l:
148                continue
149            key = l[:l.index('=')].strip()
150            data = l[l.index('=') + 1:].strip()
151            if len(data) == 0:
152                continue
153            if data[0] == '"':
154                if len(data) == 1 or data[-1] != '"':
155                    not_closed = True
156                    while lc < len(lines) and not_closed:
157                        l = lines[lc]
158                        lc += 1
159                        if l[-1] == '"':
160                            data += l
161                            not_close = False
162            self.configs[key] = data
163
164    def keys(self):
165        _keys = {}
166        for k in sorted(self.configs.keys()):
167            _keys[k.lower()] = k
168        return _keys
169
170    def find(self, name):
171        _keys = self.keys()
172        nl = name.lower()
173        if nl in _keys and not nl in bsp_config.filter_out:
174            return self.configs[_keys[nl]]
175        raise error.general('invalid configuration: %s' % (name))
176
177def run(args):
178    try:
179        optargs = { '--rtems':      'The RTEMS source directory',
180                    '--rtems-bsp':  'The RTEMS BSP (arch/bsp)',
181                    '--list':       'List the configurations' }
182        opts = options.load(sys.argv, optargs)
183
184        if opts.get_arg('--rtems'):
185            prefix = opts.get_arg('--rtems')[1]
186        else:
187            prefix = os.getcwd()
188        if opts.get_arg('--rtems-bsp') is None:
189            raise error.general('no --rtems-bsp option; please provide')
190
191        bsp = bsp_config(opts, prefix, opts.get_arg('--rtems-bsp')[1])
192
193        if opts.get_arg('--list'):
194            log.notice('RTEMS Source Builder - RTEMS Configuration, %s' % (version.str()))
195            opts.log_info()
196            configs = bsp.keys()
197            for c in sorted(configs.keys()):
198                print c
199        else:
200            for p in opts.params():
201                print bsp.find(p)
202
203    except error.general, gerr:
204        print gerr
205        sys.exit(1)
206    except error.internal, ierr:
207        print ierr
208        sys.exit(1)
209    except error.exit, eerr:
210        pass
211    except KeyboardInterrupt:
212        log.notice('abort: user terminated')
213        sys.exit(1)
214    sys.exit(0)
215
216if __name__ == "__main__":
217    run(sys.argv)
Note: See TracBrowser for help on using the repository browser.