summaryrefslogtreecommitdiffstats
path: root/bitbake
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake')
-rwxr-xr-xbitbake/lib/bb/ui/crumbs/builder.py52
-rw-r--r--bitbake/lib/bb/ui/crumbs/hobeventhandler.py3
-rwxr-xr-xbitbake/lib/bb/ui/crumbs/imagedetailspage.py24
-rwxr-xr-xbitbake/lib/bb/ui/crumbs/packageselectionpage.py27
-rw-r--r--bitbake/lib/bb/ui/crumbs/runningbuild.py41
5 files changed, 129 insertions, 18 deletions
diff --git a/bitbake/lib/bb/ui/crumbs/builder.py b/bitbake/lib/bb/ui/crumbs/builder.py
index c2e7068428..cb2338e777 100755
--- a/bitbake/lib/bb/ui/crumbs/builder.py
+++ b/bitbake/lib/bb/ui/crumbs/builder.py
@@ -27,6 +27,7 @@ import os
27import subprocess 27import subprocess
28import shlex 28import shlex
29import re 29import re
30import logging
30from bb.ui.crumbs.template import TemplateMgr 31from bb.ui.crumbs.template import TemplateMgr
31from bb.ui.crumbs.imageconfigurationpage import ImageConfigurationPage 32from bb.ui.crumbs.imageconfigurationpage import ImageConfigurationPage
32from bb.ui.crumbs.recipeselectionpage import RecipeSelectionPage 33from bb.ui.crumbs.recipeselectionpage import RecipeSelectionPage
@@ -395,6 +396,11 @@ class Builder(gtk.Window):
395 396
396 self.template = None 397 self.template = None
397 398
399 # logger
400 self.logger = logging.getLogger("BitBake")
401 self.consolelog = None
402 self.current_logfile = None
403
398 # configuration and parameters 404 # configuration and parameters
399 self.configuration = Configuration() 405 self.configuration = Configuration()
400 self.parameters = Parameters() 406 self.parameters = Parameters()
@@ -433,6 +439,7 @@ class Builder(gtk.Window):
433 self.handler.build.connect("build-aborted", self.handler_build_aborted_cb) 439 self.handler.build.connect("build-aborted", self.handler_build_aborted_cb)
434 self.handler.build.connect("task-started", self.handler_task_started_cb) 440 self.handler.build.connect("task-started", self.handler_task_started_cb)
435 self.handler.build.connect("log-error", self.handler_build_failure_cb) 441 self.handler.build.connect("log-error", self.handler_build_failure_cb)
442 self.handler.build.connect("log", self.handler_build_log_cb)
436 self.handler.build.connect("no-provider", self.handler_no_provider_cb) 443 self.handler.build.connect("no-provider", self.handler_no_provider_cb)
437 self.handler.connect("generating-data", self.handler_generating_data_cb) 444 self.handler.connect("generating-data", self.handler_generating_data_cb)
438 self.handler.connect("data-generated", self.handler_data_generated_cb) 445 self.handler.connect("data-generated", self.handler_data_generated_cb)
@@ -501,25 +508,34 @@ class Builder(gtk.Window):
501 self.set_user_config() 508 self.set_user_config()
502 self.handler.generate_recipes() 509 self.handler.generate_recipes()
503 510
504 def generate_packages_async(self): 511 def generate_packages_async(self, log = False):
505 self.switch_page(self.PACKAGE_GENERATING) 512 self.switch_page(self.PACKAGE_GENERATING)
513 if log:
514 self.current_logfile = self.handler.get_logfile()
515 self.do_log(self.current_logfile)
506 # Build packages 516 # Build packages
507 _, all_recipes = self.recipe_model.get_selected_recipes() 517 _, all_recipes = self.recipe_model.get_selected_recipes()
508 self.set_user_config() 518 self.set_user_config()
509 self.handler.reset_build() 519 self.handler.reset_build()
510 self.handler.generate_packages(all_recipes, self.configuration.default_task) 520 self.handler.generate_packages(all_recipes, self.configuration.default_task)
511 521
512 def fast_generate_image_async(self): 522 def fast_generate_image_async(self, log = False):
513 self.switch_page(self.FAST_IMAGE_GENERATING) 523 self.switch_page(self.FAST_IMAGE_GENERATING)
524 if log:
525 self.current_logfile = self.handler.get_logfile()
526 self.do_log(self.current_logfile)
514 # Build packages 527 # Build packages
515 _, all_recipes = self.recipe_model.get_selected_recipes() 528 _, all_recipes = self.recipe_model.get_selected_recipes()
516 self.set_user_config() 529 self.set_user_config()
517 self.handler.reset_build() 530 self.handler.reset_build()
518 self.handler.generate_packages(all_recipes, self.configuration.default_task) 531 self.handler.generate_packages(all_recipes, self.configuration.default_task)
519 532
520 def generate_image_async(self): 533 def generate_image_async(self, cont = False):
521 self.switch_page(self.IMAGE_GENERATING) 534 self.switch_page(self.IMAGE_GENERATING)
522 self.handler.reset_build() 535 self.handler.reset_build()
536 if not cont:
537 self.current_logfile = self.handler.get_logfile()
538 self.do_log(self.current_logfile)
523 # Build image 539 # Build image
524 self.set_user_config() 540 self.set_user_config()
525 toolchain_packages = [] 541 toolchain_packages = []
@@ -627,14 +643,14 @@ class Builder(gtk.Window):
627 pass 643 pass
628 644
629 elif next_step == self.PACKAGE_SELECTION: 645 elif next_step == self.PACKAGE_SELECTION:
630 pass 646 self.package_details_page.show_page(self.current_logfile)
631 647
632 elif next_step == self.PACKAGE_GENERATING or next_step == self.FAST_IMAGE_GENERATING: 648 elif next_step == self.PACKAGE_GENERATING or next_step == self.FAST_IMAGE_GENERATING:
633 # both PACKAGE_GENEATING and FAST_IMAGE_GENERATING share the same page 649 # both PACKAGE_GENEATING and FAST_IMAGE_GENERATING share the same page
634 self.build_details_page.show_page(next_step) 650 self.build_details_page.show_page(next_step)
635 651
636 elif next_step == self.PACKAGE_GENERATED: 652 elif next_step == self.PACKAGE_GENERATED:
637 pass 653 self.package_details_page.show_page(self.current_logfile)
638 654
639 elif next_step == self.IMAGE_GENERATING: 655 elif next_step == self.IMAGE_GENERATING:
640 # after packages are generated, selected_packages need to 656 # after packages are generated, selected_packages need to
@@ -736,7 +752,7 @@ class Builder(gtk.Window):
736 752
737 self.rcppkglist_populated() 753 self.rcppkglist_populated()
738 if self.current_step == self.FAST_IMAGE_GENERATING: 754 if self.current_step == self.FAST_IMAGE_GENERATING:
739 self.generate_image_async() 755 self.generate_image_async(True)
740 756
741 def show_error_dialog(self, msg): 757 def show_error_dialog(self, msg):
742 lbl = "<b>Error</b>\n" 758 lbl = "<b>Error</b>\n"
@@ -963,6 +979,10 @@ class Builder(gtk.Window):
963 def handler_build_failure_cb(self, running_build): 979 def handler_build_failure_cb(self, running_build):
964 self.build_details_page.show_issues() 980 self.build_details_page.show_issues()
965 981
982 def handler_build_log_cb(self, running_build, func, obj):
983 if hasattr(self.logger, func):
984 getattr(self.logger, func)(obj)
985
966 def destroy_window_cb(self, widget, event): 986 def destroy_window_cb(self, widget, event):
967 if not self.sensitive: 987 if not self.sensitive:
968 return True 988 return True
@@ -992,7 +1012,7 @@ class Builder(gtk.Window):
992 dialog.run() 1012 dialog.run()
993 dialog.destroy() 1013 dialog.destroy()
994 return 1014 return
995 self.generate_packages_async() 1015 self.generate_packages_async(True)
996 1016
997 def build_image(self): 1017 def build_image(self):
998 selected_packages = self.package_model.get_selected_packages() 1018 selected_packages = self.package_model.get_selected_packages()
@@ -1005,7 +1025,7 @@ class Builder(gtk.Window):
1005 dialog.run() 1025 dialog.run()
1006 dialog.destroy() 1026 dialog.destroy()
1007 return 1027 return
1008 self.generate_image_async() 1028 self.generate_image_async(True)
1009 1029
1010 def just_bake(self): 1030 def just_bake(self):
1011 selected_image = self.recipe_model.get_selected_image() 1031 selected_image = self.recipe_model.get_selected_image()
@@ -1022,7 +1042,7 @@ class Builder(gtk.Window):
1022 dialog.destroy() 1042 dialog.destroy()
1023 return 1043 return
1024 1044
1025 self.fast_generate_image_async() 1045 self.fast_generate_image_async(True)
1026 1046
1027 def show_binb_dialog(self, binb): 1047 def show_binb_dialog(self, binb):
1028 markup = "<b>Brought in by:</b>\n%s" % binb 1048 markup = "<b>Brought in by:</b>\n%s" % binb
@@ -1241,7 +1261,7 @@ class Builder(gtk.Window):
1241 response = dialog.run() 1261 response = dialog.run()
1242 dialog.destroy() 1262 dialog.destroy()
1243 if response == gtk.RESPONSE_YES: 1263 if response == gtk.RESPONSE_YES:
1244 self.generate_packages_async() 1264 self.generate_packages_async(True)
1245 else: 1265 else:
1246 self.switch_page(self.PACKAGE_SELECTION) 1266 self.switch_page(self.PACKAGE_SELECTION)
1247 else: 1267 else:
@@ -1289,3 +1309,15 @@ class Builder(gtk.Window):
1289 self.cancel_build_sync() 1309 self.cancel_build_sync()
1290 elif response == gtk.RESPONSE_YES: 1310 elif response == gtk.RESPONSE_YES:
1291 self.cancel_build_sync(True) 1311 self.cancel_build_sync(True)
1312
1313 def do_log(self, consolelogfile = None):
1314 if consolelogfile:
1315 if self.consolelog:
1316 self.logger.removeHandler(self.consolelog)
1317 self.consolelog = None
1318 self.consolelog = logging.FileHandler(consolelogfile)
1319 bb.msg.addDefaultlogFilter(self.consolelog)
1320 format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s")
1321 self.consolelog.setFormatter(format)
1322
1323 self.logger.addHandler(self.consolelog) \ No newline at end of file
diff --git a/bitbake/lib/bb/ui/crumbs/hobeventhandler.py b/bitbake/lib/bb/ui/crumbs/hobeventhandler.py
index a00fcd8eda..540dde0951 100644
--- a/bitbake/lib/bb/ui/crumbs/hobeventhandler.py
+++ b/bitbake/lib/bb/ui/crumbs/hobeventhandler.py
@@ -390,6 +390,9 @@ class HobHandler(gobject.GObject):
390 def reset_build(self): 390 def reset_build(self):
391 self.build.reset() 391 self.build.reset()
392 392
393 def get_logfile(self):
394 return self.server.runCommand(["getVariable", "BB_CONSOLELOG"])
395
393 def _remove_redundant(self, string): 396 def _remove_redundant(self, string):
394 ret = [] 397 ret = []
395 for i in string.split(): 398 for i in string.split():
diff --git a/bitbake/lib/bb/ui/crumbs/imagedetailspage.py b/bitbake/lib/bb/ui/crumbs/imagedetailspage.py
index 596fb851ec..40eb7a4540 100755
--- a/bitbake/lib/bb/ui/crumbs/imagedetailspage.py
+++ b/bitbake/lib/bb/ui/crumbs/imagedetailspage.py
@@ -33,7 +33,7 @@ from bb.ui.crumbs.hig import CrumbsDialog
33class ImageDetailsPage (HobPage): 33class ImageDetailsPage (HobPage):
34 34
35 class DetailBox (gtk.EventBox): 35 class DetailBox (gtk.EventBox):
36 def __init__(self, widget = None, varlist = None, vallist = None, icon = None, button = None, color = HobColors.LIGHT_GRAY): 36 def __init__(self, widget = None, varlist = None, vallist = None, icon = None, button = None, button2=None, color = HobColors.LIGHT_GRAY):
37 gtk.EventBox.__init__(self) 37 gtk.EventBox.__init__(self)
38 38
39 # set color 39 # set color
@@ -72,7 +72,11 @@ class ImageDetailsPage (HobPage):
72 self.table.attach(self.line_widgets[varlist[index]], colid, 20, row, row + 1) 72 self.table.attach(self.line_widgets[varlist[index]], colid, 20, row, row + 1)
73 # pack the button on the right 73 # pack the button on the right
74 if button: 74 if button:
75 self.hbox.pack_end(button, expand=False, fill=False) 75 self.bbox = gtk.VBox()
76 self.bbox.pack_start(button, expand=True, fill=True)
77 if button2:
78 self.bbox.pack_start(button2, expand=True, fill=True)
79 self.hbox.pack_end(self.bbox, expand=False, fill=False)
76 80
77 def update_line_widgets(self, variable, value): 81 def update_line_widgets(self, variable, value):
78 if len(self.line_widgets) == 0: 82 if len(self.line_widgets) == 0:
@@ -164,8 +168,10 @@ class ImageDetailsPage (HobPage):
164 base_image = self.builder.recipe_model.get_selected_image() 168 base_image = self.builder.recipe_model.get_selected_image()
165 layers = self.builder.configuration.layers 169 layers = self.builder.configuration.layers
166 pkg_num = "%s" % len(self.builder.package_model.get_selected_packages()) 170 pkg_num = "%s" % len(self.builder.package_model.get_selected_packages())
171 log_file = self.builder.current_logfile
167 else: 172 else:
168 pkg_num = "N/A" 173 pkg_num = "N/A"
174 log_file = None
169 175
170 # remove 176 # remove
171 for button_id, button in self.button_ids.items(): 177 for button_id, button in self.button_ids.items():
@@ -243,11 +249,17 @@ class ImageDetailsPage (HobPage):
243 view_files_button = HobAltButton("View files") 249 view_files_button = HobAltButton("View files")
244 view_files_button.connect("clicked", self.view_files_clicked_cb, image_addr) 250 view_files_button.connect("clicked", self.view_files_clicked_cb, image_addr)
245 view_files_button.set_tooltip_text("Open the directory containing the image files") 251 view_files_button.set_tooltip_text("Open the directory containing the image files")
246 self.image_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=view_files_button) 252 view_log_button = None
253 if log_file:
254 view_log_button = HobAltButton("View log")
255 view_log_button.connect("clicked", self.view_log_clicked_cb, log_file)
256 view_log_button.set_tooltip_text("Open the building log files")
257 self.image_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=view_files_button, button2=view_log_button)
247 self.box_group_area.pack_start(self.image_detail, expand=False, fill=True) 258 self.box_group_area.pack_start(self.image_detail, expand=False, fill=True)
248 259
249 # The default kernel box for the qemu images 260 # The default kernel box for the qemu images
250 self.sel_kernel = "" 261 self.sel_kernel = ""
262 self.kernel_detail = None
251 if 'qemu' in image_name: 263 if 'qemu' in image_name:
252 self.sel_kernel = self.get_kernel_file_name() 264 self.sel_kernel = self.get_kernel_file_name()
253 265
@@ -315,12 +327,16 @@ class ImageDetailsPage (HobPage):
315 self.box_group_area.pack_start(self.details_bottom_buttons, expand=False, fill=False) 327 self.box_group_area.pack_start(self.details_bottom_buttons, expand=False, fill=False)
316 328
317 self.show_all() 329 self.show_all()
318 if not is_runnable: 330 if self.kernel_detail and (not is_runnable):
319 self.kernel_detail.hide() 331 self.kernel_detail.hide()
320 332
321 def view_files_clicked_cb(self, button, image_addr): 333 def view_files_clicked_cb(self, button, image_addr):
322 subprocess.call("xdg-open /%s" % image_addr, shell=True) 334 subprocess.call("xdg-open /%s" % image_addr, shell=True)
323 335
336 def view_log_clicked_cb(self, button, log_file):
337 if log_file:
338 os.system("xdg-open /%s" % log_file)
339
324 def refresh_package_detail_box(self, image_size): 340 def refresh_package_detail_box(self, image_size):
325 self.package_detail.update_line_widgets("Total image size: ", image_size) 341 self.package_detail.update_line_widgets("Total image size: ", image_size)
326 342
diff --git a/bitbake/lib/bb/ui/crumbs/packageselectionpage.py b/bitbake/lib/bb/ui/crumbs/packageselectionpage.py
index 1b832eb633..d1015352f1 100755
--- a/bitbake/lib/bb/ui/crumbs/packageselectionpage.py
+++ b/bitbake/lib/bb/ui/crumbs/packageselectionpage.py
@@ -143,8 +143,8 @@ class PackageSelectionPage (HobPage):
143 # add all into the dialog 143 # add all into the dialog
144 self.box_group_area.pack_start(self.ins, expand=True, fill=True) 144 self.box_group_area.pack_start(self.ins, expand=True, fill=True)
145 145
146 button_box = gtk.HBox(False, 6) 146 self.button_box = gtk.HBox(False, 6)
147 self.box_group_area.pack_start(button_box, expand=False, fill=False) 147 self.box_group_area.pack_start(self.button_box, expand=False, fill=False)
148 148
149 self.build_image_button = HobButton('Build image') 149 self.build_image_button = HobButton('Build image')
150 self.build_image_button.set_size_request(205, 49) 150 self.build_image_button.set_size_request(205, 49)
@@ -152,11 +152,11 @@ class PackageSelectionPage (HobPage):
152 self.build_image_button.set_flags(gtk.CAN_DEFAULT) 152 self.build_image_button.set_flags(gtk.CAN_DEFAULT)
153 self.build_image_button.grab_default() 153 self.build_image_button.grab_default()
154 self.build_image_button.connect("clicked", self.build_image_clicked_cb) 154 self.build_image_button.connect("clicked", self.build_image_clicked_cb)
155 button_box.pack_end(self.build_image_button, expand=False, fill=False) 155 self.button_box.pack_end(self.build_image_button, expand=False, fill=False)
156 156
157 self.back_button = HobAltButton("<< Back to image configuration") 157 self.back_button = HobAltButton("<< Back to image configuration")
158 self.back_button.connect("clicked", self.back_button_clicked_cb) 158 self.back_button.connect("clicked", self.back_button_clicked_cb)
159 button_box.pack_start(self.back_button, expand=False, fill=False) 159 self.button_box.pack_start(self.back_button, expand=False, fill=False)
160 160
161 def button_click_cb(self, widget, event): 161 def button_click_cb(self, widget, event):
162 path, col = widget.table_tree.get_cursor() 162 path, col = widget.table_tree.get_cursor()
@@ -166,6 +166,25 @@ class PackageSelectionPage (HobPage):
166 if binb: 166 if binb:
167 self.builder.show_binb_dialog(binb) 167 self.builder.show_binb_dialog(binb)
168 168
169 def view_log_clicked_cb(self, button, log_file):
170 if log_file:
171 os.system("xdg-open /%s" % log_file)
172
173 def show_page(self, log_file):
174 children = self.button_box.get_children() or []
175 for child in children:
176 self.button_box.remove(child)
177 # re-packed the buttons as request, add the 'view log' button if build success
178 self.button_box.pack_start(self.back_button, expand=False, fill=False)
179 self.button_box.pack_end(self.build_image_button, expand=False, fill=False)
180 if log_file:
181 view_log_button = HobAltButton("View log")
182 view_log_button.connect("clicked", self.view_log_clicked_cb, log_file)
183 view_log_button.set_tooltip_text("Open the building log files")
184 self.button_box.pack_end(view_log_button, expand=False, fill=False)
185
186 self.show_all()
187
169 def build_image_clicked_cb(self, button): 188 def build_image_clicked_cb(self, button):
170 self.builder.build_image() 189 self.builder.build_image()
171 190
diff --git a/bitbake/lib/bb/ui/crumbs/runningbuild.py b/bitbake/lib/bb/ui/crumbs/runningbuild.py
index 0347058d7e..a57d6db5e5 100644
--- a/bitbake/lib/bb/ui/crumbs/runningbuild.py
+++ b/bitbake/lib/bb/ui/crumbs/runningbuild.py
@@ -88,6 +88,9 @@ class RunningBuild (gobject.GObject):
88 'no-provider' : (gobject.SIGNAL_RUN_LAST, 88 'no-provider' : (gobject.SIGNAL_RUN_LAST,
89 gobject.TYPE_NONE, 89 gobject.TYPE_NONE,
90 (gobject.TYPE_PYOBJECT,)), 90 (gobject.TYPE_PYOBJECT,)),
91 'log' : (gobject.SIGNAL_RUN_LAST,
92 gobject.TYPE_NONE,
93 (gobject.TYPE_STRING, gobject.TYPE_PYOBJECT,)),
91 } 94 }
92 pids_to_task = {} 95 pids_to_task = {}
93 tasks_to_iter = {} 96 tasks_to_iter = {}
@@ -126,6 +129,8 @@ class RunningBuild (gobject.GObject):
126 parent = self.tasks_to_iter[(package, task)] 129 parent = self.tasks_to_iter[(package, task)]
127 130
128 if(isinstance(event, logging.LogRecord)): 131 if(isinstance(event, logging.LogRecord)):
132 if event.taskpid == 0 or event.levelno > logging.INFO:
133 self.emit("log", "handle", event)
129 # FIXME: this is a hack! More info in Yocto #1433 134 # FIXME: this is a hack! More info in Yocto #1433
130 # http://bugzilla.pokylinux.org/show_bug.cgi?id=1433, temporarily 135 # http://bugzilla.pokylinux.org/show_bug.cgi?id=1433, temporarily
131 # mask the error message as it's not informative for the user. 136 # mask the error message as it's not informative for the user.
@@ -211,6 +216,7 @@ class RunningBuild (gobject.GObject):
211 self.tasks_to_iter[(package, task)] = i 216 self.tasks_to_iter[(package, task)] = i
212 217
213 elif isinstance(event, bb.build.TaskBase): 218 elif isinstance(event, bb.build.TaskBase):
219 self.emit("log", "info", event._message)
214 current = self.tasks_to_iter[(package, task)] 220 current = self.tasks_to_iter[(package, task)]
215 parent = self.tasks_to_iter[(package, None)] 221 parent = self.tasks_to_iter[(package, None)]
216 222
@@ -296,6 +302,7 @@ class RunningBuild (gobject.GObject):
296 self.buildaborted = True 302 self.buildaborted = True
297 303
298 elif isinstance(event, bb.command.CommandFailed): 304 elif isinstance(event, bb.command.CommandFailed):
305 self.emit("log", "error", "Command execution failed: %s" % (event.error))
299 if event.error.startswith("Exited with"): 306 if event.error.startswith("Exited with"):
300 # If the command fails with an exit code we're done, emit the 307 # If the command fails with an exit code we're done, emit the
301 # generic signal for the UI to notify the user 308 # generic signal for the UI to notify the user
@@ -323,7 +330,24 @@ class RunningBuild (gobject.GObject):
323 elif isinstance(event, bb.event.ParseCompleted) and pbar: 330 elif isinstance(event, bb.event.ParseCompleted) and pbar:
324 pbar.hide() 331 pbar.hide()
325 #using runqueue events as many as possible to update the progress bar 332 #using runqueue events as many as possible to update the progress bar
333 elif isinstance(event, bb.runqueue.runQueueTaskFailed):
334 self.emit("log", "error", "Task %s (%s) failed with exit code '%s'" % (event.taskid, event.taskstring, event.exitcode))
335 elif isinstance(event, bb.runqueue.sceneQueueTaskFailed):
336 self.emit("log", "warn", "Setscene task %s (%s) failed with exit code '%s' - real task will be run instead" \
337 % (event.taskid, event.taskstring, event.exitcode))
326 elif isinstance(event, (bb.runqueue.runQueueTaskStarted, bb.runqueue.sceneQueueTaskStarted)): 338 elif isinstance(event, (bb.runqueue.runQueueTaskStarted, bb.runqueue.sceneQueueTaskStarted)):
339 if isinstance(event, bb.runqueue.sceneQueueTaskStarted):
340 self.emit("log", "info", "Running setscene task %d of %d (%s)" % \
341 (event.stats.completed + event.stats.active + event.stats.failed + 1,
342 event.stats.total, event.taskstring))
343 else:
344 if event.noexec:
345 tasktype = 'noexec task'
346 else:
347 tasktype = 'task'
348 self.emit("log", "info", "Running %s %s of %s (ID: %s, %s)" % \
349 (tasktype, event.stats.completed + event.stats.active + event.stats.failed + 1,
350 event.stats.total, event.taskid, event.taskstring))
327 message = {} 351 message = {}
328 message["eventname"] = bb.event.getName(event) 352 message["eventname"] = bb.event.getName(event)
329 num_of_completed = event.stats.completed + event.stats.failed 353 num_of_completed = event.stats.completed + event.stats.failed
@@ -332,6 +356,10 @@ class RunningBuild (gobject.GObject):
332 message["title"] = "" 356 message["title"] = ""
333 message["task"] = event.taskstring 357 message["task"] = event.taskstring
334 self.emit("task-started", message) 358 self.emit("task-started", message)
359 elif isinstance(event, bb.event.MultipleProviders):
360 self.emit("log", "info", "multiple providers are available for %s%s (%s)" \
361 % (event._is_runtime and "runtime " or "", event._item, ", ".join(event._candidates)))
362 self.emit("log", "info", "consider defining a PREFERRED_PROVIDER entry to match %s" % (event._item))
335 elif isinstance(event, bb.event.NoProvider): 363 elif isinstance(event, bb.event.NoProvider):
336 msg = "" 364 msg = ""
337 if event._runtime: 365 if event._runtime:
@@ -346,6 +374,19 @@ class RunningBuild (gobject.GObject):
346 for reason in event._reasons: 374 for reason in event._reasons:
347 msg += ("%s\n" % reason) 375 msg += ("%s\n" % reason)
348 self.emit("no-provider", msg) 376 self.emit("no-provider", msg)
377 self.emit("log", msg)
378 else:
379 if not isinstance(event, (bb.event.BuildBase,
380 bb.event.StampUpdate,
381 bb.event.ConfigParsed,
382 bb.event.RecipeParsed,
383 bb.event.RecipePreFinalise,
384 bb.runqueue.runQueueEvent,
385 bb.runqueue.runQueueExitWait,
386 bb.event.OperationStarted,
387 bb.event.OperationCompleted,
388 bb.event.OperationProgress)):
389 self.emit("log", "error", "Unknown event: %s" % (event.error if hasattr(event, 'error') else 'error'))
349 390
350 return 391 return
351 392