#
# BitBake 'Build' implementation
#
# Core code for function execution and task handling in the
# BitBake build tools.
#
# Copyright (C) 2003, 2004  Chris Larson
#
# Based on Gentoo's portage.py.
#
# SPDX-License-Identifier: GPL-2.0-only
#
# Based on functions from the base bb module, Copyright 2003 Holger Schurig

import os
import sys
import logging
import glob
import itertools
import time
import re
import stat
import datetime
import bb
import bb.msg
import bb.process
import bb.progress
from io import StringIO
from bb import data, event, utils

bblogger = logging.getLogger('BitBake')
logger = logging.getLogger('BitBake.Build')

verboseShellLogging = False
verboseStdoutLogging = False

__mtime_cache = {}

def cached_mtime_noerror(f):
    if f not in __mtime_cache:
        try:
            __mtime_cache[f] = os.stat(f)[stat.ST_MTIME]
        except OSError:
            return 0
    return __mtime_cache[f]

def reset_cache():
    global __mtime_cache
    __mtime_cache = {}

# When we execute a Python function, we'd like certain things
# in all namespaces, hence we add them to __builtins__.
# If we do not do this and use the exec globals, they will
# not be available to subfunctions.
if hasattr(__builtins__, '__setitem__'):
    builtins = __builtins__
else:
    builtins = __builtins__.__dict__

builtins['bb'] = bb
builtins['os'] = os

class TaskBase(event.Event):
    """Base class for task events"""

    def __init__(self, t, fn, logfile, d):
        self._task = t
        self._fn = fn
        self._package = d.getVar("PF")
        self._mc = d.getVar("BB_CURRENT_MC")
        self.taskfile = d.getVar("FILE")
        self.taskname = self._task
        self.logfile = logfile
        self.time = time.time()
        self.pn = d.getVar("PN")
        self.pv = d.getVar("PV")
        event.Event.__init__(self)
        self._message = "recipe %s: task %s: %s" % (d.getVar("PF"), t, self.getDisplayName())

    def getTask(self):
        return self._task

    def setTask(self, task):
        self._task = task

    def getDisplayName(self):
        return bb.event.getName(self)[4:]

    task = property(getTask, setTask, None, "task property")

class TaskStarted(TaskBase):
    """Task execution started"""
    def __init__(self, t, fn, logfile, taskflags, d):
        super(TaskStarted, self).__init__(t, fn, logfile, d)
        self.taskflags = taskflags

class TaskSucceeded(TaskBase):
    """Task execution completed"""

class TaskFailed(TaskBase):
    """Task execution failed"""

    def __init__(self, task, fn, logfile, metadata, errprinted = False):
        self.errprinted = errprinted
        super(TaskFailed, self).__init__(task, fn, logfile, metadata)

class TaskFailedSilent(TaskBase):
    """Task execution failed (silently)"""
    def getDisplayName(self):
        # Don't need to tell the user it was silent
        return "Failed"

class TaskInvalid(TaskBase):

    def __init__(self, task, fn, metadata):
        super(TaskInvalid, self).__init__(task, fn, None, metadata)
        self._message = "No such task '%s'" % task

class TaskProgress(event.Event):
    """
    Task made some progress that could be reported to the user, usually in
    the form of a progress bar or similar.
    NOTE: this class does not inherit from TaskBase since it doesn't need
    to - it's fired within the task context itself, so we don't have any of
    the context information that you do in the case of the other events.
    The event PID can be used to determine which task it came from.
    The progress value is normally 0-100, but can also be negative
    indicating that progress has been made but we aren't able to determine
    how much.
    The rate is optional, this is simply an extra string to display to the
    user if specified.
    """
    def __init__(self, progress, rate=None):
        self.progress = progress
        self.rate = rate
        event.Event.__init__(self)


class LogTee(object):
    def __init__(self, logger, outfile):
        self.outfile = outfile
        self.logger = logger
        self.name = self.outfile.name

    def write(self, string):
        self.logger.plain(string)
        self.outfile.write(string)

    def __enter__(self):
        self.outfile.__enter__()
        return self

    def __exit__(self, *excinfo):
        self.outfile.__exit__(*excinfo)

    def __repr__(self):
        return '<LogTee {0}>'.format(self.name)

    def flush(self):
        self.outfile.flush()


