source: rtems-source-builder/source-builder/sb/build.py @ 158ad68

4.11
Last change on this file since 158ad68 was 158ad68, checked in by Chris Johns <chrisj@…>, on 10/03/20 at 11:53:04

sb: Back port the RTEMS 5 and 6 RSB engine.

  • Build GDb first as we do for RTEMS 5 and later
  • Update GDB to 9.1 for all archs expect SPARC. The SIS patches only apply to 7.9. Disable Python for SPARC

Closes #4111

  • Property mode set to 100644
File size: 27.9 KB
Line 
1#
2# RTEMS Tools Project (http://www.rtems.org/)
3# Copyright 2010-2018 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# This code builds a package given a config file. It only builds to be
22# installed not to be package unless you run a packager around this.
23#
24
25from __future__ import print_function
26
27import copy
28import getopt
29import glob
30import os
31import shutil
32import stat
33import sys
34
35try:
36    from . import check
37    from . import config
38    from . import download
39    from . import error
40    from . import ereport
41    from . import execute
42    from . import log
43    from . import options
44    from . import path
45    from . import sources
46    from . import version
47except KeyboardInterrupt:
48    print('abort: user terminated')
49    sys.exit(1)
50except:
51    raise
52
53def humanize_number(num, suffix):
54    for unit in ['','K','M','G','T','P','E','Z']:
55        if abs(num) < 1024.0:
56            return "%5.3f%s%s" % (num, unit, suffix)
57        num /= 1024.0
58    return "%.3f%s%s" % (size, 'Y', suffix)
59
60def short_name(name):
61    #
62    # If on Windows use short names to keep the build paths as short as possible.
63    #
64    if options.host_windows:
65        buildname = ''
66        add = True
67        for n in name.split('-'):
68            buildname += n[0]
69        return buildname
70    else:
71        return name
72
73class script:
74    """Create and manage a shell script."""
75
76    def __init__(self):
77        self.reset()
78
79    def reset(self):
80        self.body = []
81        self.lc = 0
82
83    def append(self, text):
84        is_str = False
85        if type(text) is str:
86            is_str = True
87        try:
88            if type(text) is unicode:
89                is_str = True
90        except:
91            pass
92        if is_str:
93            text = text.splitlines()
94        if not log.quiet:
95            i = 0
96            for l in text:
97                i += 1
98                log.output('script:%3d: %s' % (self.lc + i, l))
99        self.lc += len(text)
100        self.body.extend(text)
101
102    def write(self, name, check_for_errors = False):
103        s = None
104        try:
105            s = open(path.host(name), 'w')
106            s.write('\n'.join(self.body))
107            s.close()
108            os.chmod(path.host(name), stat.S_IRWXU | \
109                         stat.S_IRGRP | stat.S_IXGRP | \
110                         stat.S_IROTH | stat.S_IXOTH)
111        except IOError as err:
112            raise error.general('creating script: ' + name)
113        except:
114            if s is not None:
115                s.close()
116            raise
117        if s is not None:
118            s.close()
119
120class build:
121    """Build a package given a config file."""
122
123    def _generate_report_(self, header, footer = None):
124        ereport.generate('rsb-report-%s.txt' % self.macros['name'],
125                         self.opts, header, footer)
126
127    def __init__(self, name, create_tar_files, opts, macros = None):
128        try:
129            self.opts = opts
130            self.init_name = name
131            self.init_macros = macros
132            self.config = None
133            self.create_tar_files = create_tar_files
134            log.notice('config: ' + name)
135            self.set_macros(macros)
136            self.config = config.file(name, opts, self.macros)
137            self.script_build = script()
138            self.script_clean = script()
139            self.macros['buildname'] = short_name(self.macros['name'])
140        except error.general as gerr:
141            log.notice(str(gerr))
142            log.stderr('Build FAILED')
143            raise
144        except error.internal as ierr:
145            log.notice(str(ierr))
146            log.stderr('Internal Build FAILED')
147            raise
148        except:
149            raise
150
151    def copy_init_macros(self):
152        return copy.copy(self.init_macros)
153
154    def copy_macros(self):
155        return copy.copy(self.macros)
156
157    def set_macros(self, macros):
158        if macros is None:
159            self.macros = copy.copy(self.opts.defaults)
160        else:
161            self.macros = copy.copy(macros)
162        if self.config:
163            self.config.set_macros(self.macros)
164
165    def rmdir(self, rmpath):
166        log.output('removing: %s' % (path.host(rmpath)))
167        if not self.opts.dry_run():
168            if path.exists(rmpath):
169                path.removeall(rmpath)
170
171    def mkdir(self, mkpath):
172        log.output('making dir: %s' % (path.host(mkpath)))
173        if not self.opts.dry_run():
174            path.mkdir(mkpath)
175
176    def canadian_cross(self):
177        _host = self.config.expand('%{_host}')
178        _build = self.config.expand('%{_build}')
179        _target = self.config.expand('%{_target}')
180        _allowed = self.config.defined('%{allow_cxc}')
181        if len(_host) and len(_build) and (_target) and \
182           _allowed and _host != _build and _host != _target:
183            return True
184        return False
185
186    def installable(self):
187        _host = self.config.expand('%{_host}')
188        _build = self.config.expand('%{_build}')
189        _canadian_cross = self.canadian_cross()
190        if self.macros.get('_disable_installing') and \
191           self.config.expand('%{_disable_installing}') == 'yes':
192            _disable_installing = True
193        else:
194            _disable_installing = False
195        _no_install = self.opts.no_install()
196        log.trace('_build: installable: host=%s build=%s ' \
197                  'no-install=%r Cxc=%r disable_installing=%r disabled=%r' % \
198                  (_host, _build, _no_install, _canadian_cross, _disable_installing, \
199                   self.disabled()))
200        return len(_host) and len(_build) and \
201            not self.disabled() and \
202            not _disable_installing and \
203            not _canadian_cross
204
205    def source(self, name, strip_components, download_only):
206        #
207        # Return the list of sources. Merge in any macro defined sources as
208        # these may be overridden by user loaded macros.
209        #
210        _map = 'source-%s' % (name)
211        src_keys = [s for s in self.macros.map_keys(_map) if s != 'setup']
212        if len(src_keys) == 0:
213            raise error.general('no source set: %s (%s)' % (name, _map))
214        srcs = []
215        for s in src_keys:
216            sm = self.macros.get(s, globals = False, maps = _map)
217            if sm is None:
218                raise error.internal('source macro not found: %s in %s (%s)' % \
219                                         (s, name, _map))
220            opts = []
221            url = []
222            for sp in sm[2].split():
223                if len(url) == 0 and sp[0] == '-':
224                    opts += [sp]
225                else:
226                    url += [sp]
227            if len(url) == 0:
228                raise error.general('source URL not found: %s' % (' '.join(args)))
229            #
230            # Look for --rsb-file as an option we use as a local file name.
231            # This can be used if a URL has no reasonable file name the
232            # download URL parser can figure out.
233            #
234            file_override = None
235            if len(opts) > 0:
236                for o in opts:
237                    if o.startswith('--rsb-file'):
238                       os_ = o.split('=')
239                       if len(os_) != 2:
240                           raise error.general('invalid --rsb-file option: %s' % \
241                                               (' '.join(args)))
242                       if os_[0] != '--rsb-file':
243                           raise error.general('invalid --rsb-file option: %s' % \
244                                               (' '.join(args)))
245                       file_override = os_[1]
246                opts = [o for o in opts if not o.startswith('--rsb-')]
247            url = self.config.expand(' '.join(url))
248            src = download.parse_url(url, '_sourcedir',
249                                     self.config, self.opts, file_override)
250            download.get_file(src['url'], src['local'], self.opts, self.config)
251            if not download_only:
252                if strip_components > 0:
253                    tar_extract = '%%{__tar_extract} --strip-components %d' % \
254                        (strip_components)
255                else:
256                    tar_extract = '%{__tar_extract}'
257                if 'symlink' in src:
258                    sname = name.replace('-', '_')
259                    src['script'] = '%%{__ln_s} %s ${source_dir_%s}' % \
260                        (src['symlink'], sname)
261                elif 'compressed' in src:
262                    #
263                    # Zip files unpack as well so do not use tar.
264                    #
265                    src['script'] = '%s %s' % (src['compressed'], src['local'])
266                    if src['compressed-type'] != 'zip':
267                        src['script'] += ' | %s -f -' % (tar_extract)
268                else:
269                    src['script'] = '%s -f %s' % (tar_extract, src['local'])
270                srcs += [src]
271        return srcs
272
273    def source_setup(self, package, args):
274        log.output('source setup: %s: %s' % (package.name(), ' '.join(args)))
275        setup_name = args[1]
276        args = args[1:]
277        try:
278            opts, args = getopt.getopt(args[1:], 'qDcn:bas:gE')
279        except getopt.GetoptError as ge:
280            raise error.general('source setup error: %s' % str(ge))
281        quiet = False
282        unpack_before_chdir = True
283        delete_before_unpack = True
284        create_dir = False
285        deleted_dir = False
286        created_dir = False
287        changed_dir = False
288        no_errors = False
289        strip_components = 0
290        opt_name = None
291        download_only = False
292        for o in opts:
293            if o[0] == '-q':
294                quiet = True
295            elif o[0] == '-D':
296                delete_before_unpack = False
297            elif o[0] == '-c':
298                create_dir = True
299            elif o[0] == '-n':
300                opt_name = o[1]
301            elif o[0] == '-b':
302                unpack_before_chdir = True
303            elif o[0] == '-a':
304                unpack_before_chdir = False
305            elif o[0] == '-E':
306                no_errors = True
307            elif o[0] == '-s':
308                if not o[1].isdigit():
309                    raise error.general('source setup error: invalid strip count: %s' % \
310                                        (o[1]))
311                strip_components = int(o[1])
312            elif o[0] == '-g':
313                download_only = True
314        name = None
315        for source in self.source(setup_name, strip_components, download_only):
316            if name is None:
317                if opt_name is None:
318                    if source:
319                        opt_name = source['name']
320                    else:
321                        raise error.general('setup source tag not found: %d' % \
322                                            (source_tag))
323                else:
324                    name = opt_name
325            if not download_only:
326                self.script_build.append(self.config.expand('cd %{_builddir}'))
327                if not deleted_dir and delete_before_unpack and name is not None:
328                    self.script_build.append(self.config.expand('%{__rm} -rf ' + name))
329                    deleted_dir = True
330                if not created_dir and create_dir and name is not None:
331                    self.script_build.append(self.config.expand('%{__mkdir_p} ' + name))
332                    created_dir = True
333                if not changed_dir and (not unpack_before_chdir or create_dir) and \
334                   name is not None:
335                    self.script_build.append(self.config.expand('cd ' + name))
336                    changed_dir = True
337                #
338                # On Windows tar can fail on links if the link appears in the
339                # tar file before the target of the link exists. We can assume the
340                # tar file is correct, that is all files and links are valid,
341                # so on error redo the untar a second time.
342                #
343                if options.host_windows or no_errors:
344                    self.script_build.append('set +e')
345                self.script_build.append(self.config.expand(source['script']))
346                if options.host_windows or not no_errors:
347                    self.script_build.append('tar_exit=$?')
348                if options.host_windows or no_errors:
349                    self.script_build.append('set -e')
350                if options.host_windows:
351                    if no_errors:
352                        self.script_build.append(' set +e')
353                        self.script_build.append(' ' + self.config.expand(source['script']))
354                        self.script_build.append(' set -e')
355                    else:
356                        self.script_build.append('if test $tar_exit != 0; then')
357                        self.script_build.append(' ' + self.config.expand(source['script']))
358                        self.script_build.append('fi')
359        if not changed_dir and (unpack_before_chdir and not create_dir) and \
360           name is not None and not download_only:
361            self.script_build.append(self.config.expand('cd ' + name))
362            changed_dir = True
363        self.script_build.append(self.config.expand('%{__setup_post}'))
364
365    def patch_setup(self, package, args):
366        name = args[1]
367        args = args[2:]
368        _map = 'patch-%s' % (name)
369        default_opts = ' '.join(args)
370        patch_keys = [p for p in self.macros.map_keys(_map) if p != 'setup']
371        patches = []
372        for p in patch_keys:
373            pm = self.macros.get(p, globals = False, maps = _map)
374            if pm is None:
375                raise error.internal('patch macro not found: %s in %s (%s)' % \
376                                         (p, name, _map))
377            opts = []
378            url = []
379            for pp in pm[2].split():
380                if len(url) == 0 and pp[0] == '-':
381                    opts += [pp]
382                else:
383                    url += [pp]
384            if len(url) == 0:
385                raise error.general('patch URL not found: %s' % (' '.join(opts)))
386            #
387            # Look for --rsb-file as an option we use as a local file name.
388            # This can be used if a URL has no reasonable file name the
389            # download URL parser can figure out.
390            #
391            file_override = None
392            if len(opts) > 0:
393                for o in opts:
394                    if o.startswith('--rsb-file'):
395                       os_ = o.split('=')
396                       if len(os_) != 2:
397                           raise error.general('invalid --rsb-file option: %s' % \
398                                               (' '.join(opts)))
399                       if os_[0] != '--rsb-file':
400                           raise error.general('invalid --rsb-file option: %s' % \
401                                               (' '.join(opts)))
402                       file_override = os_[1]
403                opts = [o for o in opts if not o.startswith('--rsb-')]
404            if len(opts) == 0:
405                opts = default_opts
406            else:
407                opts = ' '.join(opts)
408            opts = self.config.expand(opts)
409            url = self.config.expand(' '.join(url))
410            #
411            # Parse the URL first in the source builder's patch directory.
412            #
413            patch = download.parse_url(url, '_patchdir', self.config,
414                                       self.opts, file_override)
415            #
416            # Download the patch
417            #
418            download.get_file(patch['url'], patch['local'], self.opts, self.config)
419            if 'compressed' in patch:
420                patch['script'] = patch['compressed'] + ' ' +  patch['local']
421            else:
422                patch['script'] = '%{__cat} ' + patch['local']
423            patch['script'] += ' | %%{__patch} %s' % (opts)
424            self.script_build.append(self.config.expand(patch['script']))
425
426    def run(self, command, shell_opts = '', cwd = None):
427        e = execute.capture_execution(log = log.default, dump = self.opts.quiet())
428        cmd = self.config.expand('%{___build_shell} -ex ' + shell_opts + ' ' + command)
429        log.output('run: ' + cmd)
430        exit_code, proc, output = e.shell(cmd, cwd = path.host(cwd))
431        if exit_code != 0:
432            log.output('shell cmd failed: %s' % (cmd))
433            raise error.general('building %s' % (self.macros['buildname']))
434
435    def builddir(self):
436        builddir = self.config.abspath('_builddir')
437        self.rmdir(builddir)
438        if not self.opts.dry_run():
439            self.mkdir(builddir)
440
441    def prep(self, package):
442        self.script_build.append('echo "==> %prep:"')
443        _prep = package.prep()
444        if _prep:
445            for l in _prep:
446                args = l.split()
447                if len(args):
448                    def err(msg):
449                        raise error.general('%s: %s' % (package, msg))
450                    if args[0] == '%setup':
451                        if len(args) == 1:
452                            raise error.general('invalid %%setup directive: %s' % \
453                                                (' '.join(args)))
454                        if args[1] == 'source':
455                            self.source_setup(package, args[1:])
456                        elif args[1] == 'patch':
457                            self.patch_setup(package, args[1:])
458                    elif args[0] in ['%patch', '%source']:
459                        sources.process(args[0][1:], args[1:], self.macros, err)
460                    elif args[0] == '%hash':
461                        sources.hash(args[1:], self.macros, err)
462                        self.hash(package, args)
463                    else:
464                        self.script_build.append(' '.join(args))
465
466    def build(self, package):
467        self.script_build.append('echo "==> clean %{buildroot}: ${SB_BUILD_ROOT}"')
468        self.script_build.append('%s ${SB_BUILD_ROOT}' %
469                                 (self.config.expand('%{__rmdir}')))
470        self.script_build.append('%s ${SB_BUILD_ROOT}' %
471                                 (self.config.expand('%{__mkdir_p}')))
472        self.script_build.append('echo "==> %build:"')
473        _build = package.build()
474        if _build:
475            for l in _build:
476                self.script_build.append(l)
477
478    def install(self, package):
479        self.script_build.append('echo "==> %install:"')
480        _install = package.install()
481        if _install:
482            for l in _install:
483                args = l.split()
484                self.script_build.append(' '.join(args))
485
486    def files(self, package):
487        if self.create_tar_files \
488           and not self.macros.get('%{_disable_packaging'):
489            self.script_build.append('echo "==> %files:"')
490            inpath = path.abspath(self.config.expand('%{buildroot}'))
491            tardir = path.abspath(self.config.expand('%{_tardir}'))
492            self.script_build.append(self.config.expand('if test -d %s; then' % (inpath)))
493            self.script_build.append(self.config.expand('  %%{__mkdir_p} %s' % tardir))
494            self.script_build.append(self.config.expand('  cd ' + inpath))
495            tar = path.join(tardir, package.long_name() + '.tar.bz2')
496            cmd = self.config.expand('  %{__tar} -cf - . ' + '| %{__bzip2} > ' + tar)
497            self.script_build.append(cmd)
498            self.script_build.append(self.config.expand('  cd %{_builddir}'))
499            self.script_build.append('fi')
500
501    def clean(self, package):
502        self.script_clean.reset()
503        self.script_clean.append(self.config.expand('%{___build_template}'))
504        self.script_clean.append('echo "=> ' + package.name() + ': CLEAN"')
505        self.script_clean.append('echo "==> %clean:"')
506        _clean = package.clean()
507        if _clean is not None:
508            for l in _clean:
509                args = l.split()
510                self.script_clean.append(' '.join(args))
511
512    def sizes(self, package):
513        def _sizes(package, what, path):
514            package.set_size(what, path)
515            s = humanize_number(package.get_size(what), 'B')
516            log.trace('size: %s (%s): %s (%d)' % (what, path, s, package.get_size(what)))
517            return s
518        s = {}
519        for p in [('build', '%{_builddir}'),
520                  ('build', '%{buildroot}'),
521                  ('installed', '%{buildroot}')]:
522            hs = _sizes(package, p[0], self.config.expand(p[1]))
523            s[p[0]] = hs
524        log.notice('sizes: %s: %s (installed: %s)' % (package.name(),
525                                                      s['build'],
526                                                      s['installed']))
527
528    def build_package(self, package):
529        if self.canadian_cross():
530            if not self.config.defined('%{allow_cxc}'):
531                raise error.general('Canadian Cross is not allowed')
532            self.script_build.append('echo "==> Candian-cross build/target:"')
533            self.script_build.append('SB_CXC="yes"')
534        else:
535            self.script_build.append('SB_CXC="no"')
536        self.build(package)
537        self.install(package)
538        self.files(package)
539        if not self.opts.no_clean():
540            self.clean(package)
541
542    def cleanup(self):
543        package = self.main_package()
544        if not package.disabled() and not self.opts.no_clean():
545            buildroot = self.config.abspath('buildroot')
546            builddir = self.config.abspath('_builddir')
547            buildcxcdir = self.config.abspath('_buildcxcdir')
548            tmproot = self.config.abspath('_tmproot')
549            log.trace('cleanup: %s' % (buildroot))
550            self.rmdir(buildroot)
551            log.trace('cleanup: %s' % (builddir))
552            self.rmdir(builddir)
553            if self.canadian_cross():
554                log.trace('cleanup: %s' % (buildcxcdir))
555                self.rmdir(buildcxcdir)
556            log.trace('cleanup: %s' % (tmproot))
557            self.rmdir(tmproot)
558
559    def main_package(self):
560        packages = self.config.packages()
561        return packages['main']
562
563    def reload(self):
564        self.config.load(self.init_name)
565
566    def make(self):
567        package = self.main_package()
568        if package.disabled():
569            log.notice('package: nothing to build')
570        else:
571            try:
572                name = package.name()
573                if self.canadian_cross():
574                    cxc_label = '(Cxc) '
575                else:
576                    cxc_label = ''
577                log.notice('package: %s%s' % (cxc_label, name))
578                log.trace('---- macro maps %s' % ('-' * 55))
579                log.trace('%s' % (str(self.config.macros)))
580                log.trace('-' * 70)
581                self.script_build.reset()
582                self.script_build.append(self.config.expand('%{___build_template}'))
583                self.script_build.append('echo "=> ' + name + ': BUILD"')
584                self.prep(package)
585                self.build_package(package)
586                if not self.opts.dry_run():
587                    self.builddir()
588                    build_sn = path.join(self.config.expand('%{_builddir}'), 'do-build')
589                    log.output('write script: ' + build_sn)
590                    self.script_build.write(build_sn)
591                    clean_sn = path.join(self.config.expand('%{_builddir}'), 'do-clean')
592                    log.output('write script: ' + clean_sn)
593                    self.script_clean.write(clean_sn)
594                    log.notice('building: %s%s' % (cxc_label, name))
595                    self.run(build_sn)
596                    self.sizes(package)
597                    log.notice('cleaning: %s%s' % (cxc_label, name))
598                    self.run(clean_sn)
599            except error.general as gerr:
600                log.notice(str(gerr))
601                log.stderr('Build FAILED')
602                self._generate_report_('Build: %s' % (gerr))
603                raise
604            except error.internal as ierr:
605                log.notice(str(ierr))
606                log.stderr('Internal Build FAILED')
607                self._generate_report_('Build: %s' % (ierr))
608                raise
609            except:
610                raise
611            if self.opts.dry_run():
612                self._generate_report_('Build: dry run (no actual error)',
613                                       'Build: dry run (no actual error)')
614
615    def name(self):
616        packages = self.config.packages()
617        package = packages['main']
618        return package.name()
619
620    def disabled(self):
621        packages = self.config.packages()
622        package = packages['main']
623        return package.disabled()
624
625    def get_build_size(self):
626        package = self.main_package()
627        if package.disabled():
628            return 0
629        return package.get_size('build')
630
631    def get_installed_size(self):
632        package = self.main_package()
633        if package.disabled():
634            return 0
635        return package.get_size('installed')
636
637    def includes(self):
638        if self.config:
639            return self.config.includes()
640
641def get_configs(opts):
642
643    def _scan(_path, ext):
644        configs = []
645        for root, dirs, files in os.walk(_path):
646            prefix = root[len(_path) + 1:]
647            for file in files:
648                for e in ext:
649                    if file.endswith(e):
650                        configs += [path.join(prefix, file)]
651        return configs
652
653    configs = { 'paths': [], 'files': [] }
654    paths = opts.defaults.expand('%{_configdir}').split(':')
655    root = path.host(os.path.commonprefix(paths))
656    configs['root'] = root
657    configs['localpaths'] = [lp[len(root):] for lp in paths]
658    for cp in paths:
659        hcp = path.host(path.abspath(cp))
660        configs['paths'] += [hcp]
661        hpconfigs = sorted(set(_scan(hcp, ['.cfg', '.bset'])))
662        hcplocal = hcp[len(root):]
663        configs[hcplocal] = [path.join(hcplocal, c) for c in hpconfigs]
664        configs['files'] += hpconfigs
665    configs['files'] = sorted(set(configs['files']))
666    return configs
667
668def find_config(config, configs):
669    config_root, config_ext = path.splitext(config)
670    if config_ext not in ['', '.bset', '.cfg']:
671        config_root = config
672        config_ext = ''
673    for c in configs['files']:
674        r, e = path.splitext(c)
675        if config_root == r:
676            if config_ext == '' or config_ext == e:
677                return c
678    return None
679
680def run(args):
681    ec = 0
682    try:
683        optargs = { '--list-configs': 'List available configurations' }
684        opts = options.load(args, optargs)
685        log.notice('RTEMS Source Builder, Package Builder, %s' % (version.string()))
686        opts.log_info()
687        if not check.host_setup(opts):
688            if not opts.force():
689                raise error.general('host build environment is not set up' +
690                                    ' correctly (use --force to proceed)')
691            log.notice('warning: forcing build with known host setup problems')
692        if opts.get_arg('--list-configs'):
693            configs = get_configs(opts)
694            for p in configs['paths']:
695                print('Examining: %s' % (os.path.relpath(p)))
696                for c in configs['files']:
697                    if c.endswith('.cfg'):
698                        print('    %s' % (c))
699        else:
700            for config_file in opts.config_files():
701                b = build(config_file, True, opts)
702                b.make()
703                b = None
704    except error.general as gerr:
705        log.stderr('Build FAILED')
706        ec = 1
707    except error.internal as ierr:
708        log.stderr('Internal Build FAILED')
709        ec = 1
710    except error.exit as eerr:
711        pass
712    except KeyboardInterrupt:
713        log.notice('abort: user terminated')
714        ec = 1
715    sys.exit(ec)
716
717if __name__ == "__main__":
718    run(sys.argv)
Note: See TracBrowser for help on using the repository browser.