source: rtems-tools/specbuilder/specbuilder/defaults.py @ f1a0bde

4.104.115
Last change on this file since f1a0bde was f1a0bde, checked in by Chris Johns <chrisj@…>, on 08/13/10 at 04:40:44

2010-08-13 Chris Johns <chrisj@…>

  • specbuilder/specbuilder/defaults.py: Provide a default shell.
  • specbuilder/specbuilder/rtems.py: Provide a default autoconf version.
  • specbuilder/specbuilder/setup.py: Use the default setup shell and check the version of autoconf needed.
  • Property mode set to 100644
File size: 15.2 KB
Line 
1#
2# $Id$
3#
4# RTEMS Tools Project (http://www.rtems.org/)
5# Copyright 2010 Chris Johns (chrisj@rtems.org)
6# All rights reserved.
7#
8# This file is part of the RTEMS Tools package in 'rtems-tools'.
9#
10# RTEMS Tools is free software: you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation, either version 3 of the License, or
13# (at your option) any later version.
14#
15# RTEMS Tools is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with RTEMS Tools.  If not, see <http://www.gnu.org/licenses/>.
22#
23
24#
25# Determine the defaults and load the specific file.
26#
27
28import glob
29import pprint
30import re
31import os
32
33import error
34import execute
35
36defaults = {
37# Hack. Suspect a hidden platform or comand line thing
38'_with_noarch_subpackages': '1',
39
40# Paths
41'_host_platform': '%{_host_cpu}-%{_host_vendor}-%{_host_os}%{?_gnu}',
42'_build':         '%{_host}',
43'_arch':          '%{_host_arch}',
44'_topdir':        os.getcwd(),
45'_srcrpmdir':     '%{_topdir}/SRPMS',
46'_sourcedir':     '%{_topdir}/SOURCES',
47'_specdir':       '%{_topdir}/SPECS',
48'_rpmdir':        '%{_topdir}/TARS',
49'_builddir':      '%{_topdir}/BUILD/%{name}-%{version}-%{release}',
50'_docdir':        '%{_defaultdocdir}',
51'_usrlibrpm':     '%{_topdir}/RPMLIB',
52'_tmppath':       '%{_topdir}/TMP',
53'buildroot:':     '%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)',
54
55# Not sure.
56'_gnu':           '-gnu',
57
58# Cloned stuff from an RPM insall
59'___build_args': '-e',
60'___build_cmd':  '%{?_sudo:%{_sudo} }%{?_remsh:%{_remsh} %{_remhost} }%{?_remsudo:%{_remsudo} }%{?_remchroot:%{_remchroot} %{_remroot} }%{___build_shell} %{___build_args}',
61'___build_post': 'exit 0',
62'___build_pre': '''# ___build_pre in defaults.py
63RPM_SOURCE_DIR="%{_sourcedir}"
64RPM_BUILD_DIR="%{_builddir}"
65RPM_OPT_FLAGS="%{optflags}"
66RPM_ARCH="%{_arch}"
67RPM_OS="%{_os}"
68export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS
69RPM_DOC_DIR="%{_docdir}"
70export RPM_DOC_DIR
71RPM_PACKAGE_NAME="%{name}"
72RPM_PACKAGE_VERSION="%{version}"
73RPM_PACKAGE_RELEASE="%{release}"
74export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION RPM_PACKAGE_RELEASE
75%{?buildroot:RPM_BUILD_ROOT="%{buildroot}"}
76export RPM_BUILD_ROOT
77%{?_javaclasspath:CLASSPATH="%{_javaclasspath}"; export CLASSPATH}
78LANG=C
79export LANG
80unset DISPLAY || :
81umask 022
82cd "%{_builddir}"''',
83'___build_shell': '%{?_buildshell:%{_buildshell}}%{!?_buildshell:/bin/sh}',
84'___build_template': '''#!%{___build_shell}
85%{___build_pre}
86%{nil}''',
87'___setup_shell':      '/bin/sh',
88'__aclocal':           'aclocal',
89'__ar':                'ar',
90'__arch_install_post': '%{nil}',
91'__as':                'as',
92'__autoconf':          'autoconf',
93'__autoheader':        'autoheader',
94'__automake':          'automake',
95'__awk':               'awk',
96'__bash':              '/bin/bash',
97'__bzip2':             '/usr/bin/bzip2',
98'__cat':               '/bin/cat',
99'__cc':                '/usr/bin/gcc',
100'__check_files':       '%{_usrlibrpm}/check-files %{buildroot}',
101'__chgrp':             '/usr/bin/chgrp',
102'__chmod':             '/bin/chmod',
103'__chown':             '/usr/sbin/chown',
104'__cp':                '/bin/cp',
105'__cpio':              '/usr/bin/cpio',
106'__cpp':               '/usr/bin/gcc -E',
107'__cxx':               '/usr/bin/g++',
108'__grep':              '/usr/bin/grep',
109'__gzip':              '/usr/bin/gzip',
110'__id':                '/usr/bin/id',
111'__id_u':              '%{__id} -u',
112'__install':           '/usr/bin/install',
113'__install_info':      '/usr/bin/install-info',
114'__ld':                '/usr/bin/ld',
115'__ldconfig':          '/sbin/ldconfig',
116'__ln_s':              'ln -s',
117'__make':              '/usr/bin/make',
118'__mkdir':             '/bin/mkdir',
119'__mkdir_p':           '/bin/mkdir -p',
120'__mv':                '/bin/mv',
121'__nm':                '/usr/bin/nm',
122'__objcopy':           '%{_bindir}/objcopy',
123'__objdump':           '%{_bindir}/objdump',
124'__patch':             '/usr/bin/patch',
125'__perl':              'perl',
126'__perl_provides':     '%{_usrlibrpm}/perl.prov',
127'__perl_requires':     '%{_usrlibrpm}/perl.req',
128'__ranlib':            'ranlib',
129'__remsh':             '%{__rsh}',
130'__rm':                '/bin/rm',
131'__rsh':               '/usr/bin/rsh',
132'__sed':               '/usr/bin/sed',
133'__setup_post':        '%{__chmod} -R a+rX,g-w,o-w .',
134'__sh':                '/bin/sh',
135'__tar':               '/usr/bin/tar',
136'__tar_extract':       '%{__tar} -xvvf',
137'__unzip':             '/usr/bin/unzip',
138'_datadir':            '%{_prefix}/share',
139'_defaultdocdir':      '%{_prefix}/share/doc',
140'_exeext':             '',
141'_exec_prefix':        '%{_prefix}',
142'_lib':                'lib',
143'_libdir':             '%{_exec_prefix}/%{_lib}',
144'_libexecdir':         '%{_exec_prefix}/libexec',
145'_localedir':          '%{_datadir}/locale',
146'_localstatedir':      '%{_prefix}/var',
147'_usr':                '/usr/local',
148'_usrsrc':             '%{_usr}/src',
149'_var':                '/usr/local/var',
150'_varrun':             '%{_var}/run',
151'nil':                 ''
152}
153
154class command_line:
155    """Process the command line in a common way across all SpecBuilder commands."""
156
157    _defaults = { 'params'   : [],
158                  'warn-all' : '0',
159                  'quiet'    : '0',
160                  'trace'    : '0',
161                  'dry-run'  : '0',
162                  'no-clean' : '0',
163                  'no-smp'   : '0',
164                  'rebuild'  : '0' }
165
166    _long_opts = { '--prefix'     : '_prefix',
167                   '--prefixbase' : '_prefixbase',
168                   '--topdir'     : '_topdir',
169                   '--specdir'    : '_specdir',
170                   '--builddir'   : '_builddir',
171                   '--sourcedir'  : '_sourcedir',
172                   '--usrlibrpm'  : '_usrlibrpm',
173                   '--tmppath'    : '_tmppath',
174                   '--log'        : '_logfile',
175                   '--url'        : '_url_base',
176                   '--rtems'      : '_rtemssrc' }
177
178    _long_true_opts = { '--trace'    : '_trace',
179                        '--warn-all' : '_warn_all',
180                        '--no-clean' : '_no_clean',
181                        '--no-smp'   : '_no_smp',
182                        '--rebuild'  : '_rebuild' }
183
184    _target_triplets = { '--host'   : '_host',
185                         '--build'  : '_build',
186                         '--target' : '_target' }
187
188    def __init__(self, argv):
189        self.command_path = os.path.dirname(argv[0])
190        if len(self.command_path) == 0:
191            self.command_path = '.'
192        self.command_name = os.path.basename(argv[0])
193        self.args = argv[1:]
194        self.defaults = {}
195        for to in command_line._long_true_opts:
196            self.defaults[command_line._long_true_opts[to]] = '0'
197        self._process()
198
199    def __str__(self):
200        def _dict(dd):
201            s = ''
202            ddl = dd.keys()
203            ddl.sort()
204            for d in ddl:
205                s += '  ' + d + ': ' + str(dd[d]) + '\n'
206            return s
207
208        s = 'command: ' + self.command() + \
209            '\nargs: ' + str(self.args) + \
210            '\nopts:\n' + _dict(self.opts)
211
212        return s
213
214    def _process(self):
215
216        def _process_lopt(opt, arg, long_opts, args, values = False):
217            for lo in long_opts:
218                if values and opt.startswith(lo):
219                    equals = opt.find('=')
220                    if equals < 0:
221                        if arg == len(args) - 1:
222                            raise error.general('missing option value: ' + lo)
223                        arg += 1
224                        value = args[arg]
225                    else:
226                        value = opt[equals + 1:]
227                    return lo, long_opts[lo], value, arg
228                elif opt == lo:
229                    return lo, long_opts[lo], True, arg
230            return None, None, None, arg
231
232        self.opts = command_line._defaults
233        i = 0
234        while i < len(self.args):
235            a = self.args[i]
236            if a.startswith('-'):
237                if a.startswith('--'):
238                    if a.startswith('--warn-all'):
239                        self.opts['warn-all'] = True
240                    else:
241                        lo, macro, value, i = _process_lopt(a, i,
242                                                            command_line._long_true_opts,
243                                                            self.args)
244                        if lo:
245                            self.defaults[macro] = '1'
246                            self.opts[lo[2:]] = '1'
247                        else:
248                            lo, macro, value, i = _process_lopt(a, i,
249                                                                command_line._long_opts,
250                                                                self.args, True)
251                            if lo:
252                                self.defaults[macro] = value
253                                self.opts[lo[2:]] = value
254                            else:
255                                #
256                                # The target triplet is 'cpu-vendor-os'.
257                                #
258                                lo, macro, value, i = _process_lopt(a, i,
259                                                                    command_line._target_triplets,
260                                                                    self.args, True)
261                                if lo:
262                                    #
263                                    # This is a target triplet. Run it past config.sub to make
264                                    # make sure it is ok.
265                                    #
266                                    e = execute.capture_execution()
267                                    config_sub = os.path.join(self.command_path,
268                                                              'specbuilder', 'config.sub')
269                                    exit_code, proc, output = e.shell(config_sub + ' ' + value)
270                                    if exit_code == 0:
271                                        value = output
272                                    self.defaults[macro] = value
273                                    self.opts[lo[2:]] = value
274                                    _arch = macro + '_cpu'
275                                    _vendor = macro + '_vendor'
276                                    _os = macro + '_os'
277                                    _arch_value = ''
278                                    _vendor_value = ''
279                                    _os_value = ''
280                                    dash = value.find('-')
281                                    if dash >= 0:
282                                        _arch_value = value[:dash]
283                                        value = value[dash + 1:]
284                                    dash = value.find('-')
285                                    if dash >= 0:
286                                        _vendor_value = value[:dash]
287                                        value = value[dash + 1:]
288                                    if len(value):
289                                        _os_value = value
290                                    self.defaults[_arch] = _arch_value
291                                    self.defaults[_vendor] = _vendor_value
292                                    self.defaults[_os] = _os_value
293                                if not lo:
294                                    raise error.general('invalid argument: ' + a)
295                else:
296                    if a == '-n':
297                        self.opts['dry-run'] = '1'
298                    elif a == '-q':
299                        self.opts['quiet'] = '1'
300            else:
301                self.opts['params'].append(a)
302            i += 1
303
304    def _post_process(self, _defaults):
305        if self.no_smp():
306            _defaults['_smp_mflags'] = _defaults['nil']
307        return _defaults
308
309    def expand(self, s, _defaults):
310        """Simple basic expander of spec file macros."""
311        mf = re.compile(r'%{[^}]+}')
312        expanded = True
313        while expanded:
314            expanded = False
315            for m in mf.findall(s):
316                name = m[2:-1]
317                if name in _defaults:
318                    s = s.replace(m, _defaults[name])
319                    expanded = True
320                else:
321                    raise error.general('cannot process default macro: ' + m)
322        return s
323
324    def command(self):
325        return os.path.join(self.command_path, self.command_name)
326       
327    def dry_run(self):
328        return self.opts['dry-run'] != '0'
329
330    def quiet(self):
331        return self.opts['quiet'] != '0'
332
333    def trace(self):
334        return self.opts['trace'] != '0'
335
336    def warn_all(self):
337        return self.opts['warn-all'] != '0'
338
339    def no_clean(self):
340        return self.opts['no-clean'] != '0'
341
342    def no_smp(self):
343        return self.opts['no-smp'] != '0'
344
345    def rebuild(self):
346        return self.opts['rebuild'] != '0'
347
348    def params(self):
349        return self.opts['params']
350
351    def get_spec_files(self, spec):
352        if spec.find('*') >= 0 or spec.find('?'):
353            specdir = os.path.dirname(spec)
354            specbase = os.path.basename(spec)
355            if len(specbase) == 0:
356                specbase = '*'
357            if len(specdir) == 0:
358                specdir = self.expand(defaults['_specdir'], defaults)
359            if not os.path.isdir(specdir):
360                raise error.general('specdir is not a directory or does not exist: ' + specdir)
361            files = glob.glob(os.path.join(specdir, specbase))
362            specs = files
363        else:
364            specs = [spec]
365        return specs
366
367    def spec_files(self):
368        specs = []
369        for spec in self.opts['params']:
370            specs.extend(self.get_spec_files(spec))
371        return specs
372
373    def logfiles(self):
374        if 'log' in self.opts:
375            return self.opts['log'].split(',')
376        return ['stdout']
377
378    def urls(self):
379        if 'url' in self.opts:
380            return self.opts['url'].split(',')
381        return None
382
383    def prefixbase(self):
384        if 'prefixbase' in self.opts:
385            return self.opts['prefixbase']
386        return None
387
388def load(args):
389    """
390    Copy the defaults, get the host specific values and merge
391    them overriding any matching defaults, then create an options
392    object to handle the command line merging in any command line
393    overrides. Finally post process the command line.
394    """
395    d = defaults
396    overrides = None
397    uname = os.uname()
398    if uname[0] == 'Darwin':
399        import darwin
400        overrides = darwin.load()
401    for k in overrides:
402        d[k] = overrides[k]
403    import rtems
404    overrides = rtems.load()
405    for k in overrides:
406        d[k] = overrides[k]
407    o = command_line(args)
408    for k in o.defaults:
409        d[k] = o.defaults[k]
410    d = o._post_process(d)
411    return o, d
412
413if __name__ == '__main__':
414    import sys
415    try:
416        _opts, _defaults = load(args = sys.argv)
417        print _opts
418        pprint.pprint(_defaults)
419    except error.general, gerr:
420        print gerr
421        sys.exit(1)
422    except error.internal, ierr:
423        print ierr
424        sys.exit(1)
425    sys.exit(0)
426
Note: See TracBrowser for help on using the repository browser.