class StdoutNoopContextManager:
    """
    This class acts like sys.stdout, but adds noop __enter__ and __exit__ methods.
    """
    def __enter__(self):
        return sys.stdout

    def __exit__(self, *exc_info):
        pass

    def write(self, string):
        return sys.stdout.write(string)

    def flush(self):
        sys.stdout.flush()

    @property
    def name(self):
        if "name" in dir(sys.stdout):
            return sys.stdout.name
        return "<mem>"


def exec_func(func, d, dirs = None):
    """Execute a BB 'function'"""

    try:
        oldcwd = os.getcwd()
    except:
        oldcwd = None

    flags = d.getVarFlags(func)
    cleandirs = flags.get('cleandirs') if flags else None
    if cleandirs:
        for cdir in d.expand(cleandirs).split():
            bb.utils.remove(cdir, True)
            bb.utils.mkdirhier(cdir)

    if flags and dirs is None:
        dirs = flags.get('dirs')
        if dirs:
            dirs = d.expand(dirs).split()

    if dirs:
        for adir in dirs:
            bb.utils.mkdirhier(adir)
        adir = dirs[-1]
    else:
        adir = None

    body = d.getVar(func, False)
    if not body:
        if body is None:
            logger.warning("Function %s doesn't exist", func)
        return

    ispython = flags.get('python')

    lockflag = flags.get('lockfiles')
    if lockflag:
        lockfiles = [f for f in d.expand(lockflag).split()]
    else:
        lockfiles = None

    tempdir = d.getVar('T')

    # or func allows items to be executed outside of the normal
    # task set, such as buildhistory
    task = d.getVar('BB_RUNTASK') or func
    if task == func:
        taskfunc = task
    else:
        taskfunc = "%s.%s" % (task, func)

    runfmt = d.getVar('BB_RUNFMT') or "run.{func}.{pid}"
    runfn = runfmt.format(taskfunc=taskfunc, task=task, func=func, pid=os.getpid())
    runfile = os.path.join(tempdir, runfn)
    bb.utils.mkdirhier(os.path.dirname(runfile))

    # Setup the courtesy link to the runfn, only for tasks
    # we create the link 'just' before the run script is created
    # if we create it after, and if the run script fails, then the
    # link won't be created as an exception would be fired.
    if task == func:
        runlink = os.path.join(tempdir, 'run.{0}'.format(task))
        if runlink:
            bb.utils.remove(runlink)

            try:
                os.symlink(runfn, runlink)
            except OSError:
                pass

    with bb.utils.fileslocked(lockfiles):
        if ispython:
            exec_func_python(func, d, runfile, cwd=adir)
        else:
            exec_func_shell(func, d, runfile, cwd=adir)

    try:
        curcwd = os.getcwd()
    except:
        curcwd = None

    if oldcwd and curcwd != oldcwd:
        try:
            bb.warn("Task %s changed cwd to %s" % (func, curcwd))
            os.chdir(oldcwd)
        except:
            pass

_functionfmt = """
{function}(d)
"""
logformatter = bb.msg.BBLogFormatter("%(levelname)s: %(message)s")
def exec_func_python(func, d, runfile, cwd=None):
    """Execute a python BB 'function'"""

    code = _functionfmt.format(function=func)
    bb.utils.mkdirhier(os.path.dirname(runfile))
    with open(runfile, 'w') as script:
        bb.data.emit_func_python(func, script, d)

    if cwd:
        try:
            olddir = os.getcwd()
        except OSError as e:
            bb.warn("%s: Cannot get cwd: %s" % (func, e))
            olddir = None
        os.chdir(cwd)

    bb.debug(2, "Executing python function %s" % func)

    try:
        text = "def %s(d):\n%s" % (func, d.getVar(func, False))
        fn = d.getVarFlag(func, "filename", False)
        lineno = int(d.getVarFlag(func, "lineno", False))
        bb.methodpool.insert_method(func, text, fn, lineno - 1)

        if verboseStdoutLogging:
            sys.stdout.flush()
            sys.stderr.flush()
            currout = sys.stdout
            currerr = sys.stderr
            sys.stderr = sys.stdout = execio = StringIO()
        comp = utils.better_compile(code, func, "exec_func_python() autogenerated")
        utils.better_exec(comp, {"d": d}, code, "exec_func_python() autogenerated")
    finally:
        if verboseStdoutLogging:
            execio.flush()
            logger.plain("%s" % execio.getvalue())
            sys.stdout = currout
            sys.stderr = currerr
            execio.close()
        # We want any stdout/stderr to be printed before any other log messages to make debugging
        # more accurate. In some cases we seem to lose stdout/stderr entirely in logging tests without this.
        sys.stdout.flush()
        sys.stderr.flush()
        bb.debug(2, "Python function %s finished" % func)

        if cwd and olddir:
            try:
                os.chdir(olddir)
            except OSError as e:
                bb.warn("%s: Cannot restore cwd %s: %s" % (func, olddir, e))

