summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggleton <paul.eggleton@linux.intel.com>2016-07-18 22:17:03 +1200
committerRichard Purdie <richard.purdie@linuxfoundation.org>2016-07-26 08:56:27 +0100
commit24f871c801bbd9799cae20d742a5d2d5ae9ab951 (patch)
tree511610e70cda3d43da8642b17f4260100ce22ea6
parent1052fef94eff6280e0807de8990932723a236cfe (diff)
downloadpoky-24f871c801bbd9799cae20d742a5d2d5ae9ab951.tar.gz
classes/populate_sdk_ext: show progress when preparing build system
During the extensible SDK installation process the final step is to prepare the internal copy of the build system. This can take some time, especially if you have SDK_EXT_TYPE set to "minimal" (downloading sstate artifacts) and SDK_INCLUDE_PKGDATA set to "1" (restoring pkgdata for world). To make this a bit less painful, use BitBake's new quiet mode to display status during this operation so you have some idea of how it's progressing; instead of redirecting the output to preparing_build_system.log we grab the last console log and append it instead. One result of this change is that you get the errors printed on the console during normal output rather than this going to the preparing_build_system.log file first. In OE-Core revision 227d2cbf9e0b8c35fa6644e3d72e0699db9607fa, we changed to always print the contents of preparing_build_system.log on failure, but now at least the error contents of that log is duplicated. Besides, I intentionally didn't print out the contents of that log during normal usage because it's quite verbose - the bug that we were attempting to fix was about not getting this information when seeing failures in the automated tests, thus I've moved printing the log to the test handling code instead. Part of the implementation for [YOCTO #9613]. (From OE-Core rev: 0f7cb880c934b7871f3b8432f4f02603300f6129) Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com> Signed-off-by: Ross Burton <ross.burton@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/classes/populate_sdk_ext.bbclass2
-rw-r--r--meta/files/ext-sdk-prepare.py67
2 files changed, 44 insertions, 25 deletions
diff --git a/meta/classes/populate_sdk_ext.bbclass b/meta/classes/populate_sdk_ext.bbclass
index 245adc1559..62f2c3e48a 100644
--- a/meta/classes/populate_sdk_ext.bbclass
+++ b/meta/classes/populate_sdk_ext.bbclass
@@ -428,7 +428,7 @@ sdk_ext_postinst() {
428 # current working directory when first ran, nor will it set $1 when 428 # current working directory when first ran, nor will it set $1 when
429 # sourcing a script. That is why this has to look so ugly. 429 # sourcing a script. That is why this has to look so ugly.
430 LOGFILE="$target_sdk_dir/preparing_build_system.log" 430 LOGFILE="$target_sdk_dir/preparing_build_system.log"
431 sh -c ". buildtools/environment-setup* > $LOGFILE && cd $target_sdk_dir/`dirname ${oe_init_build_env_path}` && set $target_sdk_dir && . $target_sdk_dir/${oe_init_build_env_path} $target_sdk_dir >> $LOGFILE && python $target_sdk_dir/ext-sdk-prepare.py '${SDK_INSTALL_TARGETS}' >> $LOGFILE 2>&1" || { echo "ERROR: SDK preparation failed: see $LOGFILE for a slightly more detailed log"; echo "printf 'ERROR: this SDK was not fully installed and needs reinstalling\n'" >> $env_setup_script ; exit 1 ; } 431 sh -c ". buildtools/environment-setup* > $LOGFILE && cd $target_sdk_dir/`dirname ${oe_init_build_env_path}` && set $target_sdk_dir && . $target_sdk_dir/${oe_init_build_env_path} $target_sdk_dir >> $LOGFILE && python $target_sdk_dir/ext-sdk-prepare.py $LOGFILE '${SDK_INSTALL_TARGETS}'" || { echo "ERROR: SDK preparation failed: see $LOGFILE for a slightly more detailed log"; echo "printf 'ERROR: this SDK was not fully installed and needs reinstalling\n'" >> $env_setup_script ; exit 1 ; }
432 rm $target_sdk_dir/ext-sdk-prepare.py 432 rm $target_sdk_dir/ext-sdk-prepare.py
433 fi 433 fi
434 echo done 434 echo done
diff --git a/meta/files/ext-sdk-prepare.py b/meta/files/ext-sdk-prepare.py
index 3b33c0f9e9..8b15982843 100644
--- a/meta/files/ext-sdk-prepare.py
+++ b/meta/files/ext-sdk-prepare.py
@@ -5,43 +5,62 @@
5import sys 5import sys
6import os 6import os
7import subprocess 7import subprocess
8import signal
8 9
9def exec_watch(cmd, **options): 10def reenable_sigint():
10 """Run program with stdout shown on sys.stdout""" 11 signal.signal(signal.SIGINT, signal.SIG_DFL)
11 if isinstance(cmd, str) and not "shell" in options:
12 options["shell"] = True
13 12
14 process = subprocess.Popen( 13def run_command_interruptible(cmd):
15 cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **options 14 """
16 ) 15 Run a command with output displayed on the console, but ensure any Ctrl+C is
17 16 processed only by the child process.
18 buf = '' 17 """
19 while True: 18 signal.signal(signal.SIGINT, signal.SIG_IGN)
20 out = process.stdout.read(1) 19 try:
21 if out: 20 ret = subprocess.call(cmd, shell=True, preexec_fn=reenable_sigint)
22 sys.stdout.write(out) 21 finally:
23 sys.stdout.flush() 22 signal.signal(signal.SIGINT, signal.SIG_DFL)
24 buf += out 23 return ret
25 elif out == '' and process.poll() != None:
26 break
27 24
28 return process.returncode, buf 25def get_last_consolelog():
26 '''Return the most recent console log file'''
27 logdir = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'tmp', 'log', 'cooker')
28 if os.path.exists(logdir):
29 mcdir = os.listdir(logdir)
30 if mcdir:
31 logdir = os.path.join(logdir, mcdir[0])
32 logfiles = [os.path.join(logdir, fn) for fn in os.listdir(logdir)]
33 logfiles.sort(key=os.path.getmtime)
34 if logfiles:
35 return os.path.join(logdir, logfiles[-1])
36 return None
29 37
30def main(): 38def main():
31 if len(sys.argv) < 2: 39 if len(sys.argv) < 2:
40 print('Please specify output log file')
41 return 1
42 logfile = sys.argv[1]
43 if len(sys.argv) < 3:
32 sdk_targets = [] 44 sdk_targets = []
33 else: 45 else:
34 sdk_targets = ' '.join(sys.argv[1:]).split() 46 sdk_targets = ' '.join(sys.argv[2:]).split()
35 if not sdk_targets: 47 if not sdk_targets:
36 # Just do a parse so the cache is primed 48 # Just do a parse so the cache is primed
37 ret, _ = exec_watch('bitbake -p') 49 ret = run_command_interruptible('bitbake -p --quiet')
38 return ret 50 return ret
39 51
40 print('Preparing SDK for %s...' % ', '.join(sdk_targets)) 52 with open(logfile, 'a') as logf:
53 logf.write('Preparing SDK for %s...\n' % ', '.join(sdk_targets))
41 54
42 ret, out = exec_watch('BB_SETSCENE_ENFORCE=1 bitbake %s' % ' '.join(sdk_targets)) 55 ret = run_command_interruptible('BB_SETSCENE_ENFORCE=1 bitbake --quiet %s' % ' '.join(sdk_targets))
43 if ret: 56 lastlog = get_last_consolelog()
44 return ret 57 if lastlog:
58 with open(lastlog, 'r') as f:
59 for line in f:
60 logf.write(line)
61 if ret:
62 print('ERROR: SDK preparation failed: see %s' % logfile)
63 return ret
45 64
46if __name__ == "__main__": 65if __name__ == "__main__":
47 try: 66 try: