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

4.104.11
Last change on this file since faa8181 was faa8181, checked in by Chris Johns <chrisj@…>, on Feb 22, 2011 at 3:46:44 AM

2011-02-22 Chris Johns <chrisj@…>

  • specbuilder/sb-versions, specbuilder/specbuilder/version.py: New. Print a suitable version message for automatic documentation updating from the spec files in CVS.
  • specbuilder/specbuilder/build.py: Add xz support. Add a function to return the name of a package.
  • specbuilder/specbuilder/crossgcc.py: Use the build name in the tmp path.
  • specbuilder/specbuilder/darwin.py: Add xz support.
  • specbuilder/specbuilder/defaults.py: Add xz support. Add Windows and Linux support.
  • specbuilder/specbuilder/setup.py: Reference the correct shell opts. Use the shell setup in the version probe command. Fix the version check. Add autotools to the list of spec files to install.
  • specbuilder/specbuilder/spec.py: Add changelog and configure tests. Manage sub-packages better.
  • specbuilder/specbuilder/version.py, specbuilder/specbuilder/windows.py: New.
  • Property mode set to 100644
File size: 16.3 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'__xz':                '/usr/bin/xz',
139'_datadir':            '%{_prefix}/share',
140'_defaultdocdir':      '%{_prefix}/share/doc',
141'_exeext':             '',
142'_exec_prefix':        '%{_prefix}',
143'_lib':                'lib',
144'_libdir':             '%{_exec_prefix}/%{_lib}',
145'_libexecdir':         '%{_exec_prefix}/libexec',
146'_localedir':          '%{_datadir}/locale',
147'_localstatedir':      '%{_prefix}/var',
148'_usr':                '/usr/local',
149'_usrsrc':             '%{_usr}/src',
150'_var':                '/usr/local/var',
151'_varrun':             '%{_var}/run',
152'configure': '''
153CFLAGS="${CFLAGS:-%optflags}" ; export CFLAGS ;
154CXXFLAGS="${CXXFLAGS:-%optflags}" ; export CXXFLAGS ;
155FFLAGS="${FFLAGS:-%optflags}" ; export FFLAGS ;
156./configure --build=%{_build} --host=%{_host} \
157      --target=%{_target_platform} \
158      --program-prefix=%{?_program_prefix} \
159      --prefix=%{_prefix} \
160      --exec-prefix=%{_exec_prefix} \
161      --bindir=%{_bindir} \
162      --sbindir=%{_sbindir} \
163      --sysconfdir=%{_sysconfdir} \
164      --datadir=%{_datadir} \
165      --includedir=%{_includedir} \
166      --libdir=%{_libdir} \
167      --libexecdir=%{_libexecdir} \
168      --localstatedir=%{_localstatedir} \
169      --sharedstatedir=%{_sharedstatedir} \
170      --mandir=%{_mandir} \
171      --infodir=%{_infodir}''',
172'nil':                 ''
173}
174
175class command_line:
176    """Process the command line in a common way across all SpecBuilder commands."""
177
178    _defaults = { 'params'   : [],
179                  'warn-all' : '0',
180                  'quiet'    : '0',
181                  'trace'    : '0',
182                  'dry-run'  : '0',
183                  'no-clean' : '0',
184                  'no-smp'   : '0',
185                  'rebuild'  : '0' }
186
187    _long_opts = { '--prefix'     : '_prefix',
188                   '--prefixbase' : '_prefixbase',
189                   '--topdir'     : '_topdir',
190                   '--specdir'    : '_specdir',
191                   '--builddir'   : '_builddir',
192                   '--sourcedir'  : '_sourcedir',
193                   '--usrlibrpm'  : '_usrlibrpm',
194                   '--tmppath'    : '_tmppath',
195                   '--log'        : '_logfile',
196                   '--url'        : '_url_base',
197                   '--rtems'      : '_rtemssrc' }
198
199    _long_true_opts = { '--trace'    : '_trace',
200                        '--dry-run'  : '_dry_run',
201                        '--warn-all' : '_warn_all',
202                        '--no-clean' : '_no_clean',
203                        '--no-smp'   : '_no_smp',
204                        '--rebuild'  : '_rebuild' }
205
206    _target_triplets = { '--host'   : '_host',
207                         '--build'  : '_build',
208                         '--target' : '_target' }
209
210    def __init__(self, argv):
211        self.command_path = os.path.dirname(argv[0])
212        if len(self.command_path) == 0:
213            self.command_path = '.'
214        self.command_name = os.path.basename(argv[0])
215        self.args = argv[1:]
216        self.defaults = {}
217        for to in command_line._long_true_opts:
218            self.defaults[command_line._long_true_opts[to]] = '0'
219        self._process()
220
221    def __str__(self):
222        def _dict(dd):
223            s = ''
224            ddl = dd.keys()
225            ddl.sort()
226            for d in ddl:
227                s += '  ' + d + ': ' + str(dd[d]) + '\n'
228            return s
229
230        s = 'command: ' + self.command() + \
231            '\nargs: ' + str(self.args) + \
232            '\nopts:\n' + _dict(self.opts)
233
234        return s
235
236    def _process(self):
237
238        def _process_lopt(opt, arg, long_opts, args, values = False):
239            for lo in long_opts:
240                if values and opt.startswith(lo):
241                    equals = opt.find('=')
242                    if equals < 0:
243                        if arg == len(args) - 1:
244                            raise error.general('missing option value: ' + lo)
245                        arg += 1
246                        value = args[arg]
247                    else:
248                        value = opt[equals + 1:]
249                    return lo, long_opts[lo], value, arg
250                elif opt == lo:
251                    return lo, long_opts[lo], True, arg
252            return None, None, None, arg
253
254        self.opts = command_line._defaults
255        i = 0
256        while i < len(self.args):
257            a = self.args[i]
258            if a.startswith('-'):
259                if a.startswith('--'):
260                    if a.startswith('--warn-all'):
261                        self.opts['warn-all'] = True
262                    else:
263                        lo, macro, value, i = _process_lopt(a, i,
264                                                            command_line._long_true_opts,
265                                                            self.args)
266                        if lo:
267                            self.defaults[macro] = '1'
268                            self.opts[lo[2:]] = '1'
269                        else:
270                            lo, macro, value, i = _process_lopt(a, i,
271                                                                command_line._long_opts,
272                                                                self.args, True)
273                            if lo:
274                                self.defaults[macro] = value
275                                self.opts[lo[2:]] = value
276                            else:
277                                #
278                                # The target triplet is 'cpu-vendor-os'.
279                                #
280                                lo, macro, value, i = _process_lopt(a, i,
281                                                                    command_line._target_triplets,
282                                                                    self.args, True)
283                                if lo:
284                                    #
285                                    # This is a target triplet. Run it past config.sub to make
286                                    # make sure it is ok.
287                                    #
288                                    e = execute.capture_execution()
289                                    config_sub = os.path.join(self.command_path, 
290                                                              'specbuilder', 'config.sub')
291                                    exit_code, proc, output = e.shell(config_sub + ' ' + value)
292                                    if exit_code == 0:
293                                        value = output
294                                    self.defaults[macro] = value
295                                    self.opts[lo[2:]] = value
296                                    _arch = macro + '_cpu'
297                                    _vendor = macro + '_vendor'
298                                    _os = macro + '_os'
299                                    _arch_value = ''
300                                    _vendor_value = ''
301                                    _os_value = ''
302                                    dash = value.find('-')
303                                    if dash >= 0:
304                                        _arch_value = value[:dash]
305                                        value = value[dash + 1:]
306                                    dash = value.find('-')
307                                    if dash >= 0:
308                                        _vendor_value = value[:dash]
309                                        value = value[dash + 1:]
310                                    if len(value):
311                                        _os_value = value
312                                    self.defaults[_arch] = _arch_value
313                                    self.defaults[_vendor] = _vendor_value
314                                    self.defaults[_os] = _os_value
315                                if not lo:
316                                    raise error.general('invalid argument: ' + a)
317                else:
318                    if a == '-n':
319                        self.opts['dry-run'] = '1'
320                    elif a == '-q':
321                        self.opts['quiet'] = '1'
322            else:
323                self.opts['params'].append(a)
324            i += 1
325
326    def _post_process(self, _defaults):
327        if self.no_smp():
328            _defaults['_smp_mflags'] = _defaults['nil']
329        return _defaults
330
331    def expand(self, s, _defaults):
332        """Simple basic expander of spec file macros."""
333        mf = re.compile(r'%{[^}]+}')
334        expanded = True
335        while expanded:
336            expanded = False
337            for m in mf.findall(s):
338                name = m[2:-1]
339                if name in _defaults:
340                    s = s.replace(m, _defaults[name])
341                    expanded = True
342                else:
343                    raise error.general('cannot process default macro: ' + m)
344        return s
345
346    def command(self):
347        return os.path.join(self.command_path, self.command_name)
348       
349    def dry_run(self):
350        return self.opts['dry-run'] != '0'
351
352    def quiet(self):
353        return self.opts['quiet'] != '0'
354
355    def trace(self):
356        return self.opts['trace'] != '0' 
357
358    def warn_all(self):
359        return self.opts['warn-all'] != '0'
360
361    def no_clean(self):
362        return self.opts['no-clean'] != '0'
363
364    def no_smp(self):
365        return self.opts['no-smp'] != '0'
366
367    def rebuild(self):
368        return self.opts['rebuild'] != '0'
369
370    def params(self):
371        return self.opts['params']
372
373    def get_spec_files(self, spec):
374        if spec.find('*') >= 0 or spec.find('?'):
375            specdir = os.path.dirname(spec)
376            specbase = os.path.basename(spec)
377            if len(specbase) == 0:
378                specbase = '*'
379            if len(specdir) == 0:
380                specdir = self.expand(defaults['_specdir'], defaults)
381            if not os.path.isdir(specdir):
382                raise error.general('specdir is not a directory or does not exist: ' + specdir)
383            files = glob.glob(os.path.join(specdir, specbase))
384            specs = files
385        else:
386            specs = [spec]
387        return specs
388
389    def spec_files(self):
390        specs = []
391        for spec in self.opts['params']:
392            specs.extend(self.get_spec_files(spec))
393        return specs
394
395    def logfiles(self):
396        if 'log' in self.opts:
397            return self.opts['log'].split(',')
398        return ['stdout']
399
400    def urls(self):
401        if 'url' in self.opts:
402            return self.opts['url'].split(',')
403        return None
404
405    def prefixbase(self):
406        if 'prefixbase' in self.opts:
407            return self.opts['prefixbase']
408        return None
409
410def load(args):
411    """
412    Copy the defaults, get the host specific values and merge
413    them overriding any matching defaults, then create an options
414    object to handle the command line merging in any command line
415    overrides. Finally post process the command line.
416    """
417    d = defaults
418    overrides = None
419    if os.name == 'nt':
420        import windows
421        overrides = windows.load()
422    else:
423        uname = os.uname()
424        if uname[0] == 'Darwin':
425            import darwin
426            overrides = darwin.load()
427        elif uname[0] == 'Linux':
428            import linux 
429            overrides = linux.load()
430    if overrides is None:
431        raise error.general('no hosts defaults found; please add')
432    for k in overrides:
433        d[k] = overrides[k]
434    import rtems
435    overrides = rtems.load()
436    if overrides is not None:
437        for k in overrides:
438            d[k] = overrides[k]
439    o = command_line(args)
440    for k in o.defaults:
441        d[k] = o.defaults[k]
442    d = o._post_process(d)
443    return o, d
444
445if __name__ == '__main__':
446    import sys
447    try:
448        _opts, _defaults = load(args = sys.argv)
449        print _opts
450        pprint.pprint(_defaults)
451    except error.general, gerr:
452        print gerr
453        sys.exit(1)
454    except error.internal, ierr:
455        print ierr
456        sys.exit(1)
457    sys.exit(0)
458
459
460
Note: See TracBrowser for help on using the repository browser.