def shell_trap_code():
    return '''#!/bin/sh\n
__BITBAKE_LAST_LINE=0

# Emit a useful diagnostic if something fails:
bb_sh_exit_handler() {
    ret=$?
    if [ "$ret" != 0 ]; then
        echo "WARNING: exit code $ret from a shell command."
    fi
    exit $ret
}

bb_bash_exit_handler() {
    ret=$?
    { set +x; } > /dev/null
    trap "" DEBUG
    if [ "$ret" != 0 ]; then
        echo "WARNING: ${BASH_SOURCE[0]}:${__BITBAKE_LAST_LINE} exit $ret from '$1'"

        echo "WARNING: Backtrace (BB generated script): "
        for i in $(seq 1 $((${#FUNCNAME[@]} - 1))); do
            if [ "$i" -eq 1 ]; then
                echo -e "\t#$((i)): ${FUNCNAME[$i]}, ${BASH_SOURCE[$((i-1))]}, line ${__BITBAKE_LAST_LINE}"
            else
                echo -e "\t#$((i)): ${FUNCNAME[$i]}, ${BASH_SOURCE[$((i-1))]}, line ${BASH_LINENO[$((i-1))]}"
            fi
        done
    fi
    exit $ret
}

bb_bash_debug_handler() {
    local line=${BASH_LINENO[0]}
    # For some reason the DEBUG trap trips with lineno=1 when scripts exit; ignore it
    if [ "$line" -eq 1 ]; then
        return
    fi

    # Track the line number of commands as they execute. This is so we can have access to the failing line number
    # in the EXIT trap. See http://gnu-bash.2382.n7.nabble.com/trap-echo-quot-trap-exit-on-LINENO-quot-EXIT-gt-wrong-linenumber-td3666.html
    if [ "${FUNCNAME[1]}" != "bb_bash_exit_handler" ]; then
        __BITBAKE_LAST_LINE=$line
    fi
}

case $BASH_VERSION in
"") trap 'bb_sh_exit_handler' 0
    set -e
    ;;
*)  trap 'bb_bash_exit_handler "$BASH_COMMAND"' 0
    trap '{ bb_bash_debug_handler; } 2>/dev/null' DEBUG
    set -e
    shopt -s extdebug
    ;;
esac
'''

def create_progress_handler(func, progress, logfile, d):
    if progress == 'percent':
        # Use default regex
        return bb.progress.BasicProgressHandler(d, outfile=logfile)
    elif progress.startswith('percent:'):
        # Use specified regex
        return bb.progress.BasicProgressHandler(d, regex=progress.split(':', 1)[1], outfile=logfile)
    elif progress.startswith('outof:'):
        # Use specified regex
        return bb.progress.OutOfProgressHandler(d, regex=progress.split(':', 1)[1], outfile=logfile)
    elif progress.startswith("custom:"):
        # Use a custom progress handler that was injected via OE_EXTRA_IMPORTS or __builtins__
        import functools
        from types import ModuleType

        parts = progress.split(":", 2)
        _, cls, otherargs = parts[0], parts[1], (parts[2] or None) if parts[2:] else None
        if cls:
            def resolve(x, y):
                if not x:
                    return None
                if isinstance(x, ModuleType):
                    return getattr(x, y, None)
                return x.get(y)
            cls_obj = functools.reduce(resolve, cls.split("."), bb.utils._context)
            if not cls_obj:
                # Fall-back on __builtins__
                cls_obj = functools.reduce(resolve, cls.split("."), __builtins__)
            if cls_obj:
                return cls_obj(d, outfile=logfile, otherargs=otherargs)
            bb.warn('%s: unknown custom progress handler in task progress varflag value "%s", ignoring' % (func, cls))
    else:
        bb.warn('%s: invalid task progress varflag value "%s", ignoring' % (func, progress))

    return logfile

