source: rtems-source-builder/source-builder/sb/defaults.py @ ee203a1

4.104.114.95
Last change on this file since ee203a1 was ee203a1, checked in by Chris Johns <chrisj@…>, on 04/01/13 at 04:35:51

Save the original path away.

  • Property mode set to 100644
File size: 28.2 KB
Line 
1#
2# RTEMS Tools Project (http://www.rtems.org/)
3# Copyright 2010-2012 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
24import glob
25import pprint
26import re
27import os
28
29import error
30import execute
31import git
32import path
33import sys
34
35basepath = 'sb'
36
37#
38# All paths in defaults must be Unix format. Do not store any Windows format
39# paths in the defaults.
40#
41# Every entry must describe the type of checking a host must pass.
42#
43
44defaults = {
45# Nothing
46'nil':                 ('none', 'none', ''),
47
48# Set to invalid values.
49'_bset':               ('none',    'none', ''),
50'name':                ('none',    'none', ''),
51'version':             ('none',    'none', ''),
52'release':             ('none',    'none', ''),
53
54# GNU triples needed to build packages
55'_host':               ('triplet', 'required', ''),
56'_build':              ('triplet', 'required', '%{_host}'),
57'_target':             ('none',    'optional', ''),
58
59# Paths
60'_host_platform':      ('none',    'none',     '%{_host_cpu}-%{_host_vendor}-%{_host_os}%{?_gnu}'),
61'_arch':               ('none',    'none',     '%{_host_arch}'),
62'_sbdir':              ('none',    'none',     ''),
63'_topdir':             ('dir',     'required',  path.shell(os.getcwd())),
64'_configdir':          ('dir',     'optional', '%{_topdir}/config:%{_sbdir}/config'),
65'_tardir':             ('dir',     'optional', '%{_topdir}/tar'),
66'_sourcedir':          ('dir',     'optional', '%{_topdir}/sources'),
67'_patchdir':           ('dir',     'optional', '%{_topdir}/patches:%{_sbdir}/patches'),
68'_builddir':           ('dir',     'optional', '%{_topdir}/build/%{name}-%{version}-%{release}'),
69'_buildcxcdir':        ('dir',     'optional', '%{_topdir}/build/%{name}-%{version}-%{release}-cxc'),
70'_docdir':             ('dir',     'none',     '%{_defaultdocdir}'),
71'_tmppath':            ('dir',     'none',     '%{_topdir}/build/tmp'),
72'_tmproot':            ('dir',     'none',     '%{_tmppath}/source-build-%(%{__id_u} -n)/%{_bset}'),
73'_tmpcxcroot':         ('dir',     'none',     '%{_tmppath}/source-build-%(%{__id_u} -n)-cxc/%{_bset}'),
74'buildroot':           ('dir',     'none',     '%{_tmppath}/%{name}-root-%(%{__id_u} -n)'),
75'buildcxcroot':        ('dir',     'none',     '%{_tmppath}/%{name}-root-%(%{__id_u} -n)-cxc'),
76'_datadir':            ('dir',     'none',     '%{_prefix}/share'),
77'_defaultdocdir':      ('dir',     'none',     '%{_prefix}/share/doc'),
78'_exeext':             ('none',    'none',     ''),
79'_exec_prefix':        ('dir',     'none',     '%{_prefix}'),
80'_bindir':             ('dir',     'none',     '%{_exec_prefix}/bin'),
81'_sbindir':            ('dir',     'none',     '%{_exec_prefix}/sbin'),
82'_libexecdir':         ('dir',     'none',     '%{_exec_prefix}/libexec'),
83'_datarootdir':        ('dir',     'none',     '%{_prefix}/share'),
84'_datadir':            ('dir',     'none',     '%{_datarootdir}'),
85'_sysconfdir':         ('dir',     'none',     '%{_prefix}/etc'),
86'_sharedstatedir':     ('dir',     'none',     '%{_prefix}/com'),
87'_localstatedir':      ('dir',     'none',     '%{prefix}/var'),
88'_includedir':         ('dir',     'none',     '%{_prefix}/include'),
89'_lib':                ('dir',     'none',     'lib'),
90'_libdir':             ('dir',     'none',     '%{_exec_prefix}/%{_lib}'),
91'_libexecdir':         ('dir',     'none',     '%{_exec_prefix}/libexec'),
92'_mandir':             ('dir',     'none',     '%{_datarootdir}/man'),
93'_infodir':            ('dir',     'none',     '%{_datarootdir}/info'),
94'_localedir':          ('dir',     'none',     '%{_datarootdir}/locale'),
95'_localedir':          ('dir',     'none',     '%{_datadir}/locale'),
96'_localstatedir':      ('dir',     'none',     '%{_prefix}/var'),
97'_prefix':             ('dir',     'none',     '%{_usr}'),
98'_usr':                ('dir',     'none',     '/usr/local'),
99'_usrsrc':             ('dir',     'none',     '%{_usr}/src'),
100'_var':                ('dir',     'none',     '/usr/local/var'),
101'_varrun':             ('dir',     'none',     '%{_var}/run'),
102
103# Defaults, override in platform specific modules.
104'___setup_shell':      ('exe',     'required', '/bin/sh'),
105'__aclocal':           ('exe',     'optional', 'aclocal'),
106'__ar':                ('exe',     'required', 'ar'),
107'__arch_install_post': ('exe',     'none',     '%{nil}'),
108'__as':                ('exe',     'required', 'as'),
109'__autoconf':          ('exe',     'required', 'autoconf'),
110'__autoheader':        ('exe',     'required', 'autoheader'),
111'__automake':          ('exe',     'required', 'automake'),
112'__awk':               ('exe',     'required', 'awk'),
113'__bash':              ('exe',     'optional', '/bin/bash'),
114'__bison':             ('exe',     'required', '/usr/bin/bison'),
115'__bzip2':             ('exe',     'required', '/usr/bin/bzip2'),
116'__cat':               ('exe',     'required', '/bin/cat'),
117'__cc':                ('exe',     'required', '/usr/bin/gcc'),
118'__chgrp':             ('exe',     'required', '/usr/bin/chgrp'),
119'__chmod':             ('exe',     'required', '/bin/chmod'),
120'__chown':             ('exe',     'required', '/usr/sbin/chown'),
121'__cp':                ('exe',     'required', '/bin/cp'),
122'__cpp':               ('exe',     'none',     '%{__cc} -E'),
123'__cxx':               ('exe',     'required', '/usr/bin/g++'),
124'__flex':              ('exe',     'required', '/usr/bin/flex'),
125'__git':               ('exe',     'required', '/usr/bin/git'),
126'__grep':              ('exe',     'required', '/usr/bin/grep'),
127'__gzip':              ('exe',     'required', '/usr/bin/gzip'),
128'__id':                ('exe',     'required', '/usr/bin/id'),
129'__id_u':              ('exe',     'none',     '%{__id} -u'),
130'__install':           ('exe',     'required', '/usr/bin/install'),
131'__install_info':      ('exe',     'optional', '/usr/bin/install-info'),
132'__ld':                ('exe',     'required', '/usr/bin/ld'),
133'__ldconfig':          ('exe',     'required', '/sbin/ldconfig'),
134'__ln_s':              ('exe',     'none',     'ln -s'),
135'__make':              ('exe',     'required', 'make'),
136'__makeinfo':          ('exe',     'required', '/usr/bin/makeinfo'),
137'__mkdir':             ('exe',     'required', '/bin/mkdir'),
138'__mkdir_p':           ('exe',     'none',     '/bin/mkdir -p'),
139'__mv':                ('exe',     'required', '/bin/mv'),
140'__nm':                ('exe',     'required', '/usr/bin/nm'),
141'__objcopy':           ('exe',     'optional', '/usr/bin/objcopy'),
142'__objdump':           ('exe',     'optional', '/usr/bin/objdump'),
143'__patch_bin':         ('exe',     'required', '/usr/bin/patch'),
144'__patch_opts':        ('none',    'none',     '%{nil}'),
145'__patch':             ('exe',     'none',     '%{__patch_bin} %{__patch_opts}'),
146'__perl':              ('exe',     'optional', 'perl'),
147'__ranlib':            ('exe',     'required', 'ranlib'),
148'__rm':                ('exe',     'required', '/bin/rm'),
149'__rmfile':            ('exe',     'none',     '%{__rm} -f'),
150'__rmdir':             ('exe',     'none',     '%{__rm} -rf'),
151'__sed':               ('exe',     'required', '/usr/bin/sed'),
152'__setup_post':        ('exe',     'none',     '%{__chmod} -R a+rX,g-w,o-w .'),
153'__sh':                ('exe',     'required', '/bin/sh'),
154'__tar':               ('exe',     'required', '/usr/bin/tar'),
155'__tar_extract':       ('exe',     'none',     '%{__tar} -xvvf'),
156'__touch':             ('exe',     'required', '/usr/bin/touch'),
157'__unzip':             ('exe',     'required', '/usr/bin/unzip'),
158'__xz':                ('exe',     'required', '/usr/bin/xz'),
159
160# Shell Build Settings.
161'___build_args': ('none', 'none', '-e'),
162'___build_cmd':  ('none', 'none', '%{?_sudo:%{_sudo} }%{?_remsh:%{_remsh} %{_remhost} }%{?_remsudo:%{_remsudo} }%{?_remchroot:%{_remchroot} %{_remroot} }%{___build_shell} %{___build_args}'),
163'___build_post': ('none', 'none', 'exit 0'),
164
165# Prebuild set up script.
166'___build_pre': ('none', 'none', '''# ___build_pre in as set up in defaults.py
167# Save the original path away.
168export SB_ORIG_PATH=${PATH}
169# Directories
170%{?_prefix:SB_PREFIX="%{_prefix}"}
171%{?_prefix:SB_PREFIX_CLEAN=$(echo "%{_prefix}" | %{__sed} -e \'s/^\///\')}
172SB_SOURCE_DIR="%{_sourcedir}"
173SB_BUILD_DIR="%{_builddir}"
174SB_OPT_FLAGS="%{?_tmproot:-I%{_tmproot}/${SB_PREFIX_CLEAN}/include -L%{_tmproot}/${SB_PREFIX_CLEAN}/lib} %{optflags}"
175SB_ARCH="%{_arch}"
176SB_OS="%{_os}"
177export SB_SOURCE_DIR SB_BUILD_DIR SB_OPT_FLAGS SB_ARCH SB_OS
178# Documentation
179SB_DOC_DIR="%{_docdir}"
180export SB_DOC_DIR
181# Packages
182SB_PACKAGE_NAME="%{name}"
183SB_PACKAGE_VERSION="%{version}"
184SB_PACKAGE_RELEASE="%{release}"
185export SB_PACKAGE_NAME SB_PACKAGE_VERSION SB_PACKAGE_RELEASE
186# Build directories
187export SB_PREFIX
188%{?_builddir:SB_BUILD_DIR="%{_builddir}"}
189%{?buildroot:SB_BUILD_ROOT="%{buildroot}"}
190%{?buildroot:%{?_prefix:SB_BUILD_ROOT_BINDIR="%{buildroot}/${SB_PREFIX_CLEAN}/bin"}}
191export SB_BUILD_ROOT SB_BUILD_DIR SB_BUILD_ROOT_BINDIR
192%{?_buildcxcdir:SB_BUILD_CXC_DIR="%{_buildcxcdir}"}
193%{?buildcxcroot:SB_BUILD_CXC_ROOT="%{buildcxcroot}"}
194%{?buildcxcroot:%{?_prefix:SB_BUILD_CXC_ROOT_BINDIR="%{buildcxcroot}/${SB_PREFIX_CLEAN}/bin"}}
195export SB_BUILD_CXC_ROOT SB_BUILD_CXC_DIR SB_BUILD_CXC_ROOT_BINDIR
196%{?_tmproot:SB_TMPROOT="%{_tmproot}"}
197%{?_tmproot:%{?_prefix:SB_TMPPREFIX="%{_tmproot}/${SB_PREFIX_CLEAN}"}}
198%{?_tmproot:%{?_prefix:SB_TMPBINDIR="%{_tmproot}/${SB_PREFIX_CLEAN}/bin"}}
199export SB_TMPROOT SB_TMPPREFIX SB_TMPBINDIR
200%{?_tmpcxcroot:SB_TMPCXCROOT="%{_tmproot}"}
201%{?_tmpcxcroot:%{?_prefix:SB_TMPCXCPREFIX="%{_tmpcxcroot}/${SB_PREFIX_CLEAN}"}}
202%{?_tmpcxcroot:%{?_prefix:SB_TMPCXCBINDIR="%{_tmpcxcroot}/${SB_PREFIX_CLEAN}/bin"}}
203export SB_TMPCXCROOT SB_TMPCXCPREFIX SB_TMPCXCBINDIR
204# The compiler flags
205%{?_targetcflags:CFLAGS_FOR_TARGET="%{_targetcflags}"}
206%{?_targetcxxflags:CXXFLAGS_FOR_TARGET="%{_targetcxxflags}"}
207export CFLAGS_FOR_TARGET
208export CXXFLAGS_FOR_TARGET
209# Set up the path. Put the CXC path first.
210if test -n "${SB_TMPBINDIR}" ; then
211 PATH="${SB_TMPBINDIR}:$PATH"
212fi
213if test -n "${SB_TMPCXCBINDIR}" ; then
214 PATH="${SB_TMPCXCBINDIR}:$PATH"
215fi
216export PATH
217# Default environment set up.
218LANG=C
219export LANG
220unset DISPLAY || :
221umask 022
222cd "%{_builddir}"'''),
223'___build_shell': ('none', 'none', '%{?_buildshell:%{_buildshell}}%{!?_buildshell:/bin/sh}'),
224'___build_template': ('none', 'none', '''#!%{___build_shell}
225%{___build_pre}
226%{nil}'''),
227
228# Configure command
229'configure': ('none', 'none', '''
230CFLAGS="${CFLAGS:-%optflags}" ; export CFLAGS ;
231CXXFLAGS="${CXXFLAGS:-%optflags}" ; export CXXFLAGS ;
232FFLAGS="${FFLAGS:-%optflags}" ; export FFLAGS ;
233./configure --build=%{_build} --host=%{_host} \
234      --target=%{_target_platform} \
235      --program-prefix=%{?_program_prefix} \
236      --prefix=%{_prefix} \
237      --exec-prefix=%{_exec_prefix} \
238      --bindir=%{_bindir} \
239      --sbindir=%{_sbindir} \
240      --sysconfdir=%{_sysconfdir} \
241      --datadir=%{_datadir} \
242      --includedir=%{_includedir} \
243      --libdir=%{_libdir} \
244      --libexecdir=%{_libexecdir} \
245      --localstatedir=%{_localstatedir} \
246      --sharedstatedir=%{_sharedstatedir} \
247      --mandir=%{_mandir} \
248      --infodir=%{_infodir}''')
249}
250
251class command_line:
252    """Process the command line in a common way for all Tool Builder commands."""
253
254    #
255    # The define and if it is a path and needs conversion.
256    #
257    _long_opts = { '--prefix'         : ('_prefix', True),
258                   '--prefixbase'     : ('_prefixbase', True),
259                   '--topdir'         : ('_topdir', True),
260                   '--configdir'      : ('_configdir', True),
261                   '--builddir'       : ('_builddir', True),
262                   '--sourcedir'      : ('_sourcedir', True),
263                   '--tmppath'        : ('_tmppath', True),
264                   '--log'            : ('_logfile', False),
265                   '--url'            : ('_url_base', False),
266                   '--targetcflags'   : ('_targetcflags', False),
267                   '--targetcxxflags' : ('_targetcxxflags', False),
268                   '--libstdcxxflags' : ('_libstdcxxflags', False) }
269
270    _long_true_opts = { '--force'    : '_force',
271                        '--trace'    : '_trace',
272                        '--dry-run'  : '_dry_run',
273                        '--warn-all' : '_warn_all',
274                        '--no-clean' : '_no_clean',
275                        '--no-smp'   : '_no_smp',
276                        '--rebuild'  : '_rebuild' }
277
278    _target_triplets = { '--host'   : '_host',
279                         '--build'  : '_build',
280                         '--target' : '_target' }
281
282    def _help(self):
283        print '%s: [options] [args]' % (self.command_name)
284        print 'RTEMS Source Builder, an RTEMS Tools Project (c) 2012-2013 Chris Johns'
285        print 'Options and arguments:'
286        print '--force                : Force the build to proceed'
287        print '--trace                : Trace the execution (not current used)'
288        print '--dry-run              : Do everything but actually run the build'
289        print '--warn-all             : Generate warnings'
290        print '--no-clean             : Do not clean up the build tree'
291        print '--no-smp               : Run with 1 job and not as many as CPUs'
292        print '--rebuild              : Rebuild (not used)'
293        print '--host                 : Set the host triplet'
294        print '--build                : Set the build triplet'
295        print '--target               : Set the target triplet'
296        print '--prefix path          : Tools build prefix, ie where they are installed'
297        print '--prefixbase path      : '
298        print '--topdir path          : Top of the build tree, default is $PWD'
299        print '--configdir path       : Path to the configuration directory, default: ./config'
300        print '--builddir path        : Path to the build directory, default: ./build'
301        print '--sourcedir path       : Path to the source directory, default: ./source'
302        print '--tmppath path         : Path to the temp directory, default: ./tmp'
303        print '--log file             : Log file where all build out is written too'
304        print '--url url              : URL to look for source'
305        print '--targetcflags flags   : List of C flags for the target code'
306        print '--targetcxxflags flags : List of C++ flags for the target code'
307        print '--libstdcxxflags flags : List of C++ flags to build the target libstdc++ code'
308        print '--with-<label>         : Add the --with-<label> to the build'
309        print '--without-<label>      : Add the --without-<label> to the build'
310        if self.optargs:
311            for a in self.optargs:
312                print '%-22s : %s' % (a, self.optargs[a])
313        raise error.exit()
314
315    def __init__(self, argv, optargs):
316        self.command_path = path.dirname(argv[0])
317        if len(self.command_path) == 0:
318            self.command_path = '.'
319        self.command_name = path.basename(argv[0])
320        self.argv = argv
321        self.args = argv[1:]
322        self.optargs = optargs
323        self.defaults = {}
324        for to in command_line._long_true_opts:
325            self.defaults[command_line._long_true_opts[to]] = ('none', 'none', '0')
326        self.defaults['_sbdir'] = ('dir', 'required', path.shell(self.command_path))
327        self.opts = { 'params'   : [],
328                      'warn-all' : '0',
329                      'quiet'    : '0',
330                      'force'    : '0',
331                      'trace'    : '0',
332                      'dry-run'  : '0',
333                      'no-clean' : '0',
334                      'no-smp'   : '0',
335                      'rebuild'  : '0' }
336        self._process()
337
338    def __str__(self):
339        def _dict(dd):
340            s = ''
341            ddl = dd.keys()
342            ddl.sort()
343            for d in ddl:
344                s += '  ' + d + ': ' + str(dd[d]) + '\n'
345            return s
346
347        s = 'command: ' + self.command() + \
348            '\nargs: ' + str(self.args) + \
349            '\nopts:\n' + _dict(self.opts)
350
351        return s
352
353    def _process(self):
354
355        def _process_lopt(opt, arg, long_opts, args, values = False):
356            for lo in long_opts:
357                if values and opt.startswith(lo):
358                    equals = opt.find('=')
359                    if equals < 0:
360                        if arg == len(args) - 1:
361                            raise error.general('missing option value: ' + lo)
362                        arg += 1
363                        value = args[arg]
364                    else:
365                        value = opt[equals + 1:]
366                    if type(long_opts[lo]) is tuple:
367                        if long_opts[lo][1]:
368                            value = path.shell(value)
369                        macro = long_opts[lo][0]
370                    else:
371                        macro = long_opts[lo]
372                    return lo, macro, value, arg
373                elif opt == lo:
374                    return lo, long_opts[lo], True, arg
375            return None, None, None, arg
376
377        i = 0
378        while i < len(self.args):
379            a = self.args[i]
380            if a.startswith('-'):
381                if a.startswith('--'):
382                    if a.startswith('--warn-all'):
383                        self.opts['warn-all'] = True
384                    elif a == '--help':
385                        self._help()
386                    else:
387                        lo, macro, value, i = _process_lopt(a, i,
388                                                            command_line._long_true_opts,
389                                                            self.args)
390                        if lo:
391                            self.defaults[macro] = ('none', 'none', '1')
392                            self.opts[lo[2:]] = '1'
393                        else:
394                            lo, macro, value, i = _process_lopt(a, i,
395                                                                command_line._long_opts,
396                                                                self.args, True)
397                            if lo:
398                                self.defaults[macro] = ('none', 'none', value)
399                                self.opts[lo[2:]] = value
400                            else:
401                                #
402                                # The target triplet is 'cpu-vendor-os'.
403                                #
404                                lo, macro, value, i = _process_lopt(a, i,
405                                                                    command_line._target_triplets,
406                                                                    self.args, True)
407                                if lo:
408                                    #
409                                    # This is a target triplet. Run it past config.sub to make
410                                    # make sure it is ok.
411                                    #
412                                    e = execute.capture_execution()
413                                    config_sub = path.join(self.command_path,
414                                                           basepath, 'config.sub')
415                                    exit_code, proc, output = e.shell(config_sub + ' ' + value)
416                                    if exit_code == 0:
417                                        value = output
418                                    self.defaults[macro] = ('triplet', 'none', value)
419                                    self.opts[lo[2:]] = value
420                                    _arch = macro + '_cpu'
421                                    _vendor = macro + '_vendor'
422                                    _os = macro + '_os'
423                                    _arch_value = ''
424                                    _vendor_value = ''
425                                    _os_value = ''
426                                    dash = value.find('-')
427                                    if dash >= 0:
428                                        _arch_value = value[:dash]
429                                        value = value[dash + 1:]
430                                    dash = value.find('-')
431                                    if dash >= 0:
432                                        _vendor_value = value[:dash]
433                                        value = value[dash + 1:]
434                                    if len(value):
435                                        _os_value = value
436                                    self.defaults[_arch] = ('none', 'none', _arch_value)
437                                    self.defaults[_vendor] = ('none', 'none', _vendor_value)
438                                    self.defaults[_os] = ('none', 'none', _os_value)
439                                if not lo:
440                                    sa = a.split('=')
441                                    if sa[0] not in self.optargs:
442                                        raise error.general('invalid argument (try --help): %s' % (a))
443                else:
444                    if a == '-f':
445                        self.opts['force'] = '1'
446                    elif a == '-n':
447                        self.opts['dry-run'] = '1'
448                    elif a == '-q':
449                        self.opts['quiet'] = '1'
450                    elif a == '-?':
451                        self._help()
452                    else:
453                        raise error.general('invalid argument (try --help): %s' % (a))
454            else:
455                self.opts['params'].append(a)
456            i += 1
457
458    def _post_process(self, _defaults):
459        if self.no_smp():
460            _defaults['_smp_mflags'] = ('none', 'none', _defaults['nil'][2])
461        if _defaults['_host'][2] == _defaults['nil'][2]:
462            raise error.general('host not set')
463        return _defaults
464
465    def define(self, _defaults, key, value = '1'):
466        _defaults[key] = ('none', 'none', value)
467
468    def undefine(self, _defaults, key):
469        if key in _defaults:
470            del _defaults[key]
471
472    def expand(self, s, _defaults):
473        """Simple basic expander of config file macros."""
474        mf = re.compile(r'%{[^}]+}')
475        expanded = True
476        while expanded:
477            expanded = False
478            for m in mf.findall(s):
479                name = m[2:-1]
480                if name in _defaults:
481                    s = s.replace(m, _defaults[name][2])
482                    expanded = True
483                else:
484                    raise error.general('cannot expand default macro: %s in "%s"' %
485                                        (m, s))
486        return s
487
488    def command(self):
489        return path.join(self.command_path, self.command_name)
490
491    def force(self):
492        return self.opts['force'] != '0'
493
494    def dry_run(self):
495        return self.opts['dry-run'] != '0'
496
497    def set_dry_run(self):
498        self.opts['dry-run'] = '1'
499
500    def quiet(self):
501        return self.opts['quiet'] != '0'
502
503    def trace(self):
504        return self.opts['trace'] != '0'
505
506    def warn_all(self):
507        return self.opts['warn-all'] != '0'
508
509    def no_clean(self):
510        return self.opts['no-clean'] != '0'
511
512    def no_smp(self):
513        return self.opts['no-smp'] != '0'
514
515    def rebuild(self):
516        return self.opts['rebuild'] != '0'
517
518    def params(self):
519        return self.opts['params']
520
521    def get_arg(self, arg):
522        if not arg in self.optargs:
523            raise error.internal('bad arg: %s' % (arg))
524        for a in self.args:
525            sa = a.split('=')
526            if sa[0].startswith(arg):
527                return sa
528        return None
529
530    def get_config_files(self, config):
531        #
532        # Convert to shell paths and return shell paths.
533        #
534        # @fixme should this use a passed in set of defaults and not
535        #        not the initial set of values ?
536        #
537        config = path.shell(config)
538        if '*' in config or '?' in config:
539            print config
540            configdir = path.dirname(config)
541            configbase = path.basename(config)
542            if len(configbase) == 0:
543                configbase = '*'
544            if not configbase.endswith('.cfg'):
545                configbase = configbase + '.cfg'
546            if len(configdir) == 0:
547                configdir = self.expand(self.defaults['_configdir'][2], self.defaults)
548            configs = []
549            for cp in configdir.split(':'):
550                hostconfigdir = path.host(cp)
551                for f in glob.glob(os.path.join(hostconfigdir, configbase)):
552                    configs += path.shell(f)
553        else:
554            configs = [config]
555        return configs
556
557    def config_files(self):
558        configs = []
559        for config in self.opts['params']:
560            configs.extend(self.get_config_files(config))
561        return configs
562
563    def logfiles(self):
564        if 'log' in self.opts:
565            return self.opts['log'].split(',')
566        return ['stdout']
567
568    def urls(self):
569        if 'url' in self.opts:
570            return self.opts['url'].split(',')
571        return None
572
573    def prefixbase(self):
574        if 'prefixbase' in self.opts:
575            return self.opts['prefixbase']
576        return None
577
578def load(args, optargs = None):
579    """
580    Copy the defaults, get the host specific values and merge them overriding
581    any matching defaults, then create an options object to handle the command
582    line merging in any command line overrides. Finally post process the
583    command line.
584    """
585    import copy
586    d = copy.deepcopy(defaults)
587    overrides = None
588    if os.name == 'nt':
589        import windows
590        overrides = windows.load()
591    elif os.name == 'posix':
592        uname = os.uname()
593        try:
594            if uname[0].startswith('CYGWIN_NT'):
595                import windows
596                overrides = windows.load()
597            elif uname[0] == 'Darwin':
598                import darwin
599                overrides = darwin.load()
600            elif uname[0] == 'FreeBSD':
601                import freebsd
602                overrides = freebsd.load()
603            elif uname[0] == 'Linux':
604                import linux
605                overrides = linux.load()
606        except:
607            pass
608    else:
609        raise error.general('unsupported host type; please add')
610    if overrides is None:
611        raise error.general('no hosts defaults found; please add')
612    for k in overrides:
613        d[k] = overrides[k]
614    o = command_line(args, optargs)
615    for k in o.defaults:
616        d[k] = o.defaults[k]
617    d = o._post_process(d)
618    repo = git.repo(o.expand('%{_sbdir}', d), o, d)
619    if repo.valid():
620        repo_valid = '1'
621        repo_head = repo.head()
622        repo_clean = repo.clean()
623        repo_id = repo_head
624        if not repo_clean:
625            repo_id += '-modified'
626    else:
627        repo_valid = '0'
628        repo_head = '%{nil}'
629        repo_clean = '%{nil}'
630        repo_id = 'no-repo'
631    o.define(d, '_sbgit_valid', repo_valid)
632    o.define(d, '_sbgit_head', repo_head)
633    o.define(d, '_sbgit_clean', str(repo_clean))
634    o.define(d, '_sbgit_id', repo_id)
635    return o, d
636
637def run(args):
638    try:
639        _opts, _defaults = load(args = args)
640        print 'Options:'
641        print _opts
642        print 'Defaults:'
643        for k in sorted(_defaults.keys()):
644            d = _defaults[k]
645            print '%-20s: %-8s %-10s' % (k, d[0], d[1]),
646            indent = False
647            if len(d[2]) == 0:
648                print
649            text_len = 80
650            for l in d[2].split('\n'):
651                while len(l):
652                    if indent:
653                        print '%20s  %8s %10s' % (' ', ' ', ' '),
654                    print l[0:text_len],
655                    l = l[text_len:]
656                    if len(l):
657                        print ' \\',
658                    print
659                    indent = True
660    except error.general, gerr:
661        print gerr
662        sys.exit(1)
663    except error.internal, ierr:
664        print ierr
665        sys.exit(1)
666    except error.exit, eerr:
667        pass
668    except KeyboardInterrupt:
669        _notice(opts, 'abort: user terminated')
670        sys.exit(1)
671    sys.exit(0)
672
673if __name__ == '__main__':
674    run(sys.argv)
Note: See TracBrowser for help on using the repository browser.