From 5a87d8c477ea829012785f2b284307c56f42787c Mon Sep 17 00:00:00 2001 From: Mirela Rabulea Date: Tue, 19 Jan 2016 16:31:38 +0200 Subject: bitbake: Allow Hob to run images on a custom simulator, other than qemu The current behavior of Hob is that there is a "Run Image" button which becomes visible only for qemu images. My suggested change is: - if an image is selected and it is qemu-compatible, let the "Run image" button be named "Run qemu image" - if an image is selected and it is not qemu-compatible, let the same button show up with the name "Run custom image", and besides that, an option shows-up to allow the selection of the custom script (by default it points out to runqemu script) to be used for launching this custom image Note: in case there is more than one toggled image (qemu runnable or deployable), when the user clicks the "Run custom image" button, a dialog will be presented, allowing to choose between any of the existing images. [YOCTO #8940] (Bitbake rev: cc4cfc2370297b8feb2dc39d4262e73adf06c09a) Signed-off-by: Mirela Rabulea Signed-off-by: Richard Purdie --- bitbake/lib/bb/ui/crumbs/builder.py | 59 +++++++++++++++++++++++ bitbake/lib/bb/ui/crumbs/imagedetailspage.py | 72 +++++++++++++++++++++------- 2 files changed, 113 insertions(+), 18 deletions(-) diff --git a/bitbake/lib/bb/ui/crumbs/builder.py b/bitbake/lib/bb/ui/crumbs/builder.py index dcc4104262..457cadc77a 100755 --- a/bitbake/lib/bb/ui/crumbs/builder.py +++ b/bitbake/lib/bb/ui/crumbs/builder.py @@ -1359,6 +1359,25 @@ class Builder(gtk.Window): return kernel_path + def show_load_run_script_dialog(self): + dialog = gtk.FileChooserDialog("Select Run Script", self, + gtk.FILE_CHOOSER_ACTION_OPEN) + button = dialog.add_button("Cancel", gtk.RESPONSE_NO) + HobAltButton.style_button(button) + button = dialog.add_button("Select", gtk.RESPONSE_YES) + HobButton.style_button(button) + + dialog.set_current_folder(self.parameters.image_addr) + + response = dialog.run() + run_script_path = "" + if response == gtk.RESPONSE_YES: + run_script_path = dialog.get_filename() + + dialog.destroy() + + return run_script_path + def runqemu_image(self, image_name, kernel_name): if not image_name or not kernel_name: lbl = "Please select %s to launch in QEMU." % ("a kernel" if image_name else "an image") @@ -1397,6 +1416,46 @@ class Builder(gtk.Window): dialog.run() dialog.destroy() + def run_custom_image(self, image_name, custom_sim_path): + if not image_name or not custom_sim_path: + if not image_name: + lbl = "Please select an image to launch in the custom simulator." + else: + lbl = "Please select a custom simulator for launching the selected image." + dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_INFO) + button = dialog.add_button("Close", gtk.RESPONSE_OK) + HobButton.style_button(button) + dialog.run() + dialog.destroy() + return + + image_path = os.path.join(self.parameters.image_addr, image_name) + + source_env_path = os.path.join(self.parameters.core_base, "oe-init-build-env") + tmp_path = self.parameters.tmpdir + cmdline = bb.ui.crumbs.utils.which_terminal() + if os.path.exists(image_path) and os.path.exists(custom_sim_path) \ + and os.path.exists(source_env_path) and os.path.exists(tmp_path) \ + and cmdline: + cmdline += "\' bash -c \"export OE_TMPDIR=" + tmp_path + "; " + cmdline += "source " + source_env_path + " " + os.getcwd() + "; " + cmdline += custom_sim_path + " " + image_path + "\"\'" + subprocess.Popen(shlex.split(cmdline)) + else: + lbl = "Path error" + msg = "One of your paths is wrong," + msg = msg + " please make sure the following paths exist:\n" + msg = msg + "image path:" + image_path + "\n" + msg = msg + "custom simulator path:" + custom_sim_path + "\n" + msg = msg + "source environment path:" + source_env_path + "\n" + msg = msg + "tmp path: " + tmp_path + "." + msg = msg + "You may be missing either xterm or vte for terminal services." + dialog = CrumbsMessageDialog(self, lbl, gtk.MESSAGE_ERROR, msg) + button = dialog.add_button("Close", gtk.RESPONSE_OK) + HobButton.style_button(button) + dialog.run() + dialog.destroy() + def show_packages(self): self.package_details_page.refresh_tables() self.switch_page(self.PACKAGE_SELECTION) diff --git a/bitbake/lib/bb/ui/crumbs/imagedetailspage.py b/bitbake/lib/bb/ui/crumbs/imagedetailspage.py index 352e9489fd..32d4854166 100755 --- a/bitbake/lib/bb/ui/crumbs/imagedetailspage.py +++ b/bitbake/lib/bb/ui/crumbs/imagedetailspage.py @@ -303,7 +303,7 @@ class ImageDetailsPage (HobPage): i = i + 1 self.num_toggled += is_toggled - is_runnable = self.create_bottom_buttons(self.buttonlist, self.toggled_image) + self.is_runnable = self.create_bottom_buttons(self.buttonlist, self.toggled_image) # Generated image files info varlist = ["Name: ", "Files created: ", "Directory: "] @@ -324,10 +324,23 @@ class ImageDetailsPage (HobPage): self.image_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=view_files_button, button2=open_log_button) self.box_group_area.pack_start(self.image_detail, expand=False, fill=True) + # The default script path to run the image (runqemu) + self.run_script_path = os.path.join(self.builder.parameters.core_base, "scripts/runqemu") + self.run_script_detail = None + varlist = ["Run script: "] + vallist = [] + vallist.append(self.run_script_path) + + change_run_script_button = HobAltButton("Change") + change_run_script_button.connect("clicked", self.change_run_script_cb) + change_run_script_button.set_tooltip_text("Change run script") + self.run_script_detail = self.DetailBox(varlist=varlist, vallist=vallist, button=change_run_script_button) + self.box_group_area.pack_start(self.run_script_detail, expand=False, fill=True) + # The default kernel box for the qemu images self.sel_kernel = "" self.kernel_detail = None - if 'qemu' in image_name: + if self.test_mach_runnable(image_name): self.sel_kernel = self.get_kernel_file_name() # varlist = ["Kernel: "] @@ -401,8 +414,10 @@ class ImageDetailsPage (HobPage): self.box_group_area.pack_start(self.details_bottom_buttons, expand=False, fill=False) self.show_all() - if self.kernel_detail and (not is_runnable): + if self.kernel_detail and (not self.is_runnable): self.kernel_detail.hide() + if self.run_script_detail and self.is_runnable: + self.run_script_detail.hide() self.image_saved = False def view_files_clicked_cb(self, button, image_addr): @@ -484,7 +499,9 @@ class ImageDetailsPage (HobPage): if (action_attr == 'run' and primary_action == "Run image") \ or (action_attr == 'deploy' and primary_action == "Deploy image"): action_images.append(fileitem) - + if (len(action_images) == 0 and primary_action == "Run image"): + # if there are no qemu runnable images, let the user choose any of the existing images for custom run + action_images = self.image_store # pack the corresponding 'runnable' or 'deploy' radio_buttons, if there has no more than one file. # assume that there does not both have 'deploy' and 'runnable' files in the same building result # in possible as design. @@ -499,7 +516,9 @@ class ImageDetailsPage (HobPage): for fileitem in action_images: sel_btn = gtk.RadioButton(sel_parent_btn, fileitem['type']) sel_parent_btn = sel_btn if not sel_parent_btn else sel_parent_btn - sel_btn.set_active(fileitem['is_toggled']) + if curr_row == 0: + sel_btn.set_active(True) + self.toggled_image = fileitem['name'] sel_btn.connect('toggled', self.table_selected_cb, fileitem) if curr_row < 10: table.attach(sel_btn, 0, 4, curr_row, curr_row + 1, xpadding=24) @@ -523,13 +542,15 @@ class ImageDetailsPage (HobPage): if response != gtk.RESPONSE_YES: return - + # perform the primary action on the image selected by the user for fileitem in self.image_store: - if fileitem['is_toggled']: - if fileitem['action_attr'] == 'run': + if fileitem['name'] == self.toggled_image: + if (fileitem['action_attr'] == 'run' and primary_action == "Run image"): self.builder.runqemu_image(fileitem['name'], self.sel_kernel) - elif fileitem['action_attr'] == 'deploy': + elif (fileitem['action_attr'] == 'deploy' and primary_action == "Deploy image"): self.builder.deploy_image(fileitem['name']) + elif (primary_action == "Run image"): + self.builder.run_custom_image(fileitem['name'], self.run_script_path) def table_selected_cb(self, tbutton, image): image['is_toggled'] = tbutton.get_active() @@ -541,9 +562,14 @@ class ImageDetailsPage (HobPage): if kernel_path and self.kernel_detail: import os.path self.sel_kernel = os.path.basename(kernel_path) - markup = self.kernel_detail.format_line("Kernel: ", self.sel_kernel) - label = ((self.kernel_detail.get_children()[0]).get_children()[0]).get_children()[0] - label.set_markup(markup) + self.kernel_detail.update_line_widgets("Kernel: ", self.sel_kernel); + + def change_run_script_cb(self, widget): + self.run_script_path = self.builder.show_load_run_script_dialog() + if self.run_script_path and self.run_script_detail: + import os.path + self.sel_run_script = os.path.basename(self.run_script_path) + self.run_script_detail.update_line_widgets("Run script: ", self.run_script_path) def create_bottom_buttons(self, buttonlist, image_name): # Create the buttons at the bottom @@ -566,26 +592,33 @@ class ImageDetailsPage (HobPage): packed = True name = "Run image" - if name in buttonlist and self.test_type_runnable(image_name) and self.test_mach_runnable(image_name): + if name in buttonlist: + name = "Run qemu image" + is_runnable = True + if not (self.test_type_runnable(image_name) and self.test_mach_runnable(image_name)): + name = "Run custom image" + is_runnable = False if created == True: # separator #label = gtk.Label(" or ") #self.details_bottom_buttons.pack_end(label, expand=False, fill=False) # create button "Run image" - run_button = HobAltButton("Run image") + run_button = HobAltButton(name) else: # create button "Run image" as the primary button - run_button = HobButton("Run image") + run_button = HobButton(name) #run_button.set_size_request(205, 49) run_button.set_flags(gtk.CAN_DEFAULT) packed = True - run_button.set_tooltip_text("Start up an image with qemu emulator") + if is_runnable: + run_button.set_tooltip_text("Start up an image with qemu emulator") + else: + run_button.set_tooltip_text("Start up an image with custom simulator") button_id = run_button.connect("clicked", self.run_button_clicked_cb) self.button_ids[button_id] = run_button self.details_bottom_buttons.pack_end(run_button, expand=False, fill=False) created = True - is_runnable = True name = "Save image recipe" if name in buttonlist and self.builder.recipe_model.is_custom_image(): @@ -628,7 +661,10 @@ class ImageDetailsPage (HobPage): self.show_builded_images_dialog(None, "Run image") self.set_sensitive(True) else: - self.builder.runqemu_image(self.toggled_image, self.sel_kernel) + if self.is_runnable: + self.builder.runqemu_image(self.toggled_image, self.sel_kernel) + else: + self.builder.run_custom_image(self.toggled_image, self.run_script_path) def save_button_clicked_cb(self, button): topdir = self.builder.get_topdir() -- cgit 1.2.3-korg