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

4.11
Last change on this file since f88fcf3 was f88fcf3, checked in by Chris Johns <chrisj@…>, on Mar 7, 2016 at 12:56:02 AM

sb: Update code base to support Python3 and Python2.

Fix Windows support to allow MSYS2 Python to be used.

Updates #2619.

  • Property mode set to 100644
File size: 7.0 KB
Line 
1#
2# RTEMS Tools Project (http://www.rtems.org/)
3# Copyright 2013-2016 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
21from __future__ import print_function
22
23import datetime
24import operator
25import os
26import re
27import sys
28import threading
29import time
30
31import error
32import log
33import options
34import path
35import version
36
37def _collect(path_, file):
38    confs = []
39    for root, dirs, files in os.walk(path.host(path_), topdown = True):
40        for f in files:
41            if f == file:
42                confs += [path.shell(path.join(root, f))]
43    return confs
44
45def _grep(file, pattern):
46    rege = re.compile(pattern)
47    try:
48        f = open(path.host(file), 'r')
49        matches = [rege.match(l) != None for l in f.readlines()]
50        f.close()
51    except IOError as err:
52        raise error.general('error reading: %s' % (file))
53    return True in matches
54
55class command:
56
57    def __init__(self, opts, cmd, cwd = None):
58        self.exit_code = 0
59        self.output = None
60        self.opts = opts
61        self.cmd = cmd
62        self.cwd = cwd
63
64    def run(self):
65
66        import subprocess
67
68        #
69        # Support Python 2.6
70        #
71        if "check_output" not in dir(subprocess):
72            def f(*popenargs, **kwargs):
73                if 'stdout' in kwargs:
74                    raise ValueError('stdout argument not allowed, it will be overridden.')
75                process = subprocess.Popen(stdout=subprocess.PIPE, *popenargs, **kwargs)
76                output, unused_err = process.communicate()
77                retcode = process.poll()
78                if retcode:
79                    cmd = kwargs.get("args")
80                    if cmd is None:
81                        cmd = popenargs[0]
82                    raise subprocess.CalledProcessError(retcode, cmd)
83                return output
84            subprocess.check_output = f
85
86        self.start_time = datetime.datetime.now()
87        self.exit_code = 0
88        try:
89            cmd = [self.opts.defaults.expand(c) for c in self.cmd]
90            self.output = subprocess.check_output(cmd, cwd = self.cwd)
91        except subprocess.CalledProcessError as cpe:
92            self.exit_code = cpe.returncode
93            self.output = cpe.output
94        self.end_time = datetime.datetime.now()
95
96class bsp_config:
97
98    filter_out = ['as', 'cc', 'ld', 'objcopy', 'size' ]
99
100    def __init__(self, opts, prefix, arch_bsp):
101        self.opts = opts
102        self.prefix = prefix
103        if not path.exists(prefix):
104            raise error.general('RTEMS prefix path not found: %s' % (prefix))
105        self.makefile_inc = None
106        if '/' in arch_bsp:
107            arch, bsp = arch_bsp.split('/', 1)
108        else:
109            arch = None
110            bsp = arch_bsp
111        makefile_incs = _collect(prefix, 'Makefile.inc')
112        for mi in makefile_incs:
113            found = True
114            if arch is not None and arch not in mi:
115                found = False
116            if bsp not in mi:
117                found = False
118            if found:
119                self.makefile_inc = mi
120                break
121        if self.makefile_inc is None:
122            raise error.general('RTEMS BSP not found: %s' % (arch_bsp))
123        if not path.exists(self.makefile_inc):
124            raise error.general('RTEMS BSP configuration not found: %s: %s' % \
125                                    (arch_bsp, self.makefile_inc))
126        self.command = command(opts, ['%{__make}',
127                                      '-f' '%{_sbdir}/sb/rtemsconfig.mk',
128                                      'makefile_inc=%s' % (self.makefile_inc)])
129        self.command.run()
130        self.parse(self.command.output)
131
132    def __str__(self):
133        s = None
134        for c in sorted(self.configs.keys()):
135            if s is None:
136                s = ''
137            else:
138                s += os.linesep
139            s += '%s = %s' % (c, self.configs[c])
140        return s
141
142    def parse(self, text):
143        self.configs = {}
144        lines = text.splitlines()
145        lc = 0
146        while lc < len(lines):
147            l = lines[lc].strip()
148            lc += 1
149            if len(l) == 0 or l[0] == '#' or '=' not in l:
150                continue
151            key = l[:l.index('=')].strip()
152            data = l[l.index('=') + 1:].strip()
153            if len(data) == 0:
154                continue
155            if data[0] == '"':
156                if len(data) == 1 or data[-1] != '"':
157                    not_closed = True
158                    while lc < len(lines) and not_closed:
159                        l = lines[lc]
160                        lc += 1
161                        if l[-1] == '"':
162                            data += l
163                            not_close = False
164            self.configs[key] = data
165
166    def keys(self):
167        _keys = {}
168        for k in sorted(self.configs.keys()):
169            _keys[k.lower()] = k
170        return _keys
171
172    def find(self, name):
173        _keys = list(self.keys())
174        nl = name.lower()
175        if nl in _keys and not nl in bsp_config.filter_out:
176            return self.configs[_keys[nl]]
177        raise error.general('invalid configuration: %s' % (name))
178
179def run(args):
180    try:
181        optargs = { '--rtems':      'The RTEMS source directory',
182                    '--rtems-bsp':  'The RTEMS BSP (arch/bsp)',
183                    '--list':       'List the configurations' }
184        opts = options.load(sys.argv, optargs)
185
186        if opts.get_arg('--rtems'):
187            prefix = opts.get_arg('--rtems')[1]
188        else:
189            prefix = os.getcwd()
190        if opts.get_arg('--rtems-bsp') is None:
191            raise error.general('no --rtems-bsp option; please provide')
192
193        bsp = bsp_config(opts, prefix, opts.get_arg('--rtems-bsp')[1])
194
195        if opts.get_arg('--list'):
196            log.notice('RTEMS Source Builder - RTEMS Configuration, %s' % (version.str()))
197            opts.log_info()
198            configs = list(bsp.keys())
199            for c in sorted(configs.keys()):
200                print(c)
201        else:
202            for p in opts.params():
203                print(bsp.find(p))
204
205    except error.general as gerr:
206        print(gerr)
207        sys.exit(1)
208    except error.internal as ierr:
209        print(ierr)
210        sys.exit(1)
211    except error.exit as eerr:
212        pass
213    except KeyboardInterrupt:
214        log.notice('abort: user terminated')
215        sys.exit(1)
216    sys.exit(0)
217
218if __name__ == "__main__":
219    run(sys.argv)
Note: See TracBrowser for help on using the repository browser.