diff options
author | Richard Purdie <rpurdie@linux.intel.com> | 2010-01-20 18:46:02 +0000 |
---|---|---|
committer | Richard Purdie <rpurdie@linux.intel.com> | 2010-01-20 18:46:02 +0000 |
commit | 22c29d8651668195f72e2f6a8e059d625eb511c3 (patch) | |
tree | dd1dd43f0ec47a9964c8a766eb8b3ad75cf51a64 /bitbake/lib/bb/build.py | |
parent | 1bfd6edef9db9c9175058ae801d1b601e4f15263 (diff) | |
download | openembedded-core-22c29d8651668195f72e2f6a8e059d625eb511c3.tar.gz openembedded-core-22c29d8651668195f72e2f6a8e059d625eb511c3.tar.bz2 openembedded-core-22c29d8651668195f72e2f6a8e059d625eb511c3.zip |
bitbake: Switch to bitbake-dev version (bitbake master upstream)
Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'bitbake/lib/bb/build.py')
-rw-r--r-- | bitbake/lib/bb/build.py | 226 |
1 files changed, 118 insertions, 108 deletions
diff --git a/bitbake/lib/bb/build.py b/bitbake/lib/bb/build.py index 1d6742b6e6..6d80b4b549 100644 --- a/bitbake/lib/bb/build.py +++ b/bitbake/lib/bb/build.py @@ -25,8 +25,8 @@ # #Based on functions from the base bb module, Copyright 2003 Holger Schurig -from bb import data, fetch, event, mkdirhier, utils -import bb, os +from bb import data, event, mkdirhier, utils +import bb, os, sys # When we execute a python function we'd like certain things # in all namespaces, hence we add them to __builtins__ @@ -37,7 +37,11 @@ __builtins__['os'] = os # events class FuncFailed(Exception): - """Executed function failed""" + """ + Executed function failed + First parameter a message + Second paramter is a logfile (optional) + """ class EventException(Exception): """Exception which is associated with an Event.""" @@ -50,7 +54,9 @@ class TaskBase(event.Event): def __init__(self, t, d ): self._task = t - event.Event.__init__(self, d) + self._package = bb.data.getVar("PF", d, 1) + event.Event.__init__(self) + self._message = "package %s: task %s: %s" % (bb.data.getVar("PF", d, 1), t, bb.event.getName(self)[4:]) def getTask(self): return self._task @@ -68,6 +74,10 @@ class TaskSucceeded(TaskBase): class TaskFailed(TaskBase): """Task execution failed""" + def __init__(self, msg, logfile, t, d ): + self.logfile = logfile + self.msg = msg + TaskBase.__init__(self, t, d) class InvalidTask(TaskBase): """Invalid Task""" @@ -104,42 +114,116 @@ def exec_func(func, d, dirs = None): else: adir = data.getVar('B', d, 1) + # Save current directory try: prevdir = os.getcwd() except OSError: prevdir = data.getVar('TOPDIR', d, True) + + # Setup logfiles + t = data.getVar('T', d, 1) + if not t: + bb.msg.fatal(bb.msg.domain.Build, "T not set") + mkdirhier(t) + # Gross hack, FIXME + import random + logfile = "%s/log.%s.%s.%s" % (t, func, str(os.getpid()),random.random()) + runfile = "%s/run.%s.%s" % (t, func, str(os.getpid())) + + # Change to correct directory (if specified) if adir and os.access(adir, os.F_OK): os.chdir(adir) + # Handle logfiles + si = file('/dev/null', 'r') + try: + if bb.msg.debug_level['default'] > 0 or ispython: + so = os.popen("tee \"%s\"" % logfile, "w") + else: + so = file(logfile, 'w') + except OSError, e: + bb.msg.error(bb.msg.domain.Build, "opening log file: %s" % e) + pass + + se = so + + # 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 + os.dup2(si.fileno(), osi[1]) + os.dup2(so.fileno(), oso[1]) + os.dup2(se.fileno(), ose[1]) + locks = [] lockfiles = (data.expand(flags['lockfiles'], d) or "").split() for lock in lockfiles: locks.append(bb.utils.lockfile(lock)) - if flags['python']: - exec_func_python(func, d) - else: - exec_func_shell(func, d, flags) + try: + # Run the function + if ispython: + exec_func_python(func, d, runfile, logfile) + else: + exec_func_shell(func, d, runfile, logfile, flags) + + # Restore original directory + try: + os.chdir(prevdir) + except: + pass - for lock in locks: - bb.utils.unlockfile(lock) + finally: - if os.path.exists(prevdir): - os.chdir(prevdir) + # Unlock any lockfiles + for lock in locks: + bb.utils.unlockfile(lock) + + # Restore the backup fds + os.dup2(osi[0], osi[1]) + os.dup2(oso[0], oso[1]) + os.dup2(ose[0], ose[1]) + + # Close our logs + si.close() + so.close() + se.close() -def exec_func_python(func, d): + if os.path.exists(logfile) and os.path.getsize(logfile) == 0: + bb.msg.debug(2, bb.msg.domain.Build, "Zero size logfile %s, removing" % logfile) + os.remove(logfile) + + # Close the backup fds + os.close(osi[0]) + os.close(oso[0]) + os.close(ose[0]) + +def exec_func_python(func, d, runfile, logfile): """Execute a python BB 'function'""" - import re + import re, os bbfile = bb.data.getVar('FILE', d, 1) tmp = "def " + func + "():\n%s" % data.getVar(func, d) tmp += '\n' + func + '()' + + f = open(runfile, "w") + f.write(tmp) comp = utils.better_compile(tmp, func, bbfile) g = {} # globals g['d'] = d - utils.better_exec(comp, g, tmp, bbfile) + try: + utils.better_exec(comp, g, tmp, bbfile) + except: + (t,value,tb) = sys.exc_info() + + if t in [bb.parse.SkipPackage, bb.build.FuncFailed]: + raise + bb.msg.error(bb.msg.domain.Build, "Function %s failed" % func) + raise FuncFailed("function %s failed" % func, logfile) -def exec_func_shell(func, d, flags): +def exec_func_shell(func, d, runfile, logfile, flags): """Execute a shell BB 'function' Returns true if execution was successful. For this, it creates a bash shell script in the tmp dectory, writes the local @@ -149,23 +233,13 @@ def exec_func_shell(func, d, flags): of the directories you need created prior to execution. The last item in the list is where we will chdir/cd to. """ - import sys deps = flags['deps'] check = flags['check'] - interact = flags['interactive'] if check in globals(): if globals()[check](func, deps): return - global logfile - t = data.getVar('T', d, 1) - if not t: - return 0 - mkdirhier(t) - logfile = "%s/log.%s.%s" % (t, func, str(os.getpid())) - runfile = "%s/run.%s.%s" % (t, func, str(os.getpid())) - f = open(runfile, "w") f.write("#!/bin/sh -e\n") if bb.msg.debug_level['default'] > 0: f.write("set -x\n") @@ -177,91 +251,21 @@ def exec_func_shell(func, d, flags): os.chmod(runfile, 0775) if not func: bb.msg.error(bb.msg.domain.Build, "Function not specified") - raise FuncFailed() - - # open logs - si = file('/dev/null', 'r') - try: - if bb.msg.debug_level['default'] > 0: - so = os.popen("tee \"%s\"" % logfile, "w") - else: - so = file(logfile, 'w') - except OSError, e: - bb.msg.error(bb.msg.domain.Build, "opening log file: %s" % e) - pass - - se = so - - if not interact: - # 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 - os.dup2(si.fileno(), osi[1]) - os.dup2(so.fileno(), oso[1]) - os.dup2(se.fileno(), ose[1]) + raise FuncFailed("Function not specified for exec_func_shell") # execute function - prevdir = os.getcwd() if flags['fakeroot']: maybe_fakeroot = "PATH=\"%s\" fakeroot " % bb.data.getVar("PATH", d, 1) else: maybe_fakeroot = '' lang_environment = "LC_ALL=C " ret = os.system('%s%ssh -e %s' % (lang_environment, maybe_fakeroot, runfile)) - try: - os.chdir(prevdir) - except: - pass - - if not interact: - # restore the backups - os.dup2(osi[0], osi[1]) - os.dup2(oso[0], oso[1]) - os.dup2(ose[0], ose[1]) - # close our logs - si.close() - so.close() - se.close() - - if os.path.exists(logfile) and os.path.getsize(logfile) == 0: - bb.msg.debug(2, bb.msg.domain.Build, "Zero size logfile %s, removing" % logfile) - os.remove(logfile) - - # close the backup fds - os.close(osi[0]) - os.close(oso[0]) - os.close(ose[0]) - - if ret==0: - if bb.msg.debug_level['default'] > 0: - os.remove(runfile) -# os.remove(logfile) + if ret == 0: return - else: - bb.msg.error(bb.msg.domain.Build, "function %s failed" % func) - if data.getVar("BBINCLUDELOGS", d): - bb.msg.error(bb.msg.domain.Build, "log data follows (%s)" % logfile) - number_of_lines = data.getVar("BBINCLUDELOGS_LINES", d) - if number_of_lines: - os.system('tail -n%s %s' % (number_of_lines, logfile)) - elif os.path.exists(logfile): - f = open(logfile, "r") - while True: - l = f.readline() - if l == '': - break - l = l.rstrip() - print '| %s' % l - f.close() - else: - bb.msg.error(bb.msg.domain.Build, "There was no logfile output") - else: - bb.msg.error(bb.msg.domain.Build, "see log in %s" % logfile) - raise FuncFailed( logfile ) + + bb.msg.error(bb.msg.domain.Build, "Function %s failed" % func) + raise FuncFailed("function %s failed" % func, logfile) def exec_task(task, d): @@ -282,14 +286,20 @@ def exec_task(task, d): data.setVar('OVERRIDES', 'task-%s:%s' % (task[3:], old_overrides), localdata) data.update_data(localdata) data.expandKeys(localdata) - event.fire(TaskStarted(task, localdata)) + event.fire(TaskStarted(task, localdata), localdata) exec_func(task, localdata) - event.fire(TaskSucceeded(task, localdata)) - except FuncFailed, reason: - bb.msg.note(1, bb.msg.domain.Build, "Task failed: %s" % reason ) - failedevent = TaskFailed(task, d) - event.fire(failedevent) - raise EventException("Function failed in task: %s" % reason, failedevent) + event.fire(TaskSucceeded(task, localdata), localdata) + except FuncFailed, message: + # Try to extract the optional logfile + try: + (msg, logfile) = message + except: + logfile = None + msg = message + bb.msg.note(1, bb.msg.domain.Build, "Task failed: %s" % message ) + failedevent = TaskFailed(msg, logfile, task, d) + event.fire(failedevent, d) + raise EventException("Function failed in task: %s" % message, failedevent) # make stamp, or cause event and raise exception if not data.getVarFlag(task, 'nostamp', d) and not data.getVarFlag(task, 'selfstamp', d): |