def exec_func_shell(func, d, runfile, cwd=None):
    """Execute a shell function from the metadata

    Note on directory behavior.  The 'dirs' varflag should contain a list
    of the directories you need created prior to execution.  The last
    item in the list is where we will chdir/cd to.
    """

    # Don't let the emitted shell script override PWD
    d.delVarFlag('PWD', 'export')

    with open(runfile, 'w') as script:
        script.write(shell_trap_code())

        bb.data.emit_func(func, script, d)

        if verboseShellLogging or bb.utils.to_boolean(d.getVar("BB_VERBOSE_LOGS", False)):
            script.write("set -x\n")
        if cwd:
            script.write("cd '%s'\n" % cwd)
        script.write("%s\n" % func)
        script.write('''
# cleanup
ret=$?
trap '' 0
exit $ret
''')

    os.chmod(runfile, 0o775)

    cmd = runfile
    if d.getVarFlag(func, 'fakeroot', False):
        fakerootcmd = d.getVar('FAKEROOT')
        if fakerootcmd:
            cmd = [fakerootcmd, runfile]

    # We only want to output to logger via LogTee if stdout is sys.__stdout__ (which will either
    # be real stdout or subprocess PIPE or similar). In other cases we are being run "recursively",
    # ie. inside another function, in which case stdout is already being captured so we don't
    # want to Tee here as output would be printed twice, and out of order.
    if verboseStdoutLogging and sys.stdout == sys.__stdout__:
        logfile = LogTee(logger, StdoutNoopContextManager())
    else:
        logfile = StdoutNoopContextManager()

    progress = d.getVarFlag(func, 'progress')
    if progress:
        try:
            logfile = create_progress_handler(func, progress, logfile, d)
        except:
            from traceback import format_exc
            logger.error("Failed to create progress handler")
            logger.error(format_exc())
            raise

    fifobuffer = bytearray()
    def readfifo(data):
        nonlocal fifobuffer
        fifobuffer.extend(data)
        while fifobuffer:
            message, token, nextmsg = fifobuffer.partition(b"\00")
            if token:
                splitval = message.split(b' ', 1)
                cmd = splitval[0].decode("utf-8")
                if len(splitval) > 1:
                    value = splitval[1].decode("utf-8")
                else:
                    value = ''
                if cmd == 'bbplain':
                    bb.plain(value)
                elif cmd == 'bbnote':
                    bb.note(value)
                elif cmd == 'bbverbnote':
                    bb.verbnote(value)
                elif cmd == 'bbwarn':
                    bb.warn(value)
                elif cmd == 'bberror':
                    bb.error(value)
                elif cmd == 'bbfatal':
                    # The caller will call exit themselves, so bb.error() is
                    # what we want here rather than bb.fatal()
                    bb.error(value)
                elif cmd == 'bbfatal_log':
                    bb.error(value, forcelog=True)
                elif cmd == 'bbdebug':
                    splitval = value.split(' ', 1)
                    level = int(splitval[0])
                    value = splitval[1]
                    bb.debug(level, value)
                else:
                    bb.warn("Unrecognised command '%s' on FIFO" % cmd)
                fifobuffer = nextmsg
            else:
                break

    tempdir = d.getVar('T')
    fifopath = os.path.join(tempdir, 'fifo.%s' % os.getpid())
    if os.path.exists(fifopath):
        os.unlink(fifopath)
    os.mkfifo(fifopath)
    with open(fifopath, 'r+b', buffering=0) as fifo:
        try:
            bb.debug(2, "Executing shell function %s" % func)
            with open(os.devnull, 'r+') as stdin, logfile:
                bb.process.run(cmd, shell=False, stdin=stdin, log=logfile, extrafiles=[(fifo,readfifo)])
        except bb.process.ExecutionError as exe:
            # Find the backtrace that the shell trap generated
            backtrace_marker_regex = re.compile(r"WARNING: Backtrace \(BB generated script\)")
            stdout_lines = (exe.stdout or "").split("\n")
            backtrace_start_line = None
            for i, line in enumerate(reversed(stdout_lines)):
                if backtrace_marker_regex.search(line):
                    backtrace_start_line = len(stdout_lines) - i
                    break

            # Read the backtrace frames, starting at the location we just found
            backtrace_entry_regex = re.compile(r"#(?P<frameno>\d+): (?P<funcname>[^\s]+), (?P<file>.+?), line ("
                                               r"?P<lineno>\d+)")
            backtrace_frames = []
            if backtrace_start_line:
                for line in itertools.islice(stdout_lines, backtrace_start_line, None):
                    match = backtrace_entry_regex.search(line)
                    if match:
                        backtrace_frames.append(match.groupdict())

            with open(runfile, "r") as script:
                script_lines = [line.rstrip() for line in script.readlines()]

            # For each backtrace frame, search backwards in the script (from the line number called out by the frame),
            # to find the comment that emit_vars injected when it wrote the script. This will give us the metadata
            # filename (e.g. .bb or .bbclass) and line number where the shell function was originally defined.
            script_metadata_comment_regex = re.compile(r"# line: (?P<lineno>\d+), file: (?P<file>.+)")
            better_frames = []
            # Skip the very last frame since it's just the call to the shell task in the body of the script
            for frame in backtrace_frames[:-1]:
                # Check whether the frame corresponds to a function defined in the script vs external script.
                if os.path.samefile(frame["file"], runfile):
                    # Search backwards from the frame lineno to locate the comment that BB injected
                    i = int(frame["lineno"]) - 1
                    while i >= 0:
                        match = script_metadata_comment_regex.match(script_lines[i])
                        if match:
                            # Calculate the relative line in the function itself
                            relative_line_in_function = int(frame["lineno"]) - i - 2
                            # Calculate line in the function as declared in the metadata
                            metadata_function_line = relative_line_in_function + int(match["lineno"])
                            better_frames.append("#{frameno}: {funcname}, {file}, line {lineno}".format(
                                frameno=frame["frameno"],
                                funcname=frame["funcname"],
                                file=match["file"],
                                lineno=metadata_function_line
                            ))
                            break
                        i -= 1
                else:
                    better_frames.append("#{frameno}: {funcname}, {file}, line {lineno}".format(**frame))

            if better_frames:
                better_frames = ("\t{0}".format(frame) for frame in better_frames)
                exe.extra_message = "\nBacktrace (metadata-relative locations):\n{0}".format("\n".join(better_frames))
            raise
        finally:
            os.unlink(fifopath)

    bb.debug(2, "Shell function %s finished" % func)

