Exemplo n.º 1
0
def build(ctx):
    # Exit early if we're just viewing the state.
    if ctx.options.dump_state:
        # print out the entire state
        ctx.db.dump_database()
        return 0

    # Exit early if we're just deleting a function.
    if ctx.options.delete_function:
        if not ctx.db.delete_function(ctx.options.delete_function):
            raise fbuild.Error('function %r not cached' %
                               ctx.options.delete_function)
        return 0

    # Exit early if we're just deleting a file.
    if ctx.options.delete_file:
        if not ctx.db.delete_file(ctx.options.delete_file):
            raise fbuild.Error('file %r not cached' % ctx.options.delete_file)
        return 0

    # We'll use the arguments as our targets.
    targets = ctx.options.targets

    # Installation stuff.
    if 'install' in targets:
        if targets[-1] != 'install':
            raise fbuild.Error('install must be last target')
        if not set(targets) - {'configure', 'install'}:
            targets.insert(targets.index('install') - 1, 'build')

    # Step through each target and execute it.
    for target_name in targets:
        if target_name == 'install':
            try:
                pre_install = getattr(fbuildroot, 'pre_install')
            except AttributeError:
                pass
            else:
                pre_install(ctx)

            install_files(ctx)

            try:
                post_install = getattr(fbuildroot, 'post_install')
            except AttributeError:
                pass
            else:
                post_install(ctx)
        else:
            target = fbuild.target.find(target_name)
            target.function(ctx)

    return 0
Exemplo n.º 2
0
 def install(self, path, category, addroot=''):
     try:
         self.to_install[category].append((Path(path).abspath(), addroot))
     except AttributeError:
         pass
     except KeyError:
         raise fbuild.Error('invalid install category: {}'.format(category))
Exemplo n.º 3
0
def find(target_name):
    """Look up and return a target."""

    try:
        return _targets[target_name]
    except KeyError:
        raise fbuild.Error('invalid target %r' % target_name)
Exemplo n.º 4
0
    def __init__(self, ctx, *, engine, explain=False):
        def handle_rpc(method, *args, **kwargs):
            return method(*args, **kwargs)

        self._ctx = ctx
        self._explain = explain
        self._connected = False

        if engine == 'pickle':
            self._backend = fbuild.db.pickle_backend.PickleBackend(self._ctx)
        elif engine == 'cache':
            self._backend = fbuild.db.cache_backend.CacheBackend(self._ctx)
        elif engine == 'sqlite':
            self._backend = fbuild.db.sqlite_backend.SqliteBackend(self._ctx)
        else:
            raise fbuild.Error('unknown backend: %s' % engine)

        self._rpc = fbuild.rpc.RPC(handle_rpc)
        self._rpc.daemon = True
        self.start()
Exemplo n.º 5
0
def main(argv=None):
    # Register a couple functions as targets.
    for name in ('configure', 'build'):
        try:
            fbuild.target.register(name=name)(getattr(fbuildroot, name))
        except AttributeError:
            pass

    # Get the prune handlers.
    try:
        prune_get_all = fbuildroot.prune_get_all
    except:

        def prune_get_all(ctx, root=None):
            files = set()
            if root is None:
                root = ctx.buildroot
            for dirpath, dirnames, filenames in root.walk():
                files.update(map(dirpath.__truediv__, filenames))
            return files

    try:
        prune_get_bad = fbuildroot.prune_get_bad
    except:

        def prune_get_bad(ctx, files):
            return files

    # --------------------------------------------------------------------------

    ctx = parse_args(sys.argv if argv is None else argv)

    # --------------------------------------------------------------------------
    # Replace the ctrl-c signal handler with one that will shut down the
    # scheduler before moving on.

    old_handler = signal.getsignal(signal.SIGINT)

    def handle_interrupt(signum, frame):
        ctx.scheduler.shutdown()
        old_handler(signum, frame)

    signal.signal(signal.SIGINT, handle_interrupt)

    # --------------------------------------------------------------------------

    # If we don't wrap this in a try...finally block to shutdown the scheduler
    # after all else finishes, fbuild will hang indefinitely
    try:

        # If the fbuildroot doesn't exist, error out. We do this now so that
        # there's a chance to ask fbuild for help first.
        if isinstance(fbuildroot, Exception):
            if not os.path.exists('fbuildroot.py'):
                raise fbuild.Error('Cannot find fbuildroot.py')
            else:
                raise fbuildroot

        # Exit early if we want to clean the buildroot.
        if ctx.options.clean_buildroot:
            # Only try to clean the buildroot if it actually exists.
            if ctx.options.buildroot.exists():
                ctx.options.buildroot.rmtree()
            return

        # Prep the context for running.
        ctx.create_buildroot()
        ctx.load_configuration()

        # ... and then run the build.
        try:
            result = build(ctx)
            if ctx.options.prune:
                ctx.prune(prune_get_all, prune_get_bad)
        except fbuild.Error as e:
            ctx.logger.log(e, color='red')
            sys.exit(1)
        except KeyboardInterrupt:
            # It appears that we can't reliably shutdown the scheduler's threads
            # when SIGINT is emitted, because python may raise KeyboardInterrupt
            # between the finally and the mutex.release call.  So, we can find
            # ourselves exiting functions with the lock still held.  This could
            # then cause deadlocks if that lock was ever acquired again.  Oiy.
            print('Interrupted, saving state...')
            raise
        finally:
            ctx.save_configuration()
            ctx.db.shutdown()
    finally:
        ctx.scheduler.shutdown()

    return result
