|
@@ -5,43 +5,62 @@
|
|
|
import sys
|
|
|
import os
|
|
|
import subprocess
|
|
|
+import signal
|
|
|
|
|
|
-def exec_watch(cmd, **options):
|
|
|
- """Run program with stdout shown on sys.stdout"""
|
|
|
- if isinstance(cmd, str) and not "shell" in options:
|
|
|
- options["shell"] = True
|
|
|
+def reenable_sigint():
|
|
|
+ signal.signal(signal.SIGINT, signal.SIG_DFL)
|
|
|
|
|
|
- process = subprocess.Popen(
|
|
|
- cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **options
|
|
|
- )
|
|
|
-
|
|
|
- buf = ''
|
|
|
- while True:
|
|
|
- out = process.stdout.read(1)
|
|
|
- if out:
|
|
|
- sys.stdout.write(out)
|
|
|
- sys.stdout.flush()
|
|
|
- buf += out
|
|
|
- elif out == '' and process.poll() != None:
|
|
|
- break
|
|
|
+def run_command_interruptible(cmd):
|
|
|
+ """
|
|
|
+ Run a command with output displayed on the console, but ensure any Ctrl+C is
|
|
|
+ processed only by the child process.
|
|
|
+ """
|
|
|
+ signal.signal(signal.SIGINT, signal.SIG_IGN)
|
|
|
+ try:
|
|
|
+ ret = subprocess.call(cmd, shell=True, preexec_fn=reenable_sigint)
|
|
|
+ finally:
|
|
|
+ signal.signal(signal.SIGINT, signal.SIG_DFL)
|
|
|
+ return ret
|
|
|
|
|
|
- return process.returncode, buf
|
|
|
+def get_last_consolelog():
|
|
|
+ '''Return the most recent console log file'''
|
|
|
+ logdir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'tmp', 'log', 'cooker')
|
|
|
+ if os.path.exists(logdir):
|
|
|
+ mcdir = os.listdir(logdir)
|
|
|
+ if mcdir:
|
|
|
+ logdir = os.path.join(logdir, mcdir[0])
|
|
|
+ logfiles = [os.path.join(logdir, fn) for fn in os.listdir(logdir)]
|
|
|
+ logfiles.sort(key=os.path.getmtime)
|
|
|
+ if logfiles:
|
|
|
+ return os.path.join(logdir, logfiles[-1])
|
|
|
+ return None
|
|
|
|
|
|
def main():
|
|
|
if len(sys.argv) < 2:
|
|
|
+ print('Please specify output log file')
|
|
|
+ return 1
|
|
|
+ logfile = sys.argv[1]
|
|
|
+ if len(sys.argv) < 3:
|
|
|
sdk_targets = []
|
|
|
else:
|
|
|
- sdk_targets = ' '.join(sys.argv[1:]).split()
|
|
|
+ sdk_targets = ' '.join(sys.argv[2:]).split()
|
|
|
if not sdk_targets:
|
|
|
# Just do a parse so the cache is primed
|
|
|
- ret, _ = exec_watch('bitbake -p')
|
|
|
+ ret = run_command_interruptible('bitbake -p --quiet')
|
|
|
return ret
|
|
|
|
|
|
- print('Preparing SDK for %s...' % ', '.join(sdk_targets))
|
|
|
+ with open(logfile, 'a') as logf:
|
|
|
+ logf.write('Preparing SDK for %s...\n' % ', '.join(sdk_targets))
|
|
|
|
|
|
- ret, out = exec_watch('BB_SETSCENE_ENFORCE=1 bitbake %s' % ' '.join(sdk_targets))
|
|
|
- if ret:
|
|
|
- return ret
|
|
|
+ ret = run_command_interruptible('BB_SETSCENE_ENFORCE=1 bitbake --quiet %s' % ' '.join(sdk_targets))
|
|
|
+ lastlog = get_last_consolelog()
|
|
|
+ if lastlog:
|
|
|
+ with open(lastlog, 'r') as f:
|
|
|
+ for line in f:
|
|
|
+ logf.write(line)
|
|
|
+ if ret:
|
|
|
+ print('ERROR: SDK preparation failed: see %s' % logfile)
|
|
|
+ return ret
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
try:
|