def _task_data(fn, task, d):
    localdata = bb.data.createCopy(d)
    localdata.setVar('BB_FILENAME', fn)
    localdata.setVar('OVERRIDES', 'task-%s:%s' %
                     (task[3:].replace('_', '-'), d.getVar('OVERRIDES', False)))
    bb.data.expandKeys(localdata)
    return localdata

def _exec_task(fn, task, d, quieterr):
    """Execute a BB 'task'

    Execution of a task involves a bit more setup than executing a function,
    running it with its own local metadata, and with some useful variables set.
    """
    if not d.getVarFlag(task, 'task', False):
        event.fire(TaskInvalid(task, fn, d), d)
        logger.error("No such task: %s" % task)
        return 1

    logger.debug("Executing task %s", task)

    localdata = _task_data(fn, task, d)
    tempdir = localdata.getVar('T')
    if not tempdir:
        bb.fatal("T variable not set, unable to build")

    # Change nice level if we're asked to
    nice = localdata.getVar("BB_TASK_NICE_LEVEL")
    if nice:
        curnice = os.nice(0)
        nice = int(nice) - curnice
        newnice = os.nice(nice)
        logger.debug("Renice to %s " % newnice)
    ionice = localdata.getVar("BB_TASK_IONICE_LEVEL")
    if ionice:
        try:
            cls, prio = ionice.split(".", 1)
            bb.utils.ioprio_set(os.getpid(), int(cls), int(prio))
        except:
            bb.warn("Invalid ionice level %s" % ionice)

    bb.utils.mkdirhier(tempdir)

    # Determine the logfile to generate
    logfmt = localdata.getVar('BB_LOGFMT') or 'log.{task}.{pid}'
    logbase = logfmt.format(task=task, pid=os.getpid())

    # Document the order of the tasks...
    logorder = os.path.join(tempdir, 'log.task_order')
    try:
        with open(logorder, 'a') as logorderfile:
            timestamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S.%f")
            logorderfile.write('{0} {1} ({2}): {3}\n'.format(timestamp, task, os.getpid(), logbase))
    except OSError:
        logger.exception("Opening log file '%s'", logorder)
        pass

    # Setup the courtesy link to the logfn
    loglink = os.path.join(tempdir, 'log.{0}'.format(task))
    logfn = os.path.join(tempdir, logbase)
    if loglink:
        bb.utils.remove(loglink)

        try:
           os.symlink(logbase, loglink)
        except OSError:
           pass

    prefuncs = localdata.getVarFlag(task, 'prefuncs', expand=True)
    postfuncs = localdata.getVarFlag(task, 'postfuncs', expand=True)

    class ErrorCheckHandler(logging.Handler):
        def __init__(self):
            self.triggered = False
            logging.Handler.__init__(self, logging.ERROR)
        def emit(self, record):
            if getattr(record, 'forcelog', False):
                self.triggered = False
            else:
                self.triggered = True

    # Handle logfiles
    try:
        bb.utils.mkdirhier(os.path.dirname(logfn))
        logfile = open(logfn, 'w')
    except OSError:
        logger.exception("Opening log file '%s'", logfn)
        pass

    # Dup the existing fds so we dont lose them
    osi = [os.dup(sys.stdin.fileno()), sys.stdin.fileno()]
    oso = [os.dup(sys.stdout.fileno()), sys.stdout.fileno()]
    ose = [os.dup(sys.stderr.fileno()), sys.stderr.fileno()]

    # Replace those fds with our own
    with open('/dev/null', 'r') as si:
        os.dup2(si.fileno(), osi[1])
    os.dup2(logfile.fileno(), oso[1])
    os.dup2(logfile.fileno(), ose[1])

    # Ensure Python logging goes to the logfile
    handler = logging.StreamHandler(logfile)
    handler.setFormatter(logformatter)
    # Always enable full debug output into task logfiles
    handler.setLevel(logging.DEBUG - 2)
    bblogger.addHandler(handler)

    errchk = ErrorCheckHandler()
    bblogger.addHandler(errchk)

    localdata.setVar('BB_LOGFILE', logfn)
    localdata.setVar('BB_RUNTASK', task)
    localdata.setVar('BB_TASK_LOGGER', bblogger)

    flags = localdata.getVarFlags(task)

    try:
        try:
            event.fire(TaskStarted(task, fn, logfn, flags, localdata), localdata)

            for func in (prefuncs or '').split():
                exec_func(func, localdata)
            exec_func(task, localdata)
            for func in (postfuncs or '').split():
                exec_func(func, localdata)
        finally:
            # Need to flush and close the logs before sending events where the
            # UI may try to look at the logs.
            sys.stdout.flush()
            sys.stderr.flush()

            bblogger.removeHandler(handler)

            # Restore the backup fds
            os.dup2(osi[0], osi[1])
            os.dup2(oso[0], oso[1])
            os.dup2(ose[0], ose[1])

            # Close the backup fds
            os.close(osi[0])
            os.close(oso[0])
            os.close(ose[0])

            logfile.close()
            if os.path.exists(logfn) and os.path.getsize(logfn) == 0:
                logger.debug2("Zero size logfn %s, removing", logfn)
                bb.utils.remove(logfn)
                bb.utils.remove(loglink)
    except (Exception, SystemExit) as exc:
        handled = False
        if isinstance(exc, bb.BBHandledException):
            handled = True

        if quieterr:
            if not handled:
                logger.warning(repr(exc))
            event.fire(TaskFailedSilent(task, fn, logfn, localdata), localdata)
        else:
            errprinted = errchk.triggered
            # If the output is already on stdout, we've printed the information in the
            # logs once already so don't duplicate
            if verboseStdoutLogging or handled:
                errprinted = True
            if not handled:
                logger.error(repr(exc))
            event.fire(TaskFailed(task, fn, logfn, localdata, errprinted), localdata)
        return 1

    event.fire(TaskSucceeded(task, fn, logfn, localdata), localdata)

    if not localdata.getVarFlag(task, 'nostamp', False) and not localdata.getVarFlag(task, 'selfstamp', False):
        make_stamp(task, localdata)

    return 0

