source: rtems-source-builder/source-builder/sb/setbuilder.py @ 5f6ad9d

5
Last change on this file since 5f6ad9d was 5f6ad9d, checked in by Sebastian Huber <sebastian.huber@…>, on 01/10/19 at 12:15:33

Fix 'build_max_size_human' ref. before assignment

Close #3568.

  • Property mode set to 100644
File size: 25.8 KB
RevLine 
[bf13d27]1#
2# RTEMS Tools Project (http://www.rtems.org/)
[38fd56c]3# Copyright 2010-2018 Chris Johns (chrisj@rtems.org)
[bf13d27]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#
[2f72d35]21# This code builds a package compiler tool suite given a tool set. A tool
[bf13d27]22# set lists the various tools. These are specific tool configurations.
23#
24
[3a972f6]25from __future__ import print_function
26
[984e4e6]27import copy
[251a42d]28import datetime
[71b8893]29import glob
[bf13d27]30import operator
31import os
[06834cf]32import sys
[4dc9bf3]33import textwrap
[bf13d27]34
[c18c4b6]35try:
36    import build
37    import check
38    import error
39    import log
[97a685f]40    import mailer
[cb12e48]41    import options
[c18c4b6]42    import path
43    import reports
[9a15c40]44    import sources
[affea81]45    import version
[c18c4b6]46except KeyboardInterrupt:
[3a972f6]47    print('abort: user terminated', file = sys.stderr)
[c18c4b6]48    sys.exit(1)
49except:
[3a972f6]50    print('error: unknown application load error', file = sys.stderr)
[c18c4b6]51    sys.exit(1)
[bf13d27]52
[0f97375]53class log_capture(object):
54    def __init__(self):
55        self.log = []
56        log.capture = self.capture
57
58    def __str__(self):
59        return os.linesep.join(self.log)
60
61    def capture(self, text):
62        self.log += [l for l in text.replace(chr(13), '').splitlines()]
63
64    def get(self):
65        return self.log
66
67    def clear(self):
68        self.log = []
69
[ab8319a]70class buildset:
71    """Build a set builds a set of packages."""
[bf13d27]72
[cb12e48]73    def __init__(self, bset, _configs, opts, macros = None):
[5142bec]74        log.trace('_bset: %s: init' % (bset))
[fba1136]75        self.configs = _configs
[984e4e6]76        self.opts = opts
[cb12e48]77        if macros is None:
78            self.macros = copy.copy(opts.defaults)
79        else:
80            self.macros = copy.copy(macros)
[38ed59a]81        log.trace('_bset: %s: macro defaults' % (bset))
82        log.trace(str(self.macros))
[ab8319a]83        self.bset = bset
[ce0f7a1]84        _target = self.macros.expand('%{_target}')
85        if len(_target):
86            pkg_prefix = _target
87        else:
88            pkg_prefix = self.macros.expand('%{_host}')
89        self.bset_pkg = '%s-%s-set' % (pkg_prefix, self.bset)
[c914e1d]90        self.mail_header = ''
[97a685f]91        self.mail_report = ''
[0f97375]92        self.mail_report_0subject = ''
[df56f7e]93        self.build_failure = None
[c914e1d]94
[0f97375]95    def write_mail_header(self, text = '', prepend = False):
96        if type(text) is list:
97            text = os.linesep.join(text)
98        text = text.replace('\r', '').replace('\n', os.linesep)
99        if len(text) == 0 or text[-1] != os.linesep:
[c914e1d]100            text += os.linesep
101        if prepend:
102            self.mail_header = text + self.mail_header
103        else:
104            self.mail_header += text
[adf0946]105
[0f97375]106    def get_mail_header(self):
107        return self.mail_header
108
[97a685f]109    def write_mail_report(self, text, prepend = False):
[0f97375]110        if type(text) is list:
111            text = os.linesep.join(text)
112        text = text.replace('\r', '').replace('\n', os.linesep)
113        if len(text) == 0 or text[-1] != os.linesep:
[adf0946]114            text += os.linesep
115        if prepend:
[97a685f]116            self.mail_report = text + self.mail_report
[adf0946]117        else:
[97a685f]118            self.mail_report += text
[bf13d27]119
[0f97375]120    def get_mail_report(self):
121        return self.mail_report
122
[bf13d27]123    def copy(self, src, dst):
[01b2815]124        log.output('copy: %s => %s' % (path.host(src), path.host(dst)))
125        if not self.opts.dry_run():
[869b8a6]126            path.copy_tree(src, dst)
[bf13d27]127
[0f97375]128    def report(self, _config, _build, opts, macros, format = None, mail = None):
[ce60578]129        if len(_build.main_package().name()) > 0 \
[ebf8a1f]130           and not _build.macros.get('%{_disable_reporting}') \
[ce60578]131           and (not _build.opts.get_arg('--no-report') \
132                or _build.opts.get_arg('--mail')):
[4bd058e]133            if format is None:
134                format = _build.opts.get_arg('--report-format')
135                if format is not None:
136                    if len(format) != 2:
[6444d58]137                        raise error.general('invalid report format option: %s' % \
138                                            ('='.join(format)))
[4bd058e]139                    format = format[1]
[26595c7]140            if format is None:
[ce60578]141                format = 'text'
[4bd058e]142            if format == 'text':
143                ext = '.txt'
144            elif format == 'asciidoc':
[ce60578]145                ext = '.txt'
[4bd058e]146            elif format == 'html':
147                ext = '.html'
148            elif format == 'xml':
149                ext = '.xml'
150            elif format == 'ini':
151                ext = '.ini'
[26595c7]152            else:
[4bd058e]153                raise error.general('invalid report format: %s' % (format))
[864e8ff]154            buildroot = _build.config.abspath('%{buildroot}')
[cb12e48]155            prefix = _build.macros.expand('%{_prefix}')
[06834cf]156            name = _build.main_package().name() + ext
[5142bec]157            log.notice('reporting: %s -> %s' % (_config, name))
[adf0946]158            if not _build.opts.get_arg('--no-report'):
[ce60578]159                outpath = path.host(path.join(buildroot, prefix, 'share', 'rtems', 'rsb'))
160                if not _build.opts.dry_run():
161                    outname = path.host(path.join(outpath, name))
162                else:
163                    outname = None
164                r = reports.report(format, self.configs,
165                                   copy.copy(opts), copy.copy(macros))
[adf0946]166                r.introduction(_build.config.file_name())
[ce60578]167                r.generate(_build.config.file_name())
168                r.epilogue(_build.config.file_name())
[adf0946]169                if not _build.opts.dry_run():
170                    _build.mkdir(outpath)
171                    r.write(outname)
172                del r
[0f97375]173            if mail:
[ce60578]174                r = reports.report('text', self.configs,
175                                   copy.copy(opts), copy.copy(macros))
[adf0946]176                r.introduction(_build.config.file_name())
[ce60578]177                r.generate(_build.config.file_name())
178                r.epilogue(_build.config.file_name())
[0f97375]179                self.write_mail_report(r.get_output())
[26595c7]180                del r
181
[4f26bdb]182    def root_copy(self, src, dst):
183        what = '%s -> %s' % \
184            (os.path.relpath(path.host(src)), os.path.relpath(path.host(dst)))
[5142bec]185        log.trace('_bset: %s: collecting: %s' % (self.bset, what))
[04f447f]186        self.copy(src, dst)
[bf13d27]187
[4f26bdb]188    def install(self, name, buildroot, prefix):
189        dst = prefix
190        src = path.join(buildroot, prefix)
[5142bec]191        log.notice('installing: %s -> %s' % (name, path.host(dst)))
[04f447f]192        self.copy(src, dst)
[4f26bdb]193
194    def canadian_cross(self, _build):
[6444d58]195        log.trace('_bset: Cxc for build machine: _build => _host')
196        macros_to_copy = [('%{_host}',        '%{_build}'),
197                          ('%{_host_alias}',  '%{_build_alias}'),
198                          ('%{_host_arch}',   '%{_build_arch}'),
199                          ('%{_host_cpu}',    '%{_build_cpu}'),
200                          ('%{_host_os}',     '%{_build_os}'),
201                          ('%{_host_vendor}', '%{_build_vendor}'),
202                          ('%{_tmproot}',     '%{_tmpcxcroot}'),
203                          ('%{buildroot}',    '%{buildcxcroot}'),
204                          ('%{_builddir}',    '%{_buildcxcdir}')]
205        cxc_macros = _build.copy_init_macros()
[cb12e48]206        for m in macros_to_copy:
[6444d58]207            log.trace('_bset: Cxc: %s <= %s' % (m[0], cxc_macros[m[1]]))
208            cxc_macros[m[0]] = cxc_macros[m[1]]
209        _build.set_macros(cxc_macros)
210        _build.reload()
[4f26bdb]211        _build.make()
[ebf8a1f]212        if not _build.macros.get('%{_disable_collecting}'):
[6444d58]213            self.root_copy(_build.config.expand('%{buildroot}'),
214                           _build.config.expand('%{_tmproot}'))
215        _build.set_macros(_build.copy_init_macros())
216        _build.reload()
[4f26bdb]217
218    def build_package(self, _config, _build):
[ebf8a1f]219        if not _build.disabled():
220            if _build.canadian_cross():
221                self.canadian_cross(_build)
222            _build.make()
223            if not _build.macros.get('%{_disable_collecting}'):
224                self.root_copy(_build.config.expand('%{buildroot}'),
225                               _build.config.expand('%{_tmproot}'))
[4f26bdb]226
227    def bset_tar(self, _build):
228        tardir = _build.config.expand('%{_tardir}')
[6444d58]229        if (self.opts.get_arg('--bset-tar-file') or self.opts.canadian_cross()) \
[ebf8a1f]230           and not _build.macros.get('%{_disable_packaging}'):
[ee47d72]231            path.mkdir(tardir)
[e645642]232            tar = path.join(tardir, _build.config.expand('%s.tar.bz2' % (_build.main_package().name())))
[5142bec]233            log.notice('tarball: %s' % (os.path.relpath(path.host(tar))))
[cafbcc6]234            if not self.opts.dry_run():
[4f26bdb]235                tmproot = _build.config.expand('%{_tmproot}')
[056e601]236                cmd = _build.config.expand('"cd ' + tmproot + \
237                                               ' && %{__tar} -cf - . | %{__bzip2} > ' + tar + '"')
[cafbcc6]238                _build.run(cmd, shell_opts = '-c', cwd = tmproot)
[bf13d27]239
[2f72d35]240    def parse(self, bset):
[bf13d27]241
242        def _clean(line):
243            line = line[0:-1]
244            b = line.find('#')
245            if b >= 0:
246                line = line[1:b]
247            return line.strip()
248
[e9af460]249        bsetname = bset
[bf13d27]250
[ab8319a]251        if not path.exists(bsetname):
[cb12e48]252            for cp in self.macros.expand('%{_configdir}').split(':'):
[ab8319a]253                configdir = path.abspath(cp)
[e9af460]254                bsetname = path.join(configdir, bset)
[ab8319a]255                if path.exists(bsetname):
[bf13d27]256                    break
[ab8319a]257                bsetname = None
258            if bsetname is None:
[e9af460]259                raise error.general('no build set file found: %s' % (bset))
[bf13d27]260        try:
[5142bec]261            log.trace('_bset: %s: open: %s' % (self.bset, bsetname))
[ab8319a]262            bset = open(path.host(bsetname), 'r')
[3a972f6]263        except IOError as err:
[ab8319a]264            raise error.general('error opening bset file: %s' % (bsetname))
[bf13d27]265
266        configs = []
267
268        try:
269            lc = 0
[ab8319a]270            for l in bset:
[bf13d27]271                lc += 1
272                l = _clean(l)
273                if len(l) == 0:
274                    continue
[5142bec]275                log.trace('_bset: %s: %03d: %s' % (self.bset, lc, l))
[5cba075]276                ls = l.split()
277                if ls[0][-1] == ':' and ls[0][:-1] == 'package':
[52561d9]278                    self.bset_pkg = ls[1].strip()
[cb12e48]279                    self.macros['package'] = self.bset_pkg
[5cba075]280                elif ls[0][0] == '%':
[a083b52]281                    def err(msg):
282                        raise error.general('%s:%d: %s' % (self.bset, lc, msg))
[5cba075]283                    if ls[0] == '%define':
[6fad89b]284                        if len(ls) > 2:
[cb12e48]285                            self.macros.define(ls[1].strip(),
286                                               ' '.join([f.strip() for f in ls[2:]]))
[6fad89b]287                        else:
[cb12e48]288                            self.macros.define(ls[1].strip())
[fa653c2]289                    elif ls[0] == '%undefine':
290                        if len(ls) > 2:
[8a1e7a0]291                            raise error.general('%s:%d: %undefine requires just the name' % \
292                                                    (self.bset, lc))
[cb12e48]293                        self.macros.undefine(ls[1].strip())
[5cba075]294                    elif ls[0] == '%include':
[2f72d35]295                        configs += self.parse(ls[1].strip())
[a083b52]296                    elif ls[0] in ['%patch', '%source']:
[9a15c40]297                        sources.process(ls[0][1:], ls[1:], self.macros, err)
[a083b52]298                    elif ls[0] == '%hash':
299                        sources.hash(ls[1:], self.macros, err)
[bf13d27]300                else:
[fba1136]301                    l = l.strip()
[0759d98]302                    c = build.find_config(l, self.configs)
[fba1136]303                    if c is None:
[8a1e7a0]304                        raise error.general('%s:%d: cannot find file: %s' % (self.bset, lc, l))
[fba1136]305                    configs += [c]
[bf13d27]306        except:
[ab8319a]307            bset.close()
[bf13d27]308            raise
309
[ab8319a]310        bset.close()
[bf13d27]311
312        return configs
313
[2f72d35]314    def load(self):
315
[adf0946]316        #
317        # If the build set file ends with .cfg the user has passed to the
318        # buildset builder a configuration so we just return it.
319        #
320        if self.bset.endswith('.cfg'):
321            configs = [self.bset]
[2f72d35]322        else:
[adf0946]323            exbset = self.macros.expand(self.bset)
324            self.macros['_bset'] = exbset
[96c414c]325            self.macros['_bset_tmp'] = build.short_name(exbset)
[adf0946]326            root, ext = path.splitext(exbset)
327            if exbset.endswith('.bset'):
328                bset = exbset
329            else:
330                bset = '%s.bset' % (exbset)
331            configs = self.parse(bset)
332        return configs
[2f72d35]333
[0f97375]334    def build(self, deps = None, nesting_count = 0, mail = None):
[72f89c5]335
[120e101]336        build_error = False
337
[72f89c5]338        nesting_count += 1
[bf13d27]339
[0f97375]340        if mail:
341            mail['output'].clear()
342
[5142bec]343        log.trace('_bset: %s: make' % (self.bset))
344        log.notice('Build Set: %s' % (self.bset))
[bf13d27]345
[4dc9bf3]346        mail_subject = '%s on %s' % (self.bset,
347                                     self.macros.expand('%{_host}'))
[adf0946]348
[bf13d27]349        current_path = os.environ['PATH']
[0add2ea]350
[251a42d]351        start = datetime.datetime.now()
352
[df56f7e]353        mail_report = False
[2802080]354        have_errors = False
[df56f7e]355
[0f97375]356        if mail:
357            mail['output'].clear()
358
[bf13d27]359        try:
[120e101]360            configs = self.load()
361
362            log.trace('_bset: %s: configs: %s'  % (self.bset, ','.join(configs)))
363
[5f6ad9d]364            sizes_valid = False
[bf13d27]365            builds = []
366            for s in range(0, len(configs)):
[ebf8a1f]367                b = None
[729f0bb]368                try:
[984e4e6]369                    #
370                    # Each section of the build set gets a separate set of
[cb12e48]371                    # macros so we do not contaminate one configuration with
[984e4e6]372                    # another.
373                    #
[cb12e48]374                    opts = copy.copy(self.opts)
375                    macros = copy.copy(self.macros)
[729f0bb]376                    if configs[s].endswith('.bset'):
[72f89c5]377                        log.trace('_bset: == %2d %s' % (nesting_count + 1, '=' * 75))
[cb12e48]378                        bs = buildset(configs[s], self.configs, opts, macros)
[0f97375]379                        bs.build(deps, nesting_count, mail)
[729f0bb]380                        del bs
381                    elif configs[s].endswith('.cfg'):
[0f97375]382                        if mail:
383                            mail_report = True
[72f89c5]384                        log.trace('_bset: -- %2d %s' % (nesting_count + 1, '-' * 75))
[120e101]385                        try:
[0f97375]386                            b = build.build(configs[s],
387                                            self.opts.get_arg('--pkg-tar-files'),
388                                            opts,
389                                            macros)
[120e101]390                        except:
391                            build_error = True
392                            raise
[01b2815]393                        if b.macros.get('%{_disable_reporting}'):
394                            mail_report = False
[79f80fd]395                        if deps is None:
[4f26bdb]396                            self.build_package(configs[s], b)
[ce60578]397                            self.report(configs[s], b,
398                                        copy.copy(self.opts),
[0f97375]399                                        copy.copy(self.macros),
400                                        mail = mail)
401                            # Always produce an XML report.
[4bd058e]402                            self.report(configs[s], b,
403                                        copy.copy(self.opts),
404                                        copy.copy(self.macros),
[0f97375]405                                        format = 'xml',
406                                        mail = mail)
[2802080]407                            if s == len(configs) - 1 and not have_errors:
[4f26bdb]408                                self.bset_tar(b)
[79f80fd]409                        else:
410                            deps += b.config.includes()
[729f0bb]411                        builds += [b]
[29819a2]412                        #
413                        # Dump post build macros.
414                        #
415                        log.trace('_bset: macros post-build')
416                        log.trace(str(macros))
[729f0bb]417                    else:
418                        raise error.general('invalid config type: %s' % (configs[s]))
[3a972f6]419                except error.general as gerr:
[2802080]420                    have_errors = True
[ebf8a1f]421                    if b is not None:
422                        if self.build_failure is None:
423                            self.build_failure = b.name()
424                        self.write_mail_header('')
425                        self.write_mail_header('= ' * 40)
426                        self.write_mail_header('Build FAILED: %s' % (b.name()))
427                        self.write_mail_header('- ' * 40)
428                        self.write_mail_header(str(log.default))
429                        self.write_mail_header('- ' * 40)
430                        if self.opts.keep_going():
[01b2815]431                            log.notice(str(gerr))
[ebf8a1f]432                            if self.opts.always_clean():
433                                builds += [b]
434                        else:
435                            raise
[729f0bb]436                    else:
437                        raise
[6444d58]438            #
439            # Installing ...
440            #
441            log.trace('_bset: installing: deps:%r no-install:%r' % \
442                      (deps is None, self.opts.no_install()))
[b843e62]443            if deps is None \
444               and not self.opts.no_install() \
445               and not have_errors:
[4f26bdb]446                for b in builds:
[6444d58]447                    log.trace('_bset: installing: %r' % b.installable())
448                    if b.installable():
[ebf8a1f]449                        self.install(b.name(),
450                                     b.config.expand('%{buildroot}'),
451                                     b.config.expand('%{_prefix}'))
[38fd56c]452            #
453            # Sizes ...
454            #
455            if len(builds) > 1:
456                size_build = 0
457                size_installed = 0
458                size_build_max = 0
459                for b in builds:
460                    s = b.get_build_size()
461                    size_build += s
462                    if s > size_build_max:
463                        size_build_max = s
464                    size_installed += b.get_installed_size()
465                size_sources = 0
466                for p in builds[0].config.expand('%{_sourcedir}').split(':'):
467                    size_sources += path.get_size(p)
468                size_patches = 0
469                for p in builds[0].config.expand('%{_patchdir}').split(':'):
470                    size_patches += path.get_size(p)
471                size_total = size_sources + size_patches + size_installed
[079f95a]472                build_max_size_human = build.humanize_number(size_build_max + size_installed, 'B')
473                build_total_size_human = build.humanize_number(size_total, 'B')
474                build_sources_size_human = build.humanize_number(size_sources, 'B')
475                build_patches_size_human = build.humanize_number(size_patches, 'B')
476                build_installed_size_human = build.humanize_number(size_installed, 'B')
477                build_size = 'usage: %s' % (build_max_size_human)
478                build_size += ' total: %s' % (build_total_size_human)
479                build_size += ' (sources: %s' % (build_sources_size_human)
480                build_size += ', patches: %s' % (build_patches_size_human)
481                build_size += ', installed %s)' % (build_installed_size_human)
[5f6ad9d]482                sizes_valid = True
[38fd56c]483            #
484            # Cleaning ...
485            #
[4f26bdb]486            if deps is None and \
[0add2ea]487                    (not self.opts.no_clean() or self.opts.always_clean()):
[bf13d27]488                for b in builds:
[ebf8a1f]489                    if not b.disabled():
490                        log.notice('cleaning: %s' % (b.name()))
491                        b.cleanup()
[38fd56c]492            #
493            # Log the build size message
494            #
495            if len(builds) > 1:
496                log.notice('Build Sizes: %s' % (build_size))
497            #
498            # Clear out the builds ...
499            #
[bf13d27]500            for b in builds:
501                del b
[3a972f6]502        except error.general as gerr:
[120e101]503            if not build_error:
504                log.stderr(str(gerr))
[df56f7e]505            raise
506        except KeyboardInterrupt:
507            mail_report = False
508            raise
[bf13d27]509        except:
[df56f7e]510            self.build_failure = 'RSB general failure'
[bf13d27]511            raise
[c914e1d]512        finally:
513            end = datetime.datetime.now()
514            os.environ['PATH'] = current_path
515            build_time = str(end - start)
[0f97375]516            if mail_report and not self.macros.defined('mail_disable'):
517                self.write_mail_header('Build Time: %s' % (build_time), True)
518                self.write_mail_header('', True)
[df56f7e]519                if self.build_failure is not None:
[4dc9bf3]520                    mail_subject = 'FAILED %s (%s)' % \
[0f97375]521                        (mail_subject, self.build_failure)
[c914e1d]522                else:
[4dc9bf3]523                    mail_subject = 'PASSED %s' % (mail_subject)
524                mail_subject = 'Build %s: %s' % (reports.platform(mode = 'system'),
525                                                 mail_subject)
[0f97375]526                self.write_mail_header(mail['header'], True)
527                self.write_mail_header('')
528                log.notice('Mailing report: %s' % (mail['to']))
529                body = self.get_mail_header()
[38fd56c]530                body += 'Sizes' + os.linesep
531                body += '=====' + os.linesep + os.linesep
[5f6ad9d]532                if sizes_valid:
[079f95a]533                    body += 'Maximum build usage: ' + build_max_size_human + os.linesep
534                    body += 'Total size: ' + build_total_size_human + os.linesep
535                    body += 'Installed : ' + build_installed_size_human + os.linesep
536                    body += 'Sources: ' + build_sources_size_human + os.linesep
[c5d84ce]537                    body += 'Patches: ' + build_patches_size_human + os.linesep
[079f95a]538                else:
539                    body += 'No packages built'
540                body += os.linesep
[0f97375]541                body += 'Output' + os.linesep
542                body += '======' + os.linesep + os.linesep
543                body += os.linesep.join(mail['output'].get())
544                body += os.linesep + os.linesep
545                body += 'Report' + os.linesep
546                body += '======' + os.linesep + os.linesep
547                body += self.get_mail_report()
548                if not opts.dry_run():
549                    mail['mail'].send(mail['to'], mail_subject, body)
[c914e1d]550            log.notice('Build Set: Time %s' % (build_time))
[adf0946]551
[d63f135]552def list_bset_cfg_files(opts, configs):
553    if opts.get_arg('--list-configs') or opts.get_arg('--list-bsets'):
554        if opts.get_arg('--list-configs'):
555            ext = '.cfg'
556        else:
557            ext = '.bset'
558        for p in configs['paths']:
[3a972f6]559            print('Examining: %s' % (os.path.relpath(p)))
[d63f135]560        for c in configs['files']:
561            if c.endswith(ext):
[3a972f6]562                print('    %s' % (c))
[d63f135]563        return True
564    return False
565
[bf13d27]566def run():
567    import sys
[74da24c]568    ec = 0
[120e101]569    setbuilder_error = False
[0f97375]570    mail = None
[bf13d27]571    try:
[cafbcc6]572        optargs = { '--list-configs':  'List available configurations',
573                    '--list-bsets':    'List available build sets',
[a16bfe1]574                    '--list-configs':  'List available configuration files.',
[79f80fd]575                    '--list-deps':     'List the dependent files.',
[adf0946]576                    '--bset-tar-file': 'Create a build set tar file',
577                    '--pkg-tar-files': 'Create package tar files',
[26595c7]578                    '--no-report':     'Do not create a package report.',
[97a685f]579                    '--report-format': 'The report format (text, html, asciidoc).' }
580        mailer.append_options(optargs)
[cb12e48]581        opts = options.load(sys.argv, optargs)
[0f97375]582        if opts.get_arg('--mail'):
583            mail = { 'mail'  : mailer.mail(opts),
584                     'output': log_capture() }
585            to_addr = opts.get_arg('--mail-to')
586            if to_addr is not None:
587                mail['to'] = to_addr[1]
588            else:
[70e3e5e]589                mail['to'] = opts.defaults.expand('%{_mail_tools_to}')
[0f97375]590            mail['from'] = mail['mail'].from_address()
[47d703fd]591        log.notice('RTEMS Source Builder - Set Builder, %s' % (version.str()))
[72f89c5]592        opts.log_info()
[cb12e48]593        if not check.host_setup(opts):
[fba1136]594            raise error.general('host build environment is not set up correctly')
[0f97375]595        if mail:
[4dc9bf3]596            mail['header'] = os.linesep.join(mail['output'].get()) + os.linesep
[0f97375]597            mail['header'] += os.linesep
[4dc9bf3]598            mail['header'] += 'Host: '  + reports.platform('compact') + os.linesep
599            indent = '       '
600            for l in textwrap.wrap(reports.platform('extended'),
601                                   width = 80 - len(indent)):
602                mail['header'] += indent + l + os.linesep
[cb12e48]603        configs = build.get_configs(opts)
[79f80fd]604        if opts.get_arg('--list-deps'):
605            deps = []
606        else:
607            deps = None
[d63f135]608        if not list_bset_cfg_files(opts, configs):
[2cc7a97]609            prefix = opts.defaults.expand('%{_prefix}')
[6444d58]610            if opts.canadian_cross():
611                opts.disable_install()
612
[3963ac4]613            if not opts.dry_run() and \
[eeded98]614               not opts.canadian_cross() and \
[3963ac4]615               not opts.no_install() and \
616               not path.ispathwritable(prefix):
[2cc7a97]617                raise error.general('prefix is not writable: %s' % (path.host(prefix)))
[0f97375]618
[71b8893]619            for bset in opts.params():
[120e101]620                setbuilder_error = True
[cb12e48]621                b = buildset(bset, configs, opts)
[0f97375]622                b.build(deps, mail = mail)
[74da24c]623                b = None
[120e101]624                setbuilder_error = False
[0f97375]625
[79f80fd]626        if deps is not None:
627            c = 0
628            for d in sorted(set(deps)):
629                c += 1
[3a972f6]630                print('dep[%d]: %s' % (c, d))
631    except error.general as gerr:
[120e101]632        if not setbuilder_error:
633            log.stderr(str(gerr))
[74da24c]634        log.stderr('Build FAILED')
635        ec = 1
[3a972f6]636    except error.internal as ierr:
[120e101]637        if not setbuilder_error:
638            log.stderr(str(ierr))
[74da24c]639        log.stderr('Internal Build FAILED')
640        ec = 1
[3a972f6]641    except error.exit as eerr:
[bf13d27]642        pass
643    except KeyboardInterrupt:
[5142bec]644        log.notice('abort: user terminated')
[74da24c]645        ec = 1
[0f97375]646    except:
647        raise
648        log.notice('abort: unknown error')
649        ec = 1
[74da24c]650    sys.exit(ec)
[bf13d27]651
652if __name__ == "__main__":
653    run()
Note: See TracBrowser for help on using the repository browser.