diff options
Diffstat (limited to 'bitbake/lib/bb/ui/crumbs/hobeventhandler.py')
| -rw-r--r-- | bitbake/lib/bb/ui/crumbs/hobeventhandler.py | 586 | 
1 files changed, 351 insertions, 235 deletions
diff --git a/bitbake/lib/bb/ui/crumbs/hobeventhandler.py b/bitbake/lib/bb/ui/crumbs/hobeventhandler.py index ddab987ca8..b071ad4503 100644 --- a/bitbake/lib/bb/ui/crumbs/hobeventhandler.py +++ b/bitbake/lib/bb/ui/crumbs/hobeventhandler.py  | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | # Copyright (C) 2011 Intel Corporation | 4 | # Copyright (C) 2011 Intel Corporation | 
| 5 | # | 5 | # | 
| 6 | # Authored by Joshua Lock <josh@linux.intel.com> | 6 | # Authored by Joshua Lock <josh@linux.intel.com> | 
| 7 | # Authored by Dongxiao Xu <dongxiao.xu@intel.com> | ||
| 7 | # | 8 | # | 
| 8 | # This program is free software; you can redistribute it and/or modify | 9 | # This program is free software; you can redistribute it and/or modify | 
| 9 | # it under the terms of the GNU General Public License version 2 as | 10 | # it under the terms of the GNU General Public License version 2 as | 
| @@ -20,10 +21,7 @@ | |||
| 20 | 21 | ||
| 21 | import gobject | 22 | import gobject | 
| 22 | import logging | 23 | import logging | 
| 23 | import tempfile | 24 | from bb.ui.crumbs.runningbuild import RunningBuild | 
| 24 | import datetime | ||
| 25 | |||
| 26 | progress_total = 0 | ||
| 27 | 25 | ||
| 28 | class HobHandler(gobject.GObject): | 26 | class HobHandler(gobject.GObject): | 
| 29 | 27 | ||
| @@ -31,147 +29,176 @@ class HobHandler(gobject.GObject): | |||
| 31 | This object does BitBake event handling for the hob gui. | 29 | This object does BitBake event handling for the hob gui. | 
| 32 | """ | 30 | """ | 
| 33 | __gsignals__ = { | 31 | __gsignals__ = { | 
| 34 | "machines-updated" : (gobject.SIGNAL_RUN_LAST, | 32 | "layers-updated" : (gobject.SIGNAL_RUN_LAST, | 
| 35 | gobject.TYPE_NONE, | 33 | gobject.TYPE_NONE, | 
| 36 | (gobject.TYPE_PYOBJECT,)), | 34 | (gobject.TYPE_PYOBJECT,)), | 
| 37 | "sdk-machines-updated": (gobject.SIGNAL_RUN_LAST, | 35 | "package-formats-updated" : (gobject.SIGNAL_RUN_LAST, | 
| 38 | gobject.TYPE_NONE, | 36 | gobject.TYPE_NONE, | 
| 39 | (gobject.TYPE_PYOBJECT,)), | 37 | (gobject.TYPE_PYOBJECT,)), | 
| 40 | "distros-updated" : (gobject.SIGNAL_RUN_LAST, | 38 | "config-updated" : (gobject.SIGNAL_RUN_LAST, | 
| 41 | gobject.TYPE_NONE, | 39 | gobject.TYPE_NONE, | 
| 42 | (gobject.TYPE_PYOBJECT,)), | 40 | (gobject.TYPE_STRING, gobject.TYPE_PYOBJECT,)), | 
| 43 | "package-formats-found" : (gobject.SIGNAL_RUN_LAST, | 41 | "command-succeeded" : (gobject.SIGNAL_RUN_LAST, | 
| 44 | gobject.TYPE_NONE, | 42 | gobject.TYPE_NONE, | 
| 45 | (gobject.TYPE_PYOBJECT,)), | 43 | (gobject.TYPE_INT,)), | 
| 46 | "config-found" : (gobject.SIGNAL_RUN_LAST, | 44 | "command-failed" : (gobject.SIGNAL_RUN_LAST, | 
| 47 | gobject.TYPE_NONE, | 45 | gobject.TYPE_NONE, | 
| 48 | (gobject.TYPE_STRING,)), | 46 | (gobject.TYPE_STRING,)), | 
| 49 | "generating-data" : (gobject.SIGNAL_RUN_LAST, | 47 | "generating-data" : (gobject.SIGNAL_RUN_LAST, | 
| 50 | gobject.TYPE_NONE, | 48 | gobject.TYPE_NONE, | 
| 51 | ()), | 49 | ()), | 
| 52 | "data-generated" : (gobject.SIGNAL_RUN_LAST, | 50 | "data-generated" : (gobject.SIGNAL_RUN_LAST, | 
| 53 | gobject.TYPE_NONE, | 51 | gobject.TYPE_NONE, | 
| 54 | ()), | 52 | ()), | 
| 55 | "fatal-error" : (gobject.SIGNAL_RUN_LAST, | 53 | "parsing-started" : (gobject.SIGNAL_RUN_LAST, | 
| 56 | gobject.TYPE_NONE, | 54 | gobject.TYPE_NONE, | 
| 57 | (gobject.TYPE_STRING, | 55 | (gobject.TYPE_PYOBJECT,)), | 
| 58 | gobject.TYPE_STRING,)), | 56 | "parsing" : (gobject.SIGNAL_RUN_LAST, | 
| 59 | "command-failed" : (gobject.SIGNAL_RUN_LAST, | 57 | gobject.TYPE_NONE, | 
| 60 | gobject.TYPE_NONE, | 58 | (gobject.TYPE_PYOBJECT,)), | 
| 61 | (gobject.TYPE_STRING,)), | 59 | "parsing-completed" : (gobject.SIGNAL_RUN_LAST, | 
| 62 | "reload-triggered" : (gobject.SIGNAL_RUN_LAST, | 60 | gobject.TYPE_NONE, | 
| 63 | gobject.TYPE_NONE, | 61 | (gobject.TYPE_PYOBJECT,)), | 
| 64 | (gobject.TYPE_STRING, | ||
| 65 | gobject.TYPE_STRING,)), | ||
| 66 | } | 62 | } | 
| 67 | 63 | ||
| 68 | (CFG_PATH_LOCAL, CFG_PATH_PRE, CFG_PATH_POST, CFG_PATH_LAYERS, CFG_FILES_DISTRO, CFG_FILES_MACH, CFG_FILES_SDK, FILES_MATCH_CLASS, GENERATE_TGTS, REPARSE_FILES, BUILD_IMAGE) = range(11) | 64 | (CFG_AVAIL_LAYERS, CFG_PATH_LAYERS, CFG_FILES_DISTRO, CFG_FILES_MACH, CFG_FILES_SDKMACH, FILES_MATCH_CLASS, PARSE_CONFIG, PARSE_BBFILES, GENERATE_TGTS, GENERATE_PACKAGEINFO, BUILD_TARGET_RECIPES, BUILD_TARGET_IMAGE, CMD_END) = range(13) | 
| 65 | (LAYERS_REFRESH, GENERATE_RECIPES, GENERATE_PACKAGES, GENERATE_IMAGE, POPULATE_PACKAGEINFO) = range(5) | ||
| 69 | 66 | ||
| 70 | def __init__(self, taskmodel, server): | 67 | def __init__(self, server, server_addr, client_addr, recipe_model, package_model): | 
| 71 | gobject.GObject.__init__(self) | 68 | super(HobHandler, self).__init__() | 
| 72 | 69 | ||
| 73 | self.current_command = None | 70 | self.build = RunningBuild(sequential=True) | 
| 74 | self.building = False | 71 | |
| 75 | self.build_toolchain = False | 72 | self.recipe_model = recipe_model | 
| 76 | self.build_toolchain_headers = False | 73 | self.package_model = package_model | 
| 74 | |||
| 75 | self.commands_async = [] | ||
| 77 | self.generating = False | 76 | self.generating = False | 
| 78 | self.build_queue = [] | ||
| 79 | self.current_phase = None | 77 | self.current_phase = None | 
| 80 | self.bbpath_ok = False | 78 | self.building = False | 
| 81 | self.bbfiles_ok = False | 79 | self.recipe_queue = [] | 
| 82 | self.build_type = "image" | 80 | self.package_queue = [] | 
| 83 | self.image_dir = os.path.join(tempfile.gettempdir(), 'hob-images') | ||
| 84 | 81 | ||
| 85 | self.model = taskmodel | ||
| 86 | self.server = server | 82 | self.server = server | 
| 87 | 83 | self.error_msg = "" | |
| 88 | deploy_dir = self.server.runCommand(["getVariable", "DEPLOY_DIR"]) | 84 | self.initcmd = None | 
| 89 | self.image_out_dir = os.path.join(deploy_dir, "images") | 85 | |
| 90 | self.image_output_types = self.server.runCommand(["getVariable", "IMAGE_FSTYPES"]).split(" ") | 86 | self.split_model = False | 
| 91 | self.bbpath = self.server.runCommand(["getVariable", "BBPATH"]) | 87 | if server_addr and client_addr: | 
| 92 | self.bbfiles = self.server.runCommand(["getVariable", "BBFILES"]) | 88 | self.split_model = (server_addr != client_addr) | 
| 93 | 89 | self.reset_server() # reset server if server was found just now | |
| 94 | def run_next_command(self): | 90 | self.server_addr = server_addr | 
| 95 | if self.current_command and not self.generating: | 91 | |
| 92 | def kick(self): | ||
| 93 | import xmlrpclib | ||
| 94 | try: | ||
| 95 | # kick the while thing off | ||
| 96 | if self.split_model: | ||
| 97 | self.commands_async.append(self.CFG_AVAIL_LAYERS) | ||
| 98 | else: | ||
| 99 | self.commands_async.append(self.CFG_PATH_LAYERS) | ||
| 100 | self.commands_async.append(self.CFG_FILES_DISTRO) | ||
| 101 | self.commands_async.append(self.CFG_FILES_MACH) | ||
| 102 | self.commands_async.append(self.CFG_FILES_SDKMACH) | ||
| 103 | self.commands_async.append(self.FILES_MATCH_CLASS) | ||
| 104 | self.run_next_command() | ||
| 105 | return True | ||
| 106 | except xmlrpclib.Fault as x: | ||
| 107 | print("XMLRPC Fault getting commandline:\n %s" % x) | ||
| 108 | return False | ||
| 109 | |||
| 110 | def set_busy(self): | ||
| 111 | if not self.generating: | ||
| 96 | self.emit("generating-data") | 112 | self.emit("generating-data") | 
| 97 | self.generating = True | 113 | self.generating = True | 
| 98 | 114 | ||
| 99 | if self.current_command == self.CFG_PATH_LOCAL: | 115 | def clear_busy(self): | 
| 100 | self.current_command = self.CFG_PATH_PRE | 116 | if self.generating: | 
| 101 | self.server.runCommand(["findConfigFilePath", "hob-pre.conf"]) | 117 | self.emit("data-generated") | 
| 102 | elif self.current_command == self.CFG_PATH_PRE: | 118 | self.generating = False | 
| 103 | self.current_command = self.CFG_PATH_POST | 119 | |
| 104 | self.server.runCommand(["findConfigFilePath", "hob-post.conf"]) | 120 | def run_next_command(self, initcmd=None): | 
| 105 | elif self.current_command == self.CFG_PATH_POST: | 121 | if initcmd != None: | 
| 106 | self.current_command = self.CFG_PATH_LAYERS | 122 | self.initcmd = initcmd | 
| 123 | |||
| 124 | if self.commands_async: | ||
| 125 | self.set_busy() | ||
| 126 | next_command = self.commands_async.pop(0) | ||
| 127 | else: | ||
| 128 | self.clear_busy() | ||
| 129 | if self.initcmd != None: | ||
| 130 | self.emit("command-succeeded", self.initcmd) | ||
| 131 | return | ||
| 132 | |||
| 133 | if next_command == self.CFG_AVAIL_LAYERS: | ||
| 134 | self.server.runCommand(["findCoreBaseFiles", "layers", "conf/layer.conf"]) | ||
| 135 | elif next_command == self.CFG_PATH_LAYERS: | ||
| 107 | self.server.runCommand(["findConfigFilePath", "bblayers.conf"]) | 136 | self.server.runCommand(["findConfigFilePath", "bblayers.conf"]) | 
| 108 | elif self.current_command == self.CFG_PATH_LAYERS: | 137 | elif next_command == self.CFG_FILES_DISTRO: | 
| 109 | self.current_command = self.CFG_FILES_DISTRO | ||
| 110 | self.server.runCommand(["findConfigFiles", "DISTRO"]) | 138 | self.server.runCommand(["findConfigFiles", "DISTRO"]) | 
| 111 | elif self.current_command == self.CFG_FILES_DISTRO: | 139 | elif next_command == self.CFG_FILES_MACH: | 
| 112 | self.current_command = self.CFG_FILES_MACH | ||
| 113 | self.server.runCommand(["findConfigFiles", "MACHINE"]) | 140 | self.server.runCommand(["findConfigFiles", "MACHINE"]) | 
| 114 | elif self.current_command == self.CFG_FILES_MACH: | 141 | elif next_command == self.CFG_FILES_SDKMACH: | 
| 115 | self.current_command = self.CFG_FILES_SDK | ||
| 116 | self.server.runCommand(["findConfigFiles", "MACHINE-SDK"]) | 142 | self.server.runCommand(["findConfigFiles", "MACHINE-SDK"]) | 
| 117 | elif self.current_command == self.CFG_FILES_SDK: | 143 | elif next_command == self.FILES_MATCH_CLASS: | 
| 118 | self.current_command = self.FILES_MATCH_CLASS | ||
| 119 | self.server.runCommand(["findFilesMatchingInDir", "rootfs_", "classes"]) | 144 | self.server.runCommand(["findFilesMatchingInDir", "rootfs_", "classes"]) | 
| 120 | elif self.current_command == self.FILES_MATCH_CLASS: | 145 | elif next_command == self.PARSE_CONFIG: | 
| 121 | self.current_command = self.GENERATE_TGTS | 146 | self.server.runCommand(["parseConfigurationFiles", "", ""]) | 
| 122 | self.server.runCommand(["generateTargetsTree", "classes/image.bbclass"]) | 147 | elif next_command == self.PARSE_BBFILES: | 
| 123 | elif self.current_command == self.GENERATE_TGTS: | 148 | self.server.runCommand(["parseFiles"]) | 
| 124 | if self.generating: | 149 | elif next_command == self.GENERATE_TGTS: | 
| 125 | self.emit("data-generated") | 150 | self.server.runCommand(["generateTargetsTree", "classes/image.bbclass", [], True]) | 
| 126 | self.generating = False | 151 | elif next_command == self.GENERATE_PACKAGEINFO: | 
| 127 | self.current_command = None | 152 | self.server.runCommand(["triggerEvent", "bb.event.RequestPackageInfo()"]) | 
| 128 | elif self.current_command == self.REPARSE_FILES: | 153 | elif next_command == self.BUILD_TARGET_RECIPES: | 
| 129 | if self.build_queue: | 154 | self.clear_busy() | 
| 130 | self.current_command = self.BUILD_IMAGE | ||
| 131 | else: | ||
| 132 | self.current_command = self.CFG_PATH_LAYERS | ||
| 133 | self.server.runCommand(["resetCooker"]) | ||
| 134 | self.server.runCommand(["reparseFiles"]) | ||
| 135 | elif self.current_command == self.BUILD_IMAGE: | ||
| 136 | if self.generating: | ||
| 137 | self.emit("data-generated") | ||
| 138 | self.generating = False | ||
| 139 | self.building = True | 155 | self.building = True | 
| 140 | self.server.runCommand(["buildTargets", self.build_queue, "build"]) | 156 | self.server.runCommand(["buildTargets", self.recipe_queue, "build"]) | 
| 141 | self.build_queue = [] | 157 | self.recipe_queue = [] | 
| 142 | self.current_command = None | 158 | elif next_command == self.BUILD_TARGET_IMAGE: | 
| 143 | 159 | self.clear_busy() | |
| 144 | def handle_event(self, event, running_build, pbar): | 160 | self.building = True | 
| 161 | targets = ["hob-image"] | ||
| 162 | self.server.runCommand(["setVariable", "LINGUAS_INSTALL", ""]) | ||
| 163 | self.server.runCommand(["setVariable", "PACKAGE_INSTALL", " ".join(self.package_queue)]) | ||
| 164 | if self.toolchain_build: | ||
| 165 | pkgs = self.package_queue + [i+'-dev' for i in self.package_queue] + [i+'-dbg' for i in self.package_queue] | ||
| 166 | self.server.runCommand(["setVariable", "TOOLCHAIN_TARGET_TASK", " ".join(pkgs)]) | ||
| 167 | targets.append("hob-toolchain") | ||
| 168 | self.server.runCommand(["buildTargets", targets, "build"]) | ||
| 169 | |||
| 170 | def handle_event(self, event): | ||
| 145 | if not event: | 171 | if not event: | 
| 146 | return | 172 | return | 
| 147 | 173 | ||
| 148 | # If we're running a build, use the RunningBuild event handler | ||
| 149 | if self.building: | 174 | if self.building: | 
| 150 | self.current_phase = "building" | 175 | self.current_phase = "building" | 
| 151 | running_build.handle_event(event) | 176 | self.build.handle_event(event) | 
| 177 | |||
| 178 | if isinstance(event, bb.event.PackageInfo): | ||
| 179 | self.package_model.populate(event._pkginfolist) | ||
| 180 | self.run_next_command() | ||
| 181 | |||
| 182 | elif(isinstance(event, logging.LogRecord)): | ||
| 183 | if event.levelno >= logging.ERROR: | ||
| 184 | self.error_msg += event.msg + '\n' | ||
| 185 | |||
| 152 | elif isinstance(event, bb.event.TargetsTreeGenerated): | 186 | elif isinstance(event, bb.event.TargetsTreeGenerated): | 
| 153 | self.current_phase = "data generation" | 187 | self.current_phase = "data generation" | 
| 154 | if event._model: | 188 | if event._model: | 
| 155 | self.model.populate(event._model) | 189 | self.recipe_model.populate(event._model) | 
| 190 | elif isinstance(event, bb.event.CoreBaseFilesFound): | ||
| 191 | self.current_phase = "configuration lookup" | ||
| 192 | paths = event._paths | ||
| 193 | self.emit('layers-updated', paths) | ||
| 156 | elif isinstance(event, bb.event.ConfigFilesFound): | 194 | elif isinstance(event, bb.event.ConfigFilesFound): | 
| 157 | self.current_phase = "configuration lookup" | 195 | self.current_phase = "configuration lookup" | 
| 158 | var = event._variable | 196 | var = event._variable | 
| 159 | if var == "distro": | 197 | values = event._values | 
| 160 | distros = event._values | 198 | values.sort() | 
| 161 | distros.sort() | 199 | self.emit("config-updated", var, values) | 
| 162 | self.emit("distros-updated", distros) | ||
| 163 | elif var == "machine": | ||
| 164 | machines = event._values | ||
| 165 | machines.sort() | ||
| 166 | self.emit("machines-updated", machines) | ||
| 167 | elif var == "machine-sdk": | ||
| 168 | sdk_machines = event._values | ||
| 169 | sdk_machines.sort() | ||
| 170 | self.emit("sdk-machines-updated", sdk_machines) | ||
| 171 | elif isinstance(event, bb.event.ConfigFilePathFound): | 200 | elif isinstance(event, bb.event.ConfigFilePathFound): | 
| 172 | self.current_phase = "configuration lookup" | 201 | self.current_phase = "configuration lookup" | 
| 173 | path = event._path | ||
| 174 | self.emit("config-found", path) | ||
| 175 | elif isinstance(event, bb.event.FilesMatchingFound): | 202 | elif isinstance(event, bb.event.FilesMatchingFound): | 
| 176 | self.current_phase = "configuration lookup" | 203 | self.current_phase = "configuration lookup" | 
| 177 | # FIXME: hard coding, should at least be a variable shared between | 204 | # FIXME: hard coding, should at least be a variable shared between | 
| @@ -183,48 +210,84 @@ class HobHandler(gobject.GObject): | |||
| 183 | fs, sep, format = classname.rpartition("_") | 210 | fs, sep, format = classname.rpartition("_") | 
| 184 | formats.append(format) | 211 | formats.append(format) | 
| 185 | formats.sort() | 212 | formats.sort() | 
| 186 | self.emit("package-formats-found", formats) | 213 | self.emit("package-formats-updated", formats) | 
| 187 | elif isinstance(event, bb.command.CommandCompleted): | 214 | elif isinstance(event, bb.command.CommandCompleted): | 
| 188 | self.current_phase = None | 215 | self.current_phase = None | 
| 189 | self.run_next_command() | 216 | self.run_next_command() | 
| 217 | |||
| 218 | elif isinstance(event, bb.event.NoProvider): | ||
| 219 | if event._runtime: | ||
| 220 | r = "R" | ||
| 221 | else: | ||
| 222 | r = "" | ||
| 223 | if event._dependees: | ||
| 224 | self.error_msg += " Nothing %sPROVIDES '%s' (but %s %sDEPENDS on or otherwise requires it)" % (r, event._item, ", ".join(event._dependees), r) | ||
| 225 | else: | ||
| 226 | self.error_msg += " Nothing %sPROVIDES '%s'" % (r, event._item) | ||
| 227 | if event._reasons: | ||
| 228 | for reason in event._reasons: | ||
| 229 | self.error_msg += " %s" % reason | ||
| 230 | |||
| 231 | self.commands_async = [] | ||
| 232 | self.emit("command-failed", self.error_msg) | ||
| 233 | self.error_msg = "" | ||
| 234 | |||
| 190 | elif isinstance(event, bb.command.CommandFailed): | 235 | elif isinstance(event, bb.command.CommandFailed): | 
| 191 | self.emit("command-failed", event.error) | 236 | self.commands_async = [] | 
| 192 | elif isinstance(event, bb.event.CacheLoadStarted): | 237 | if self.error_msg: | 
| 193 | self.current_phase = "cache loading" | 238 | self.emit("command-failed", self.error_msg) | 
| 194 | bb.ui.crumbs.hobeventhandler.progress_total = event.total | 239 | self.error_msg = "" | 
| 195 | pbar.set_text("Loading cache: %s/%s" % (0, bb.ui.crumbs.hobeventhandler.progress_total)) | 240 | elif isinstance(event, (bb.event.ParseStarted, | 
| 196 | elif isinstance(event, bb.event.CacheLoadProgress): | 241 | bb.event.CacheLoadStarted, | 
| 197 | self.current_phase = "cache loading" | 242 | bb.event.TreeDataPreparationStarted, | 
| 198 | pbar.set_text("Loading cache: %s/%s" % (event.current, bb.ui.crumbs.hobeventhandler.progress_total)) | 243 | )): | 
| 199 | elif isinstance(event, bb.event.CacheLoadCompleted): | 244 | message = {} | 
| 200 | self.current_phase = None | 245 | message["eventname"] = bb.event.getName(event) | 
| 201 | pbar.set_text("Loading...") | 246 | message["current"] = 0 | 
| 202 | elif isinstance(event, bb.event.ParseStarted): | 247 | message["total"] = None | 
| 203 | self.current_phase = "recipe parsing" | 248 | message["title"] = "Parsing recipes: " | 
| 204 | if event.total == 0: | 249 | self.emit("parsing-started", message) | 
| 205 | return | 250 | elif isinstance(event, (bb.event.ParseProgress, | 
| 206 | bb.ui.crumbs.hobeventhandler.progress_total = event.total | 251 | bb.event.CacheLoadProgress, | 
| 207 | pbar.set_text("Processing recipes: %s/%s" % (0, bb.ui.crumbs.hobeventhandler.progress_total)) | 252 | bb.event.TreeDataPreparationProgress)): | 
| 208 | elif isinstance(event, bb.event.ParseProgress): | 253 | message = {} | 
| 209 | self.current_phase = "recipe parsing" | 254 | message["eventname"] = bb.event.getName(event) | 
| 210 | pbar.set_text("Processing recipes: %s/%s" % (event.current, bb.ui.crumbs.hobeventhandler.progress_total)) | 255 | message["current"] = event.current | 
| 211 | elif isinstance(event, bb.event.ParseCompleted): | 256 | message["total"] = event.total | 
| 212 | self.current_phase = None | 257 | message["title"] = "Parsing recipes: " | 
| 213 | pbar.set_fraction(1.0) | 258 | self.emit("parsing", message) | 
| 214 | pbar.set_text("Loading...") | 259 | elif isinstance(event, (bb.event.ParseCompleted, | 
| 215 | elif isinstance(event, logging.LogRecord): | 260 | bb.event.CacheLoadCompleted, | 
| 216 | format = bb.msg.BBLogFormatter("%(levelname)s: %(message)s") | 261 | bb.event.TreeDataPreparationCompleted)): | 
| 217 | if event.levelno >= format.CRITICAL: | 262 | message = {} | 
| 218 | self.emit("fatal-error", event.getMessage(), self.current_phase) | 263 | message["eventname"] = bb.event.getName(event) | 
| 264 | message["current"] = event.total | ||
| 265 | message["total"] = event.total | ||
| 266 | message["title"] = "Parsing recipes: " | ||
| 267 | self.emit("parsing-completed", message) | ||
| 268 | |||
| 219 | return | 269 | return | 
| 220 | 270 | ||
| 221 | def event_handle_idle_func (self, eventHandler, running_build, pbar): | 271 | def init_cooker(self): | 
| 222 | # Consume as many messages as we can in the time available to us | 272 | self.server.runCommand(["initCooker"]) | 
| 223 | event = eventHandler.getEvent() | 273 | |
| 224 | while event: | 274 | def refresh_layers(self, bblayers): | 
| 225 | self.handle_event(event, running_build, pbar) | 275 | self.server.runCommand(["initCooker"]) | 
| 226 | event = eventHandler.getEvent() | 276 | self.server.runCommand(["setVariable", "BBLAYERS", " ".join(bblayers)]) | 
| 227 | return True | 277 | self.commands_async.append(self.PARSE_CONFIG) | 
| 278 | self.commands_async.append(self.CFG_FILES_DISTRO) | ||
| 279 | self.commands_async.append(self.CFG_FILES_MACH) | ||
| 280 | self.commands_async.append(self.CFG_FILES_SDKMACH) | ||
| 281 | self.commands_async.append(self.FILES_MATCH_CLASS) | ||
| 282 | self.run_next_command(self.LAYERS_REFRESH) | ||
| 283 | |||
| 284 | def set_extra_inherit(self, bbclass): | ||
| 285 | inherits = self.server.runCommand(["getVariable", "INHERIT"]) or "" | ||
| 286 | inherits = inherits + " " + bbclass | ||
| 287 | self.server.runCommand(["setVariable", "INHERIT", inherits]) | ||
| 288 | |||
| 289 | def set_bblayers(self, bblayers): | ||
| 290 | self.server.runCommand(["setVariable", "BBLAYERS", " ".join(bblayers)]) | ||
| 228 | 291 | ||
| 229 | def set_machine(self, machine): | 292 | def set_machine(self, machine): | 
| 230 | self.server.runCommand(["setVariable", "MACHINE", machine]) | 293 | self.server.runCommand(["setVariable", "MACHINE", machine]) | 
| @@ -232,62 +295,78 @@ class HobHandler(gobject.GObject): | |||
| 232 | def set_sdk_machine(self, sdk_machine): | 295 | def set_sdk_machine(self, sdk_machine): | 
| 233 | self.server.runCommand(["setVariable", "SDKMACHINE", sdk_machine]) | 296 | self.server.runCommand(["setVariable", "SDKMACHINE", sdk_machine]) | 
| 234 | 297 | ||
| 298 | def set_image_fstypes(self, image_fstypes): | ||
| 299 | self.server.runCommand(["setVariable", "IMAGE_FSTYPES", " ".join(image_fstypes).lstrip(" ")]) | ||
| 300 | |||
| 235 | def set_distro(self, distro): | 301 | def set_distro(self, distro): | 
| 236 | self.server.runCommand(["setVariable", "DISTRO", distro]) | 302 | self.server.runCommand(["setVariable", "DISTRO", distro]) | 
| 237 | 303 | ||
| 238 | def set_package_format(self, format): | 304 | def set_package_format(self, format): | 
| 239 | self.server.runCommand(["setVariable", "PACKAGE_CLASSES", "package_%s" % format]) | 305 | package_classes = "" | 
| 240 | 306 | for pkgfmt in format.split(): | |
| 241 | def reload_data(self, config=None): | 307 | package_classes += ("package_%s" % pkgfmt + " ") | 
| 242 | img = self.model.selected_image | 308 | self.server.runCommand(["setVariable", "PACKAGE_CLASSES", package_classes]) | 
| 243 | selected_packages, _ = self.model.get_selected_packages() | ||
| 244 | self.emit("reload-triggered", img, " ".join(selected_packages)) | ||
| 245 | self.current_command = self.REPARSE_FILES | ||
| 246 | self.run_next_command() | ||
| 247 | 309 | ||
| 248 | def set_bbthreads(self, threads): | 310 | def set_bbthreads(self, threads): | 
| 249 | self.server.runCommand(["setVariable", "BB_NUMBER_THREADS", threads]) | 311 | self.server.runCommand(["setVariable", "BB_NUMBER_THREADS", threads]) | 
| 250 | 312 | ||
| 251 | def set_pmake(self, threads): | 313 | def set_pmake(self, threads): | 
| 252 | pmake = "-j %s" % threads | 314 | pmake = "-j %s" % threads | 
| 253 | self.server.runCommand(["setVariable", "BB_NUMBER_THREADS", pmake]) | 315 | self.server.runCommand(["setVariable", "PARALLEL_MAKE", pmake]) | 
| 254 | 316 | ||
| 255 | def build_targets(self, tgts, configurator, build_type="image"): | 317 | def set_dl_dir(self, directory): | 
| 256 | self.build_type = build_type | 318 | self.server.runCommand(["setVariable", "DL_DIR", directory]) | 
| 257 | targets = [] | 319 | |
| 258 | nbbp = None | 320 | def set_sstate_dir(self, directory): | 
| 259 | nbbf = None | 321 | self.server.runCommand(["setVariable", "SSTATE_DIR", directory]) | 
| 260 | targets.extend(tgts) | ||
| 261 | if self.build_toolchain and self.build_toolchain_headers: | ||
| 262 | targets.append("meta-toolchain-sdk") | ||
| 263 | elif self.build_toolchain: | ||
| 264 | targets.append("meta-toolchain") | ||
| 265 | self.build_queue = targets | ||
| 266 | |||
| 267 | if not self.bbpath_ok: | ||
| 268 | if self.image_dir in self.bbpath.split(":"): | ||
| 269 | self.bbpath_ok = True | ||
| 270 | else: | ||
| 271 | nbbp = self.image_dir | ||
| 272 | 322 | ||
| 273 | if not self.bbfiles_ok: | 323 | def set_sstate_mirror(self, url): | 
| 274 | import re | 324 | self.server.runCommand(["setVariable", "SSTATE_MIRROR", url]) | 
| 275 | pattern = "%s/\*.bb" % self.image_dir | ||
| 276 | 325 | ||
| 277 | for files in self.bbfiles.split(" "): | 326 | def set_extra_size(self, image_extra_size): | 
| 278 | if re.match(pattern, files): | 327 | self.server.runCommand(["setVariable", "IMAGE_ROOTFS_EXTRA_SPACE", str(image_extra_size)]) | 
| 279 | self.bbfiles_ok = True | ||
| 280 | 328 | ||
| 281 | if not self.bbfiles_ok: | 329 | def set_rootfs_size(self, image_rootfs_size): | 
| 282 | nbbf = "%s/*.bb" % self.image_dir | 330 | self.server.runCommand(["setVariable", "IMAGE_ROOTFS_SIZE", str(image_rootfs_size)]) | 
| 283 | 331 | ||
| 284 | if nbbp or nbbf: | 332 | def set_incompatible_license(self, incompat_license): | 
| 285 | configurator.insertTempBBPath(nbbp, nbbf) | 333 | self.server.runCommand(["setVariable", "INCOMPATIBLE_LICENSE", incompat_license]) | 
| 286 | self.bbpath_ok = True | ||
| 287 | self.bbfiles_ok = True | ||
| 288 | 334 | ||
| 289 | self.current_command = self.REPARSE_FILES | 335 | def set_extra_config(self, extra_setting): | 
| 290 | self.run_next_command() | 336 | for key in extra_setting.keys(): | 
| 337 | value = extra_setting[key] | ||
| 338 | self.server.runCommand(["setVariable", key, value]) | ||
| 339 | |||
| 340 | def request_package_info_async(self): | ||
| 341 | self.commands_async.append(self.GENERATE_PACKAGEINFO) | ||
| 342 | self.run_next_command(self.POPULATE_PACKAGEINFO) | ||
| 343 | |||
| 344 | def generate_recipes(self): | ||
| 345 | self.commands_async.append(self.PARSE_CONFIG) | ||
| 346 | self.commands_async.append(self.GENERATE_TGTS) | ||
| 347 | self.run_next_command(self.GENERATE_RECIPES) | ||
| 348 | |||
| 349 | def generate_packages(self, tgts): | ||
| 350 | targets = [] | ||
| 351 | targets.extend(tgts) | ||
| 352 | self.recipe_queue = targets | ||
| 353 | self.commands_async.append(self.PARSE_CONFIG) | ||
| 354 | self.commands_async.append(self.PARSE_BBFILES) | ||
| 355 | self.commands_async.append(self.BUILD_TARGET_RECIPES) | ||
| 356 | self.run_next_command(self.GENERATE_PACKAGES) | ||
| 357 | |||
| 358 | def generate_image(self, tgts, toolchain_build=False): | ||
| 359 | self.package_queue = tgts | ||
| 360 | self.toolchain_build = toolchain_build | ||
| 361 | self.commands_async.append(self.PARSE_CONFIG) | ||
| 362 | self.commands_async.append(self.PARSE_BBFILES) | ||
| 363 | self.commands_async.append(self.BUILD_TARGET_IMAGE) | ||
| 364 | self.run_next_command(self.GENERATE_IMAGE) | ||
| 365 | |||
| 366 | def build_failed_async(self): | ||
| 367 | self.initcmd = None | ||
| 368 | self.commands_async = [] | ||
| 369 | self.building = False | ||
| 291 | 370 | ||
| 292 | def cancel_build(self, force=False): | 371 | def cancel_build(self, force=False): | 
| 293 | if force: | 372 | if force: | 
| @@ -298,46 +377,83 @@ class HobHandler(gobject.GObject): | |||
| 298 | # leave the workdir in a usable state | 377 | # leave the workdir in a usable state | 
| 299 | self.server.runCommand(["stateShutdown"]) | 378 | self.server.runCommand(["stateShutdown"]) | 
| 300 | 379 | ||
| 301 | def set_incompatible_license(self, incompatible): | 380 | def reset_server(self): | 
| 302 | self.server.runCommand(["setVariable", "INCOMPATIBLE_LICENSE", incompatible]) | 381 | self.server.runCommand(["resetCooker"]) | 
| 303 | 382 | ||
| 304 | def toggle_toolchain(self, enabled): | 383 | def reset_build(self): | 
| 305 | if self.build_toolchain != enabled: | 384 | self.build.reset() | 
| 306 | self.build_toolchain = enabled | 385 | |
| 307 | 386 | def get_parameters(self): | |
| 308 | def toggle_toolchain_headers(self, enabled): | 387 | # retrieve the parameters from bitbake | 
| 309 | if self.build_toolchain_headers != enabled: | 388 | params = {} | 
| 310 | self.build_toolchain_headers = enabled | 389 | params["core_base"] = self.server.runCommand(["getVariable", "COREBASE"]) or "" | 
| 311 | 390 | hob_layer = params["core_base"] + "/meta-hob" | |
| 312 | def set_fstypes(self, fstypes): | 391 | params["layer"] = (self.server.runCommand(["getVariable", "BBLAYERS"]) or "") + " " + hob_layer | 
| 313 | self.server.runCommand(["setVariable", "IMAGE_FSTYPES", fstypes]) | 392 | params["dldir"] = self.server.runCommand(["getVariable", "DL_DIR"]) or "" | 
| 314 | 393 | params["machine"] = self.server.runCommand(["getVariable", "MACHINE"]) or "" | |
| 315 | def add_image_output_type(self, output_type): | 394 | params["distro"] = self.server.runCommand(["getVariable", "DISTRO"]) or "defaultsetup" | 
| 316 | if output_type not in self.image_output_types: | 395 | params["pclass"] = self.server.runCommand(["getVariable", "PACKAGE_CLASSES"]) or "" | 
| 317 | self.image_output_types.append(output_type) | 396 | params["sstatedir"] = self.server.runCommand(["getVariable", "SSTATE_DIR"]) or "" | 
| 318 | fstypes = " ".join(self.image_output_types).lstrip(" ") | 397 | params["sstatemirror"] = self.server.runCommand(["getVariable", "SSTATE_MIRROR"]) or "" | 
| 319 | self.set_fstypes(fstypes) | 398 | |
| 320 | return self.image_output_types | 399 | num_threads = self.server.runCommand(["getCpuCount"]) | 
| 321 | 400 | if not num_threads: | |
| 322 | def remove_image_output_type(self, output_type): | 401 | num_threads = 1 | 
| 323 | if output_type in self.image_output_types: | 402 | max_threads = 65536 | 
| 324 | ind = self.image_output_types.index(output_type) | 403 | else: | 
| 325 | self.image_output_types.pop(ind) | 404 | num_threads = int(num_threads) | 
| 326 | fstypes = " ".join(self.image_output_types).lstrip(" ") | 405 | max_threads = 16 * num_threads | 
| 327 | self.set_fstypes(fstypes) | 406 | params["max_threads"] = max_threads | 
| 328 | return self.image_output_types | 407 | |
| 329 | 408 | bbthread = self.server.runCommand(["getVariable", "BB_NUMBER_THREADS"]) | |
| 330 | def get_image_deploy_dir(self): | 409 | if not bbthread: | 
| 331 | return self.image_out_dir | 410 | bbthread = num_threads | 
| 332 | 411 | else: | |
| 333 | def make_temp_dir(self): | 412 | bbthread = int(bbthread) | 
| 334 | bb.utils.mkdirhier(self.image_dir) | 413 | params["bbthread"] = bbthread | 
| 335 | 414 | ||
| 336 | def remove_temp_dir(self): | 415 | pmake = self.server.runCommand(["getVariable", "PARALLEL_MAKE"]) | 
| 337 | bb.utils.remove(self.image_dir, True) | 416 | if not pmake: | 
| 338 | 417 | pmake = num_threads | |
| 339 | def get_temp_recipe_path(self, name): | 418 | elif isinstance(pmake, int): | 
| 340 | timestamp = datetime.date.today().isoformat() | 419 | pass | 
| 341 | image_file = "hob-%s-variant-%s.bb" % (name, timestamp) | 420 | else: | 
| 342 | recipepath = os.path.join(self.image_dir, image_file) | 421 | pmake = int(pmake.lstrip("-j ")) | 
| 343 | return recipepath | 422 | params["pmake"] = pmake | 
| 423 | |||
| 424 | image_addr = self.server.runCommand(["getVariable", "DEPLOY_DIR_IMAGE"]) or "" | ||
| 425 | if self.server_addr: | ||
| 426 | image_addr = "http://" + self.server_addr + ":" + image_addr | ||
| 427 | params["image_addr"] = image_addr | ||
| 428 | |||
| 429 | image_extra_size = self.server.runCommand(["getVariable", "IMAGE_ROOTFS_EXTRA_SPACE"]) | ||
| 430 | if not image_extra_size: | ||
| 431 | image_extra_size = 0 | ||
| 432 | else: | ||
| 433 | image_extra_size = int(image_extra_size) | ||
| 434 | params["image_extra_size"] = image_extra_size | ||
| 435 | |||
| 436 | image_rootfs_size = self.server.runCommand(["getVariable", "IMAGE_ROOTFS_SIZE"]) | ||
| 437 | if not image_rootfs_size: | ||
| 438 | image_rootfs_size = 0 | ||
| 439 | else: | ||
| 440 | image_rootfs_size = int(image_rootfs_size) | ||
| 441 | params["image_rootfs_size"] = image_rootfs_size | ||
| 442 | |||
| 443 | image_overhead_factor = self.server.runCommand(["getVariable", "IMAGE_OVERHEAD_FACTOR"]) | ||
| 444 | if not image_overhead_factor: | ||
| 445 | image_overhead_factor = 1 | ||
| 446 | else: | ||
| 447 | image_overhead_factor = float(image_overhead_factor) | ||
| 448 | params['image_overhead_factor'] = image_overhead_factor | ||
| 449 | |||
| 450 | params["incompat_license"] = self.server.runCommand(["getVariable", "INCOMPATIBLE_LICENSE"]) or "" | ||
| 451 | params["sdk_machine"] = self.server.runCommand(["getVariable", "SDKMACHINE"]) or self.server.runCommand(["getVariable", "SDK_ARCH"]) or "" | ||
| 452 | |||
| 453 | #params["image_types"] = self.server.runCommand(["getVariable", "IMAGE_TYPES"]) or "" | ||
| 454 | params["image_fstypes"] = self.server.runCommand(["getVariable", "IMAGE_FSTYPES"]) or "" | ||
| 455 | """ | ||
| 456 | A workaround | ||
| 457 | """ | ||
| 458 | params["image_types"] = "jffs2 sum.jffs2 cramfs ext2 ext2.gz ext2.bz2 ext3 ext3.gz ext2.lzma btrfs live squashfs squashfs-lzma ubi tar tar.gz tar.bz2 tar.xz cpio cpio.gz cpio.xz cpio.lzma" | ||
| 459 | return params | ||