def exec_task(fn, task, d, profile = False):
    try:
        quieterr = False
        if d.getVarFlag(task, "quieterrors", False) is not None:
            quieterr = True

        if profile:
            profname = "profile-%s.log" % (d.getVar("PN") + "-" + task)
            try:
                import cProfile as profile
            except:
                import profile
            prof = profile.Profile()
            ret = profile.Profile.runcall(prof, _exec_task, fn, task, d, quieterr)
            prof.dump_stats(profname)
            bb.utils.process_profilelog(profname)

            return ret
        else:
            return _exec_task(fn, task, d, quieterr)

    except Exception:
        from traceback import format_exc
        if not quieterr:
            logger.error("Build of %s failed" % (task))
            logger.error(format_exc())
            failedevent = TaskFailed(task, None, d, True)
            event.fire(failedevent, d)
        return 1

def _get_cleanmask(taskname, mcfn):
    """
    Internal stamp helper function to generate stamp cleaning mask
    Returns the stamp path+filename

    In the bitbake core, d can be a CacheData and file_name will be set.
    When called in task context, d will be a data store, file_name will not be set
    """
    cleanmask = bb.parse.siggen.stampcleanmask_mcfn(taskname, mcfn)
    taskflagname = taskname.replace("_setscene", "")
    if cleanmask:
        return [cleanmask, cleanmask.replace(taskflagname, taskflagname + "_setscene")]
    return []

