summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/ui/crumbs/hobeventhandler.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/ui/crumbs/hobeventhandler.py')
-rw-r--r--bitbake/lib/bb/ui/crumbs/hobeventhandler.py586
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
21import gobject 22import gobject
22import logging 23import logging
23import tempfile 24from bb.ui.crumbs.runningbuild import RunningBuild
24import datetime
25
26progress_total = 0
27 25
28class HobHandler(gobject.GObject): 26class 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