# # RTEMS Tools Project (http://www.rtems.org/) # Copyright 2010-2013 Chris Johns (chrisj@rtems.org) # All rights reserved. # # This file is part of the RTEMS Tools package in 'rtems-tools'. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # # Determine the defaults and load the specific file. # import datetime import glob import pprint import re import os import string import error import execute import git import log import macros import path import sys import version basepath = 'sb' # # Save the host state. # host_windows = False class command_line: """Process the command line in a common way for all Tool Builder commands.""" def __init__(self, argv, optargs, _defaults, command_path): self._long_opts = { # key macro handler param defs init '--prefix' : ('_prefix', self._lo_path, True, None, False), '--topdir' : ('_topdir', self._lo_path, True, None, False), '--configdir' : ('_configdir', self._lo_path, True, None, False), '--builddir' : ('_builddir', self._lo_path, True, None, False), '--sourcedir' : ('_sourcedir', self._lo_path, True, None, False), '--tmppath' : ('_tmppath', self._lo_path, True, None, False), '--jobs' : ('_jobs', self._lo_jobs, True, 'max', True), '--log' : ('_logfile', self._lo_string, True, None, False), '--url' : ('_url_base', self._lo_string, True, None, False), '--no-download' : ('_disable_download', self._lo_bool, False, '0', True), '--macros' : ('_macros', self._lo_string, True, None, False), '--targetcflags' : ('_targetcflags', self._lo_string, True, None, False), '--targetcxxflags' : ('_targetcxxflags', self._lo_string, True, None, False), '--libstdcxxflags' : ('_libstdcxxflags', self._lo_string, True, None, False), '--force' : ('_force', self._lo_bool, False, '0', True), '--quiet' : ('_quiet', self._lo_bool, False, '0', True), '--trace' : ('_trace', self._lo_bool, False, '0', True), '--dry-run' : ('_dry_run', self._lo_bool, False, '0', True), '--warn-all' : ('_warn_all', self._lo_bool, False, '0', True), '--no-clean' : ('_no_clean', self._lo_bool, False, '0', True), '--keep-going' : ('_keep_going', self._lo_bool, False, '0', True), '--always-clean' : ('_always_clean', self._lo_bool, False, '0', True), '--no-install' : ('_no_install', self._lo_bool, False, '0', True), '--regression' : ('_regression', self._lo_bool, False, '0', True), '--host' : ('_host', self._lo_triplets, True, None, False), '--build' : ('_build', self._lo_triplets, True, None, False), '--target' : ('_target', self._lo_triplets, True, None, False), '--help' : (None, self._lo_help, False, None, False) } self.command_path = command_path self.command_name = path.basename(argv[0]) self.argv = argv self.args = argv[1:] self.optargs = optargs self.defaults = _defaults self.opts = { 'params' : [] } for lo in self._long_opts: self.opts[lo[2:]] = self._long_opts[lo][3] if self._long_opts[lo][4]: self.defaults[self._long_opts[lo][0]] = ('none', 'none', self._long_opts[lo][3]) def __str__(self): def _dict(dd): s = '' ddl = dd.keys() ddl.sort() for d in ddl: s += ' ' + d + ': ' + str(dd[d]) + '\n' return s s = 'command: ' + self.command() + \ '\nargs: ' + str(self.args) + \ '\nopts:\n' + _dict(self.opts) return s def _lo_string(self, opt, macro, value): if value is None: raise error.general('option requires a value: %s' % (opt)) self.opts[opt[2:]] = value self.defaults[macro] = value def _lo_path(self, opt, macro, value): if value is None: raise error.general('option requires a path: %s' % (opt)) value = path.abspath(value) self.opts[opt[2:]] = value self.defaults[macro] = value def _lo_jobs(self, opt, macro, value): if value is None: raise error.general('option requires a value: %s' % (opt)) ok = False if value in ['max', 'none', 'half']: ok = True else: try: i = int(value) ok = True except: pass if not ok: try: f = float(value) ok = True except: pass if not ok: raise error.general('invalid jobs option: %s' % (value)) self.defaults[macro] = value self.opts[opt[2:]] = value def _lo_bool(self, opt, macro, value): if value is not None: raise error.general('option does not take a value: %s' % (opt)) self.opts[opt[2:]] = '1' self.defaults[macro] = '1' def _lo_triplets(self, opt, macro, value): # # This is a target triplet. Run it past config.sub to make make sure it # is ok. The target triplet is 'cpu-vendor-os'. # e = execute.capture_execution() config_sub = path.join(self.command_path, basepath, 'config.sub') exit_code, proc, output = e.shell(config_sub + ' ' + value) if exit_code == 0: value = output self.defaults[macro] = ('triplet', 'none', value) self.opts[opt[2:]] = value _cpu = macro + '_cpu' _arch = macro + '_arch' _vendor = macro + '_vendor' _os = macro + '_os' _arch_value = '' _vendor_value = '' _os_value = '' dash = value.find('-') if dash >= 0: _arch_value = value[:dash] value = value[dash + 1:] dash = value.find('-') if dash >= 0: _vendor_value = value[:dash] value = value[dash + 1:] if len(value): _os_value = value self.defaults[_cpu] = _arch_value self.defaults[_arch] = _arch_value self.defaults[_vendor] = _vendor_value self.defaults[_os] = _os_value def _lo_help(self, opt, macro, value): self.help() def help(self): print '%s: [options] [args]' % (self.command_name) print 'RTEMS Source Builder, an RTEMS Tools Project (c) 2012-2015 Chris Johns' print 'Options and arguments:' print '--force : Force the build to proceed' print '--quiet : Quiet output (not used)' print '--trace : Trace the execution' print '--dry-run : Do everything but actually run the build' print '--warn-all : Generate warnings' print '--no-clean : Do not clean up the build tree' print '--always-clean : Always clean the build tree, even with an error' print '--keep-going : Do not stop on an error.' print '--regression : Set --no-install, --keep-going and --always-clean' print '--jobs : Run with specified number of jobs, default: num CPUs.' print '--host : Set the host triplet' print '--build : Set the build triplet' print '--target : Set the target triplet' print '--prefix path : Tools build prefix, ie where they are installed' print '--topdir path : Top of the build tree, default is $PWD' print '--configdir path : Path to the configuration directory, default: ./config' print '--builddir path : Path to the build directory, default: ./build' print '--sourcedir path : Path to the source directory, default: ./source' print '--tmppath path : Path to the temp directory, default: ./tmp' print '--macros file[,[file] : Macro format files to load after the defaults' print '--log file : Log file where all build out is written too' print '--url url[,url] : URL to look for source' print '--no-download : Disable the source downloader' print '--no-install : Do not install the packages to the prefix' print '--targetcflags flags : List of C flags for the target code' print '--targetcxxflags flags : List of C++ flags for the target code' print '--libstdcxxflags flags : List of C++ flags to build the target libstdc++ code' print '--with-