Exemplo n.º 6
0
def autoconf_config_header(ctx, dst, src:fbuild.db.SRC, patterns, *,
        buildroot=None) -> fbuild.db.DST:
    """L{autoconf_config_header} replaces the I{patterns} in the file named
    I{src} and saves the changes into file named I{dst}. It uses autoconf
    AC_CONFIG_HEADERS @word@ and #define patterns to find the insertion
    points."""

    buildroot = buildroot or ctx.buildroot
    src = fbuild.path.Path(src)
    dst = fbuild.path.Path.addroot(dst, buildroot)
    dst.parent.makedirs()

    ctx.logger.log(' * creating ' + dst, color='yellow')

    missing_definitions = []

    def replace(match):
        if match.group('sub'):
            # Handle the @foo@ substitution
            value = patterns[match.group('sub')]
            if isinstance(value, str):
                return value
            elif isinstance(value, collections.Iterable):
                return ' '.join(str(v) for v in value)
            return str(value)
        else:
            # Handle the #undef replacement
            key = match.group('def')
            try:
                value = patterns[key]
            except KeyError:
                # We couldn't find a value for this
                # key, so log it and continue on.
                missing_definitions.append(key)
                value = None

            if isinstance(value, bool):
                value = int(value)
            elif \
                    not isinstance(value, str) and \
                    isinstance(value, collections.Iterable):
                value = ' '.join(str(v) for v in value)

            if value:
                return '#define %s %s' % (key, value)
            else:
                return '/* #undef %s */' % (key)

    with open(src, 'r') as src_file:
        code = src_file.read()

    code = re.sub('(^#undef +(?P<def>\w+)$)|(?:@(?P<sub>\w+)@)', replace, code,
        flags=re.M)

    if missing_definitions:
        raise fbuild.Error('missing definitions: %s' %
            ' '.join(missing_definitions))

    with open(dst, 'w') as dst_file:
        dst_file.write(code)

    return dst
Exemplo n.º 7
0
def main(argv=None):
    # Register a couple functions as targets.
    for name in ('configure', 'build'):
        try:
            fbuild.target.register(name=name)(getattr(fbuildroot, name))
        except AttributeError:
            pass

    # --------------------------------------------------------------------------

    # Hacky way of enabling warnings before parsing options.
    if '--no-warnings' not in sys.argv:
        warnings.filterwarnings('always', category=fbuild.Deprecation)

    # --------------------------------------------------------------------------

    ctx = parse_args(sys.argv if argv is None else argv)

    # --------------------------------------------------------------------------
    # Replace the ctrl-c signal handler with one that will shut down the
    # scheduler before moving on.

    old_handler = signal.getsignal(signal.SIGINT)

    def handle_interrupt(signum, frame):
        ctx.scheduler.shutdown()
        old_handler(signum, frame)

    signal.signal(signal.SIGINT, handle_interrupt)

    # --------------------------------------------------------------------------

    # If we don't wrap this in a try...finally block to shutdown the scheduler
    # after all else finishes, fbuild will hang indefinitely.
    try:
        # If the fbuildroot doesn't exist, error out. We do this now so that
        # there's a chance to ask fbuild for help first.
        if isinstance(fbuildroot, Exception):
            if not os.path.exists('fbuildroot.py'):
                raise fbuild.Error('Cannot find fbuildroot.py')
            else:
                raise fbuildroot

        # Exit early if we want to clean the buildroot.
        if ctx.options.clean_buildroot:
            # Only try to clean the buildroot if it actually exists.
            if ctx.options.buildroot.exists():
                ctx.options.buildroot.rmtree()
            return

        # Prep the context for running.
        ctx.create_buildroot()
        ctx.load_configuration()

        # ... and then run the build.
        try:
            result = build(ctx)
        except fbuild.Error as e:
            ctx.logger.log(e, color='red')
            sys.exit(1)
        except KeyboardInterrupt:
            # It appears that we can't reliably shutdown the scheduler's threads
            # when SIGINT is emitted, because python may raise KeyboardInterrupt
            # between the finally and the mutex.release call.  So, we can find
            # ourselves exiting functions with the lock still held.  This could
            # then cause deadlocks if that lock was ever acquired again.  Oiy.
            print('Interrupted, saving state...')
            raise
        else:
            # Only delete the temporary directory if the build succeeded.
            ctx.clear_temp_dir()
        finally:
            ctx.save_configuration()
            ctx.db.shutdown()
    finally:
        ctx.scheduler.shutdown()

    return result