def clean_stamp_mcfn(task, mcfn):
    cleanmask = _get_cleanmask(task, mcfn)
    for mask in cleanmask:
        for name in glob.glob(mask):
            # Preserve sigdata files in the stamps directory
            if "sigdata" in name or "sigbasedata" in name:
                continue
            # Preserve taint files in the stamps directory
            if name.endswith('.taint'):
                continue
            os.unlink(name)

def clean_stamp(task, d):
    mcfn = d.getVar('BB_FILENAME')
    clean_stamp_mcfn(task, mcfn)

def make_stamp_mcfn(task, mcfn):

    basestamp = bb.parse.siggen.stampfile_mcfn(task, mcfn)

    stampdir = os.path.dirname(basestamp)
    if cached_mtime_noerror(stampdir) == 0:
        bb.utils.mkdirhier(stampdir)

    clean_stamp_mcfn(task, mcfn)

    # Remove the file and recreate to force timestamp
    # change on broken NFS filesystems
    if basestamp:
        bb.utils.remove(basestamp)
        open(basestamp, "w").close()

def make_stamp(task, d):
    """
    Creates/updates a stamp for a given task
    """
    mcfn = d.getVar('BB_FILENAME')

    make_stamp_mcfn(task, mcfn)

    # If we're in task context, write out a signature file for each task
    # as it completes
    if not task.endswith("_setscene"):
        stampbase = bb.parse.siggen.stampfile_base(mcfn)
        bb.parse.siggen.dump_sigtask(mcfn, task, stampbase, True)


def find_stale_stamps(task, mcfn):
    current = bb.parse.siggen.stampfile_mcfn(task, mcfn)
    current2 = bb.parse.siggen.stampfile_mcfn(task + "_setscene", mcfn)
    cleanmask = _get_cleanmask(task, mcfn)
    found = []
    for mask in cleanmask:
        for name in glob.glob(mask):
            if "sigdata" in name or "sigbasedata" in name:
                continue
            if name.endswith('.taint'):
                continue
            if name == current or name == current2:
                continue
            logger.debug2("Stampfile %s does not match %s or %s" % (name, current, current2))
            found.append(name)
    return found

def write_taint(task, d):
    """
    Creates a "taint" file which will force the specified task and its
    dependents to be re-run the next time by influencing the value of its
    taskhash.
    """
    mcfn = d.getVar('BB_FILENAME')
    bb.parse.siggen.invalidate_task(task, mcfn)

