diff options
Diffstat (limited to 'import-layers/yocto-poky/bitbake/lib/bb/build.py')
-rw-r--r-- | import-layers/yocto-poky/bitbake/lib/bb/build.py | 194 |
1 files changed, 136 insertions, 58 deletions
diff --git a/import-layers/yocto-poky/bitbake/lib/bb/build.py b/import-layers/yocto-poky/bitbake/lib/bb/build.py index db5072cb4..c4c8aeb64 100644 --- a/import-layers/yocto-poky/bitbake/lib/bb/build.py +++ b/import-layers/yocto-poky/bitbake/lib/bb/build.py @@ -35,8 +35,8 @@ import stat import bb import bb.msg import bb.process -from contextlib import nested -from bb import event, utils +import bb.progress +from bb import data, event, utils bblogger = logging.getLogger('BitBake') logger = logging.getLogger('BitBake.Build') @@ -61,8 +61,13 @@ def reset_cache(): # 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. -__builtins__['bb'] = bb -__builtins__['os'] = os +if hasattr(__builtins__, '__setitem__'): + builtins = __builtins__ +else: + builtins = __builtins__.__dict__ + +builtins['bb'] = bb +builtins['os'] = os class FuncFailed(Exception): def __init__(self, name = None, logfile = None): @@ -133,6 +138,25 @@ class TaskInvalid(TaskBase): super(TaskInvalid, self).__init__(task, 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): @@ -164,11 +188,10 @@ class LogTee(object): def exec_func(func, d, dirs = None, pythonexception=False): """Execute a BB 'function'""" - body = d.getVar(func, False) - if not body: - if body is None: - logger.warn("Function %s doesn't exist", func) - return + try: + oldcwd = os.getcwd() + except: + oldcwd = None flags = d.getVarFlags(func) cleandirs = flags.get('cleandirs') @@ -187,8 +210,13 @@ def exec_func(func, d, dirs = None, pythonexception=False): bb.utils.mkdirhier(adir) adir = dirs[-1] else: - adir = d.getVar('B', True) - bb.utils.mkdirhier(adir) + 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') @@ -233,6 +261,18 @@ def exec_func(func, d, dirs = None, pythonexception=False): 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) """ @@ -248,7 +288,8 @@ def exec_func_python(func, d, runfile, cwd=None, pythonexception=False): if cwd: try: olddir = os.getcwd() - except OSError: + except OSError as e: + bb.warn("%s: Cannot get cwd: %s" % (func, e)) olddir = None os.chdir(cwd) @@ -274,8 +315,8 @@ def exec_func_python(func, d, runfile, cwd=None, pythonexception=False): if cwd and olddir: try: os.chdir(olddir) - except OSError: - pass + except OSError as e: + bb.warn("%s: Cannot restore cwd %s: %s" % (func, olddir, e)) def shell_trap_code(): return '''#!/bin/sh\n @@ -323,7 +364,7 @@ trap '' 0 exit $ret ''') - os.chmod(runfile, 0775) + os.chmod(runfile, 0o775) cmd = runfile if d.getVarFlag(func, 'fakeroot', False): @@ -336,41 +377,64 @@ exit $ret else: logfile = sys.stdout + progress = d.getVarFlag(func, 'progress', True) + if progress: + if progress == 'percent': + # Use default regex + logfile = bb.progress.BasicProgressHandler(d, outfile=logfile) + elif progress.startswith('percent:'): + # Use specified regex + logfile = bb.progress.BasicProgressHandler(d, regex=progress.split(':', 1)[1], outfile=logfile) + elif progress.startswith('outof:'): + # Use specified regex + logfile = bb.progress.OutOfProgressHandler(d, regex=progress.split(':', 1)[1], outfile=logfile) + else: + bb.warn('%s: invalid task progress varflag value "%s", ignoring' % (func, progress)) + + fifobuffer = bytearray() def readfifo(data): - lines = data.split('\0') - for line in lines: - splitval = line.split(' ', 1) - cmd = splitval[0] - if len(splitval) > 1: - value = splitval[1] + 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 == '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: - value = '' - if cmd == 'bbplain': - bb.plain(value) - elif cmd == 'bbnote': - bb.note(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) + break tempdir = d.getVar('T', True) fifopath = os.path.join(tempdir, 'fifo.%s' % os.getpid()) if os.path.exists(fifopath): os.unlink(fifopath) os.mkfifo(fifopath) - with open(fifopath, 'r+') as fifo: + with open(fifopath, 'r+b', buffering=0) as fifo: try: bb.debug(2, "Executing shell function %s" % func) @@ -501,21 +565,32 @@ def _exec_task(fn, task, d, quieterr): flags = localdata.getVarFlags(task) - event.fire(TaskStarted(task, logfn, flags, localdata), localdata) try: - for func in (prefuncs or '').split(): - exec_func(func, localdata) - exec_func(task, localdata) - for func in (postfuncs or '').split(): - exec_func(func, localdata) - except FuncFailed as exc: - if quieterr: - event.fire(TaskFailedSilent(task, logfn, localdata), localdata) - else: - errprinted = errchk.triggered + try: + event.fire(TaskStarted(task, logfn, flags, localdata), localdata) + except (bb.BBHandledException, SystemExit): + return 1 + except FuncFailed as exc: logger.error(str(exc)) - event.fire(TaskFailed(task, logfn, localdata, errprinted), localdata) - return 1 + return 1 + + try: + for func in (prefuncs or '').split(): + exec_func(func, localdata) + exec_func(task, localdata) + for func in (postfuncs or '').split(): + exec_func(func, localdata) + except FuncFailed as exc: + if quieterr: + event.fire(TaskFailedSilent(task, logfn, localdata), localdata) + else: + errprinted = errchk.triggered + logger.error(str(exc)) + event.fire(TaskFailed(task, logfn, localdata, errprinted), localdata) + return 1 + except bb.BBHandledException: + event.fire(TaskFailed(task, logfn, localdata, True), localdata) + return 1 finally: sys.stdout.flush() sys.stderr.flush() @@ -575,7 +650,7 @@ def exec_task(fn, task, d, profile = False): event.fire(failedevent, d) return 1 -def stamp_internal(taskname, d, file_name, baseonly=False): +def stamp_internal(taskname, d, file_name, baseonly=False, noextra=False): """ Internal stamp helper function Makes sure the stamp directory exists @@ -598,6 +673,8 @@ def stamp_internal(taskname, d, file_name, baseonly=False): if baseonly: return stamp + if noextra: + extrainfo = "" if not stamp: return @@ -693,12 +770,12 @@ def write_taint(task, d, file_name = None): with open(taintfn, 'w') as taintf: taintf.write(str(uuid.uuid4())) -def stampfile(taskname, d, file_name = None): +def stampfile(taskname, d, file_name = None, noextra=False): """ Return the stamp for a given task (d can be a data dict or dataCache) """ - return stamp_internal(taskname, d, file_name) + return stamp_internal(taskname, d, file_name, noextra=noextra) def add_tasks(tasklist, d): task_deps = d.getVar('_task_deps', False) @@ -774,6 +851,7 @@ def deltask(task, d): 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') |