source: rtems-source-builder/source-builder/sb/options.py @ abe5d1b

Last change on this file since abe5d1b was 8effa3e, checked in by Chris Johns <chrisj@…>, on 06/30/20 at 07:55:53

sb/options: A Canadian Cross is a different host, build and target

The check must make sure each is different.

  • Property mode set to 100644
File size: 28.6 KB
Line 
1#
2# RTEMS Tools Project (http://www.rtems.org/)
3# Copyright 2010-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#
21# Determine the defaults and load the specific file.
22#
23
24from __future__ import print_function
25
26import datetime
27import glob
28import pprint
29import re
30import os
31import string
32
33import download
34import error
35import execute
36import git
37import log
38import macros
39import path
40import sources
41import sys
42
43import version
44
45basepath = 'sb'
46
47#
48# Save the host and POSIX state.
49#
50host_windows = False
51host_posix = True
52
53class command_line:
54    """Process the command line in a common way for all Tool Builder commands."""
55
56    def __init__(self, argv, optargs, _defaults, command_path):
57        self._long_opts = {
58            # key                       macro                handler            param  defs   init
59            '--prefix'               : ('_prefix',           self._lo_path,     True,  None,  False),
60            '--topdir'               : ('_topdir',           self._lo_path,     True,  None,  False),
61            '--configdir'            : ('_configdir',        self._lo_path,     True,  None,  False),
62            '--builddir'             : ('_builddir',         self._lo_path,     True,  None,  False),
63            '--sourcedir'            : ('_sourcedir',        self._lo_path,     True,  None,  False),
64            '--patchdir'             : ('_patchdir',         self._lo_path,     True,  None,  False),
65            '--tmppath'              : ('_tmppath',          self._lo_path,     True,  None,  False),
66            '--jobs'                 : ('_jobs',             self._lo_jobs,     True,  'max', True),
67            '--log'                  : ('_logfile',          self._lo_string,   True,  None,  False),
68            '--url'                  : ('_url_base',         self._lo_string,   True,  None,  False),
69            '--no-download'          : ('_disable_download', self._lo_bool,     False, '0',   True),
70            '--macros'               : ('_macros',           self._lo_string,   True,  None,  False),
71            '--source-only-download' : ('_source_download',  self._lo_bool,     False, '0',   True),
72            '--targetcflags'         : ('_targetcflags',     self._lo_string,   True,  None,  False),
73            '--targetcxxflags'       : ('_targetcxxflags',   self._lo_string,   True,  None,  False),
74            '--libstdcxxflags'       : ('_libstdcxxflags',   self._lo_string,   True,  None,  False),
75            '--force'                : ('_force',            self._lo_bool,     False, '0',   True),
76            '--quiet'                : ('_quiet',            self._lo_bool,     False, '0',   True),
77            '--trace'                : ('_trace',            self._lo_bool,     False, '0',   True),
78            '--dry-run'              : ('_dry_run',          self._lo_bool,     False, '0',   True),
79            '--warn-all'             : ('_warn_all',         self._lo_bool,     False, '0',   True),
80            '--no-clean'             : ('_no_clean',         self._lo_bool,     False, '0',   True),
81            '--keep-going'           : ('_keep_going',       self._lo_bool,     False, '0',   True),
82            '--always-clean'         : ('_always_clean',     self._lo_bool,     False, '0',   True),
83            '--no-install'           : ('_no_install',       self._lo_bool,     False, '0',   True),
84            '--regression'           : ('_regression',       self._lo_bool,     False, '0',   True),
85            '--host'                 : ('_host',             self._lo_triplets, True,  None,  False),
86            '--build'                : ('_build',            self._lo_triplets, True,  None,  False),
87            '--target'               : ('_target',           self._lo_triplets, True,  None,  False),
88            '--rtems-tools'          : ('_rtems_tools',      self._lo_string,   True,  None,  False),
89            '--rtems-bsp'            : ('_rtems_bsp',        self._lo_string,   True,  None,  False),
90            '--rtems-version'        : ('_rtems_version',    self._lo_string,   True,  None,  False),
91            '--help'                 : (None,                self._lo_help,     False, None,  False)
92            }
93
94        self.command_path = command_path
95        self.command_name = path.basename(argv[0])
96        self.argv = argv
97        self.args = argv[1:]
98        self.optargs = optargs
99        self.defaults = _defaults
100        self.opts = { 'params' : [] }
101        for lo in self._long_opts:
102            self.opts[lo[2:]] = self._long_opts[lo][3]
103            if self._long_opts[lo][4]:
104                self.defaults[self._long_opts[lo][0]] = ('none',
105                                                         'none',
106                                                         self._long_opts[lo][3])
107
108    def __str__(self):
109        def _dict(dd):
110            s = ''
111            ddl = list(dd.keys())
112            ddl.sort()
113            for d in ddl:
114                s += '  ' + d + ': ' + str(dd[d]) + '\n'
115            return s
116
117        s = 'command: ' + self.command() + \
118            '\nargs: ' + str(self.args) + \
119            '\nopts:\n' + _dict(self.opts)
120
121        return s
122
123    def _lo_string(self, opt, macro, value):
124        if value is None:
125            raise error.general('option requires a value: %s' % (opt))
126        self.opts[opt[2:]] = value
127        self.defaults[macro] = value
128
129    def _lo_path(self, opt, macro, value):
130        if value is None:
131            raise error.general('option requires a path: %s' % (opt))
132        value = path.abspath(value)
133        self.opts[opt[2:]] = value
134        self.defaults[macro] = value
135
136    def _lo_jobs(self, opt, macro, value):
137        if value is None:
138            raise error.general('option requires a value: %s' % (opt))
139        ok = False
140        if value in ['max', 'none', 'half']:
141            ok = True
142        else:
143            try:
144                i = int(value)
145                ok = True
146            except:
147                pass
148            if not ok:
149                try:
150                    f = float(value)
151                    ok = True
152                except:
153                    pass
154        if not ok:
155            raise error.general('invalid jobs option: %s' % (value))
156        self.defaults[macro] = value
157        self.opts[opt[2:]] = value
158
159    def _lo_bool(self, opt, macro, value):
160        if value is not None:
161            raise error.general('option does not take a value: %s' % (opt))
162        self.opts[opt[2:]] = '1'
163        self.defaults[macro] = '1'
164
165    def _lo_triplets(self, opt, macro, value):
166        #
167        # This is a target triplet. Run it past config.sub to make make sure it
168        # is ok.  The target triplet is 'cpu-vendor-os'.
169        #
170        e = execute.capture_execution()
171        config_sub = path.join(self.command_path,
172                               basepath, 'config.sub')
173        exit_code, proc, output = e.shell(config_sub + ' ' + value)
174        if exit_code == 0:
175            value = output
176        self.defaults[macro] = ('triplet', 'none', value)
177        self.opts[opt[2:]] = value
178        _cpu = macro + '_cpu'
179        _arch = macro + '_arch'
180        _vendor = macro + '_vendor'
181        _os = macro + '_os'
182        _arch_value = ''
183        _vendor_value = ''
184        _os_value = ''
185        dash = value.find('-')
186        if dash >= 0:
187            _arch_value = value[:dash]
188            value = value[dash + 1:]
189        dash = value.find('-')
190        if dash >= 0:
191            _vendor_value = value[:dash]
192            value = value[dash + 1:]
193        if len(value):
194            _os_value = value
195        self.defaults[_cpu]    = _arch_value
196        self.defaults[_arch]   = _arch_value
197        self.defaults[_vendor] = _vendor_value
198        self.defaults[_os]     = _os_value
199
200    def _lo_help(self, opt, macro, value):
201        self.help()
202
203    def help(self):
204        print('%s: [options] [args]' % (self.command_name))
205        print('RTEMS Source Builder, an RTEMS Tools Project (c) 2012-2019 Chris Johns')
206        print('Options and arguments:')
207        print('--force                : Force the build to proceed')
208        print('--quiet                : Quiet output (not used)')
209        print('--trace                : Trace the execution')
210        print('--dry-run              : Do everything but actually run the build')
211        print('--warn-all             : Generate warnings')
212        print('--no-clean             : Do not clean up the build tree')
213        print('--always-clean         : Always clean the build tree, even with an error')
214        print('--keep-going           : Do not stop on an error.')
215        print('--regression           : Set --no-install, --keep-going and --always-clean')
216        print('--jobs                 : Run with specified number of jobs, default: num CPUs.')
217        print('--host                 : Set the host triplet')
218        print('--build                : Set the build triplet')
219        print('--target               : Set the target triplet')
220        print('--prefix path          : Tools build prefix, ie where they are installed')
221        print('--topdir path          : Top of the build tree, default is $PWD')
222        print('--configdir path       : Path to the configuration directory, default: ./config')
223        print('--builddir path        : Path to the build directory, default: ./build')
224        print('--sourcedir path       : Path to the source directory, default: ./source')
225        print('--patchdir path        : Path to the patches directory, default: ./patches')
226        print('--tmppath path         : Path to the temp directory, default: ./tmp')
227        print('--macros file[,[file]  : Macro format files to load after the defaults')
228        print('--log file             : Log file where all build out is written too')
229        print('--url url[,url]        : URL to look for source')
230        print('--no-download          : Disable the source downloader')
231        print('--no-install           : Do not install the packages to the prefix')
232        print('--targetcflags flags   : List of C flags for the target code')
233        print('--targetcxxflags flags : List of C++ flags for the target code')
234        print('--libstdcxxflags flags : List of C++ flags to build the target libstdc++ code')
235        print('--source-only-download : Only download the source')
236        print('--with-<label>         : Add the --with-<label> to the build')
237        print('--without-<label>      : Add the --without-<label> to the build')
238        print('--rtems-tools path     : Path to an install RTEMS tool set')
239        print('--rtems-bsp arc/bsp    : Standard RTEMS architecure and BSP specifier')
240        print('--rtems-version ver    : The RTEMS major/minor version string')
241        if self.optargs:
242            for a in self.optargs:
243                print('%-22s : %s' % (a, self.optargs[a]))
244        raise error.exit()
245
246    def process(self):
247        for a in self.args:
248            if a == '-?' or a == '--help':
249                self.help()
250        arg = 0
251        while arg < len(self.args):
252            a = self.args[arg]
253            if a.startswith('--'):
254                los = a.split('=', 1)
255                lo = los[0]
256                if lo in self._long_opts:
257                    long_opt = self._long_opts[lo]
258                    if len(los) == 1:
259                        if long_opt[2]:
260                            if arg == len(self.args) - 1:
261                                raise error.general('option requires a parameter: %s' % \
262                                                    (lo))
263                            arg += 1
264                            value = self.args[arg]
265                        else:
266                            value = None
267                    else:
268                        value = '='.join(los[1:])
269                    long_opt[1](lo, long_opt[0], value)
270                else:
271                    if a.startswith('--with'):
272                        if len(los) != 1:
273                            value = los[1]
274                        else:
275                            value = '1'
276                        self.defaults[los[0][2:].replace('-', '_').lower()] = \
277                            ('none', 'none', value)
278                    else:
279                        if lo not in self.optargs:
280                            raise error.general('unknown option: %s' % (lo))
281            else:
282                if a.startswith('-'):
283                    raise error.general('short options not supported; only "-?"')
284                self.opts['params'].append(a)
285            arg += 1
286
287    def pre_process(self):
288        arg = 0
289        while arg < len(self.args):
290            a = self.args[arg]
291            if a == '--source-only-download':
292                self.args += ['--dry-run',
293                              '--with-download',
294                              '--quiet',
295                              '--without-log',
296                              '--without-error-report']
297            if a == '--dry-run':
298                self.args += ['--without-error-report']
299            arg += 1
300
301    def post_process(self, logfile = True):
302        # Handle the log first.
303        logctrl = self.parse_args('--without-log')
304        if logctrl is None:
305            if logfile:
306                logfiles = self.logfiles()
307            else:
308                logfiles = None
309            log.default = log.log(streams = logfiles)
310        if self.trace():
311            log.tracing = True
312        if self.quiet():
313            log.quiet = True
314        # Must have a host
315        if self.defaults['_host'] == self.defaults['nil']:
316            raise error.general('--host not set')
317        # Must have a host
318        if self.defaults['_build'] == self.defaults['nil']:
319            raise error.general('--build not set')
320        # Default prefix
321        prefix = self.parse_args('--prefix')
322        if prefix is None:
323            value = path.join(self.defaults['_prefix'],
324                              'rtems',
325                              str(self.defaults['rtems_version']))
326            self.opts['prefix'] = value
327            self.defaults['_prefix'] = value
328        # Manage the regression option
329        if self.opts['regression'] != '0':
330            self.opts['no-install'] = '1'
331            self.defaults['_no_install'] = '1'
332            self.opts['keep-going'] = '1'
333            self.defaults['_keep_going'] = '1'
334            self.opts['always-clean'] = '1'
335            self.defaults['_always_clean'] = '1'
336        # Handle the jobs for make
337        if '_ncpus' not in self.defaults:
338            raise error.general('host number of CPUs not set')
339        ncpus = self.jobs(self.defaults['_ncpus'])
340        if ncpus > 1:
341            self.defaults['_smp_mflags'] = '-j %d' % (ncpus)
342        else:
343            self.defaults['_smp_mflags'] = self.defaults['nil']
344        # Load user macro files
345        um = self.user_macros()
346        if um:
347            checked = path.exists(um)
348            if False in checked:
349                raise error.general('macro file not found: %s' % \
350                                    (um[checked.index(False)]))
351            for m in um:
352                self.defaults.load(m)
353        # Check if the user has a private set of macros to load
354        if 'RSB_MACROS' in os.environ:
355            if path.exists(os.environ['RSB_MACROS']):
356                self.defaults.load(os.environ['RSB_MACROS'])
357        if 'HOME' in os.environ:
358            rsb_macros = path.join(os.environ['HOME'], '.rsb_macros')
359            if path.exists(rsb_macros):
360                self.defaults.load(rsb_macros)
361
362    def sb_released(self):
363        if version.released():
364            self.defaults['rsb_released'] = '1'
365        self.defaults['rsb_version'] = version.string()
366
367    def sb_git(self):
368        repo = git.repo(self.defaults.expand('%{_sbdir}'), self)
369        if repo.valid():
370            repo_valid = '1'
371            repo_head = repo.head()
372            repo_clean = not repo.dirty()
373            repo_remotes = '%{nil}'
374            remotes = repo.remotes()
375            if 'origin' in remotes:
376                repo_remotes = '%s/origin' % (remotes['origin']['url'])
377            repo_id = repo_head
378            if not repo_clean:
379                repo_id += '-modified'
380            repo_mail = repo.email()
381        else:
382            repo_valid = '0'
383            repo_head = '%{nil}'
384            repo_clean = '%{nil}'
385            repo_remotes = '%{nil}'
386            repo_id = 'no-repo'
387            repo_mail = None
388        self.defaults['_sbgit_valid'] = repo_valid
389        self.defaults['_sbgit_head']  = repo_head
390        self.defaults['_sbgit_clean'] = str(repo_clean)
391        self.defaults['_sbgit_remotes'] = str(repo_remotes)
392        self.defaults['_sbgit_id']    = repo_id
393        if repo_mail is not None:
394            self.defaults['_sbgit_mail'] = repo_mail
395
396    def command(self):
397        return path.join(self.command_path, self.command_name)
398
399    def force(self):
400        return self.opts['force'] != '0'
401
402    def dry_run(self):
403        return self.opts['dry-run'] != '0'
404
405    def set_dry_run(self):
406        self.opts['dry-run'] = '1'
407
408    def quiet(self):
409        return self.opts['quiet'] != '0'
410
411    def trace(self):
412        return self.opts['trace'] != '0'
413
414    def warn_all(self):
415        return self.opts['warn-all'] != '0'
416
417    def keep_going(self):
418        return self.opts['keep-going'] != '0'
419
420    def no_clean(self):
421        return self.opts['no-clean'] != '0'
422
423    def always_clean(self):
424        return self.opts['always-clean'] != '0'
425
426    def no_install(self):
427        return self.opts['no-install'] != '0'
428
429    def canadian_cross(self):
430        _host = self.defaults.expand('%{_host}')
431        _build = self.defaults.expand('%{_build}')
432        _target = self.defaults.expand('%{_target}')
433        #
434        # The removed fix has been put back. I suspect
435        # this was done as a result of another issue that
436        # has been fixed.
437        #
438        return len(_target) and len(_host) and len(_build) \
439            and _host != _build and _host != _target
440
441    def user_macros(self):
442        #
443        # Return something even if it does not exist.
444        #
445        if self.opts['macros'] is None:
446            return None
447        um = []
448        configs = self.defaults.expand('%{_configdir}').split(':')
449        for m in self.opts['macros'].split(','):
450            if path.exists(m):
451                um += [m]
452            else:
453                # Get the expanded config macros then check them.
454                cm = path.expand(m, configs)
455                ccm = path.exists(cm)
456                if True in ccm:
457                    # Pick the first found
458                    um += [cm[ccm.index(True)]]
459                else:
460                    um += [m]
461        return um if len(um) else None
462
463    def jobs(self, cpus):
464        cpus = int(cpus)
465        if self.opts['jobs'] == 'none':
466            cpus = 0
467        elif self.opts['jobs'] == 'max':
468            pass
469        elif self.opts['jobs'] == 'half':
470            cpus = cpus / 2
471        else:
472            ok = False
473            try:
474                i = int(self.opts['jobs'])
475                cpus = i
476                ok = True
477            except:
478                pass
479            if not ok:
480                try:
481                    f = float(self.opts['jobs'])
482                    cpus = f * cpus
483                    ok = True
484                except:
485                    pass
486                if not ok:
487                    raise error.internal('bad jobs option: %s' % (self.opts['jobs']))
488        if cpus <= 0:
489            cpu = 1
490        return cpus
491
492    def params(self):
493        return self.opts['params']
494
495    def parse_args(self, arg, error = True, extra = True):
496        for a in range(0, len(self.args)):
497            if self.args[a].startswith(arg):
498                lhs = None
499                rhs = None
500                if '=' in self.args[a]:
501                    eqs = self.args[a].split('=', 1)
502                    lhs = eqs[0]
503                    if len(eqs) > 2:
504                        rhs = '='.join(eqs[1:])
505                    else:
506                        rhs = eqs[1]
507                elif extra:
508                    lhs = self.args[a]
509                    a += 1
510                    if a < len(self.args):
511                        rhs = self.args[a]
512                return [lhs, rhs]
513            a += 1
514        return None
515
516    def get_arg(self, arg):
517        if self.optargs is None or arg not in self.optargs:
518            return None
519        return self.parse_args(arg)
520
521    def with_arg(self, label, default = 'not-found'):
522        # the default if there is no option for without.
523        result = default
524        for pre in ['with', 'without']:
525            arg_str = '--%s-%s' % (pre, label)
526            arg_label = '%s_%s' % (pre, label)
527            arg = self.parse_args(arg_str, error = False, extra = False)
528            if arg is not None:
529                if arg[1] is  None:
530                    result = 'yes'
531                else:
532                    result = arg[1]
533                break
534        return [arg_label, result]
535
536    def get_config_files(self, config):
537        #
538        # Convert to shell paths and return shell paths.
539        #
540        # @fixme should this use a passed in set of defaults and not
541        #        not the initial set of values ?
542        #
543        config = path.shell(config)
544        if '*' in config or '?' in config:
545            print(config)
546            configdir = path.dirname(config)
547            configbase = path.basename(config)
548            if len(configbase) == 0:
549                configbase = '*'
550            if not configbase.endswith('.cfg'):
551                configbase = configbase + '.cfg'
552            if len(configdir) == 0:
553                configdir = self.macros.expand(self.defaults['_configdir'])
554            configs = []
555            for cp in configdir.split(':'):
556                hostconfigdir = path.host(cp)
557                for f in glob.glob(os.path.join(hostconfigdir, configbase)):
558                    configs += path.shell(f)
559        else:
560            configs = [config]
561        return configs
562
563    def config_files(self):
564        configs = []
565        for config in self.opts['params']:
566            configs.extend(self.get_config_files(config))
567        return configs
568
569    def logfiles(self):
570        if 'log' in self.opts and self.opts['log'] is not None:
571            return self.opts['log'].split(',')
572        return ['rsb-log-%s.txt' % (datetime.datetime.now().strftime('%Y%m%d-%H%M%S'))]
573
574    def urls(self):
575        if self.opts['url'] is not None:
576            return self.opts['url'].split(',')
577        return None
578
579    def download_disabled(self):
580        return self.opts['no-download'] != '0'
581
582    def disable_install(self):
583        self.opts['no-install'] = '1'
584
585    def info(self):
586        s = ' Command Line: %s%s' % (' '.join(self.argv), os.linesep)
587        s += ' Python: %s' % (sys.version.replace('\n', ''))
588        return s
589
590    def log_info(self):
591        log.output(self.info())
592
593    def rtems_options(self):
594        # Check for RTEMS specific helper options.
595        rtems_tools = self.parse_args('--rtems-tools')
596        if rtems_tools is not None:
597            if self.get_arg('--with-tools') is not None:
598                raise error.general('--rtems-tools and --with-tools cannot be used together')
599            self.args.append('--with-tools=%s' % (rtems_tools[1]))
600        rtems_version = self.parse_args('--rtems-version')
601        if rtems_version is None:
602            rtems_version = str(version.version())
603        else:
604            rtems_version = rtems_version[1]
605        self.defaults['rtems_version'] = rtems_version
606        rtems_arch_bsp = self.parse_args('--rtems-bsp')
607        if rtems_arch_bsp is not None:
608            if self.get_arg('--target') is not None:
609                raise error.general('--rtems-bsp and --target cannot be used together')
610            ab = rtems_arch_bsp[1].split('/')
611            if len(ab) != 2:
612                raise error.general('invalid --rtems-bsp option')
613            self.args.append('--target=%s-rtems%s' % (ab[0], rtems_version))
614            self.args.append('--with-rtems-bsp=%s' % (ab[1]))
615
616def load(args, optargs = None, defaults = '%{_sbdir}/defaults.mc', logfile = True):
617    """
618    Copy the defaults, get the host specific values and merge them overriding
619    any matching defaults, then create an options object to handle the command
620    line merging in any command line overrides. Finally post process the
621    command line.
622    """
623
624    global host_windows
625    global host_posix
626
627    #
628    # Adjust the args to remove the wrapper.
629    #
630    args = args[1:]
631
632    #
633    # The path to this command.
634    #
635    command_path = path.dirname(path.abspath(args[0]))
636    if len(command_path) == 0:
637        command_path = '.'
638
639    #
640    # The command line contains the base defaults object all build objects copy
641    # and modify by loading a configuration.
642    #
643    o = command_line(args,
644                     optargs,
645                     macros.macros(name = defaults,
646                                   sbdir = command_path),
647                     command_path)
648
649    overrides = None
650    if os.name == 'nt':
651        try:
652            import windows
653            overrides = windows.load()
654            host_windows = True
655            host_posix = False
656        except:
657            raise error.general('failed to load Windows host support')
658    elif os.name == 'posix':
659        uname = os.uname()
660        try:
661            if uname[0].startswith('MINGW64_NT'):
662                import windows
663                overrides = windows.load()
664                host_windows = True
665            elif uname[0].startswith('CYGWIN_NT'):
666                import windows
667                overrides = windows.load()
668            elif uname[0] == 'Darwin':
669                import darwin
670                overrides = darwin.load()
671            elif uname[0] == 'FreeBSD':
672                import freebsd
673                overrides = freebsd.load()
674            elif uname[0] == 'NetBSD':
675                import netbsd
676                overrides = netbsd.load()
677            elif uname[0] == 'Linux':
678                import linux
679                overrides = linux.load()
680            elif uname[0] == 'SunOS':
681                import solaris
682                overrides = solaris.load()
683        except error.general as ge:
684            raise error.general('failed to load %s host support: %s' % (uname[0], ge))
685        except:
686            raise error.general('failed to load %s host support' % (uname[0]))
687    else:
688        raise error.general('unsupported host type; please add')
689    if overrides is None:
690        raise error.general('no hosts defaults found; please add')
691    for k in overrides:
692        o.defaults[k] = overrides[k]
693
694    o.sb_released()
695    o.sb_git()
696    o.rtems_options()
697    o.pre_process()
698    o.process()
699    o.post_process(logfile)
700
701    #
702    # Load the release settings
703    #
704    def setting_error(msg):
705        raise error.general(msg)
706    hashes = version.load_release_settings('hashes')
707    for hash in hashes:
708        hs = hash[1].split()
709        if len(hs) != 2:
710            raise error.general('invalid release hash in VERSION')
711        sources.hash((hs[0], hash[0], hs[1]), o.defaults, setting_error)
712    release_path = version.load_release_setting('version', 'release_path',
713                                                raw = True)
714    if release_path is not None:
715        try:
716            release_path = ','.join([rp.strip() for rp in release_path.split(',')])
717        except:
718            raise error.general('invalid release path in VERSION')
719        download.set_release_path(release_path, o.defaults)
720    return o
721
722def run(args):
723    try:
724        _opts = load(args = args, defaults = 'defaults.mc')
725        log.notice('RTEMS Source Builder - Defaults, %s' % (version.string()))
726        _opts.log_info()
727        log.notice('Options:')
728        log.notice(str(_opts))
729        log.notice('Defaults:')
730        log.notice(str(_opts.defaults))
731        log.notice('with-opt1: %r' % (_opts.with_arg('opt1')))
732        log.notice('without-opt2: %r' % (_opts.with_arg('opt2')))
733    except error.general as gerr:
734        print(gerr)
735        sys.exit(1)
736    except error.internal as ierr:
737        print(ierr)
738        sys.exit(1)
739    except error.exit as eerr:
740        pass
741    except KeyboardInterrupt:
742        _notice(opts, 'abort: user terminated')
743        sys.exit(1)
744    sys.exit(0)
745
746if __name__ == '__main__':
747    run(sys.argv)
Note: See TracBrowser for help on using the repository browser.