def add_tasks(tasklist, d):
    task_deps = d.getVar('_task_deps', False)
    if not task_deps:
        task_deps = {}
    if not 'tasks' in task_deps:
        task_deps['tasks'] = []
    if not 'parents' in task_deps:
        task_deps['parents'] = {}

    for task in tasklist:
        task = d.expand(task)

        d.setVarFlag(task, 'task', 1)

        if not task in task_deps['tasks']:
            task_deps['tasks'].append(task)

        flags = d.getVarFlags(task)
        def getTask(name):
            if not name in task_deps:
                task_deps[name] = {}
            if name in flags:
                deptask = d.expand(flags[name])
                if name in ['noexec', 'fakeroot', 'nostamp']:
                    if deptask != '1':
                        bb.warn("In a future version of BitBake, setting the '{}' flag to something other than '1' "
                                "will result in the flag not being set. See YP bug #13808.".format(name))

                task_deps[name][task] = deptask
        getTask('mcdepends')
        getTask('depends')
        getTask('rdepends')
        getTask('deptask')
        getTask('rdeptask')
        getTask('recrdeptask')
        getTask('recideptask')
        getTask('nostamp')
        getTask('fakeroot')
        getTask('noexec')
        getTask('umask')
        task_deps['parents'][task] = []
        if 'deps' in flags:
            for dep in flags['deps']:
                # Check and warn for "addtask task after foo" while foo does not exist
                #if not dep in tasklist:
                #    bb.warn('%s: dependent task %s for %s does not exist' % (d.getVar('PN'), dep, task))
                dep = d.expand(dep)
                task_deps['parents'][task].append(dep)

    # don't assume holding a reference
    d.setVar('_task_deps', task_deps)

def addtask(task, before, after, d):
    if task[:3] != "do_":
        task = "do_" + task

    d.setVarFlag(task, "task", 1)
    bbtasks = d.getVar('__BBTASKS', False) or []
    if task not in bbtasks:
        bbtasks.append(task)
    d.setVar('__BBTASKS', bbtasks)

    existing = d.getVarFlag(task, "deps", False) or []
    if after is not None:
        # set up deps for function
        for entry in after.split():
            if entry not in existing:
                existing.append(entry)
    d.setVarFlag(task, "deps", existing)
    if before is not None:
        # set up things that depend on this func
        for entry in before.split():
            existing = d.getVarFlag(entry, "deps", False) or []
            if task not in existing:
                d.setVarFlag(entry, "deps", [task] + existing)

def deltask(task, d):
    if task[:3] != "do_":
        task = "do_" + task

    bbtasks = d.getVar('__BBTASKS', False) or []
    if task in bbtasks:
        bbtasks.remove(task)
        d.delVarFlag(task, 'task')
        d.setVar('__BBTASKS', bbtasks)

    d.delVarFlag(task, 'deps')
    for bbtask in d.getVar('__BBTASKS', False) or []:
        deps = d.getVarFlag(bbtask, 'deps', False) or []
        if task in deps:
            deps.remove(task)
            d.setVarFlag(bbtask, 'deps', deps)

def preceedtask(task, with_recrdeptasks, d):
    """
    Returns a set of tasks in the current recipe which were specified as
    precondition by the task itself ("after") or which listed themselves
    as precondition ("before"). Preceeding tasks specified via the
    "recrdeptask" are included in the result only if requested. Beware
    that this may lead to the task itself being listed.
    """
    preceed = set()

    # Ignore tasks which don't exist
    tasks = d.getVar('__BBTASKS', False)
    if task not in tasks:
        return preceed

    preceed.update(d.getVarFlag(task, 'deps') or [])
    if with_recrdeptasks:
        recrdeptask = d.getVarFlag(task, 'recrdeptask')
        if recrdeptask:
            preceed.update(recrdeptask.split())
    return preceed

def tasksbetween(task_start, task_end, d):
    """
    Return the list of tasks between two tasks in the current recipe,
    where task_start is to start at and task_end is the task to end at
    (and task_end has a dependency chain back to task_start).
    """
    outtasks = []
    tasks = list(filter(lambda k: d.getVarFlag(k, "task"), d.keys()))
    def follow_chain(task, endtask, chain=None):
        if not chain:
            chain = []
        if task in chain:
            bb.fatal("Circular task dependencies as %s depends on itself via the chain %s" % (task, " -> ".join(chain)))
        chain.append(task)
        for othertask in tasks:
            if othertask == task:
                continue
            if task == endtask:
                for ctask in chain:
                    if ctask not in outtasks:
                        outtasks.append(ctask)
            else:
                deps = d.getVarFlag(othertask, 'deps', False)
                if task in deps:
                    follow_chain(othertask, endtask, chain)
        chain.pop()
    follow_chain(task_start, task_end)
    return outtasks
