blob: d8bdbcabf999c8c470c896f02889aedbc237e5b4 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#!/usr/bin/env python
2# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4"""
5BitBake 'TaskData' implementation
6
7Task data collection and handling
8
9"""
10
11# Copyright (C) 2006 Richard Purdie
12#
13# This program is free software; you can redistribute it and/or modify
14# it under the terms of the GNU General Public License version 2 as
15# published by the Free Software Foundation.
16#
17# This program is distributed in the hope that it will be useful,
18# but WITHOUT ANY WARRANTY; without even the implied warranty of
19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20# GNU General Public License for more details.
21#
22# You should have received a copy of the GNU General Public License along
23# with this program; if not, write to the Free Software Foundation, Inc.,
24# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25
26import logging
27import re
28import bb
29
30logger = logging.getLogger("BitBake.TaskData")
31
32def re_match_strings(target, strings):
33 """
34 Whether or not the string 'target' matches
35 any one string of the strings which can be regular expression string
36 """
37 return any(name == target or re.match(name, target)
38 for name in strings)
39
Patrick Williamsc0f7c042017-02-23 20:41:17 -060040class TaskEntry:
41 def __init__(self):
42 self.tdepends = []
43 self.idepends = []
44 self.irdepends = []
45
Patrick Williamsc124f4f2015-09-15 14:41:29 -050046class TaskData:
47 """
48 BitBake Task Data implementation
49 """
50 def __init__(self, abort = True, tryaltconfigs = False, skiplist = None, allowincomplete = False):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050051 self.build_targets = {}
52 self.run_targets = {}
53
54 self.external_targets = []
55
Patrick Williamsc0f7c042017-02-23 20:41:17 -060056 self.seenfns = []
57 self.taskentries = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -050058
59 self.depids = {}
60 self.rdepids = {}
61
62 self.consider_msgs_cache = []
63
64 self.failed_deps = []
65 self.failed_rdeps = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -060066 self.failed_fns = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -050067
68 self.abort = abort
69 self.tryaltconfigs = tryaltconfigs
70 self.allowincomplete = allowincomplete
71
72 self.skiplist = skiplist
73
Patrick Williamsc124f4f2015-09-15 14:41:29 -050074 def add_tasks(self, fn, dataCache):
75 """
76 Add tasks for a given fn to the database
77 """
78
79 task_deps = dataCache.task_deps[fn]
80
Patrick Williamsc0f7c042017-02-23 20:41:17 -060081 if fn in self.failed_fns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050082 bb.msg.fatal("TaskData", "Trying to re-add a failed file? Something is broken...")
83
84 # Check if we've already seen this fn
Patrick Williamsc0f7c042017-02-23 20:41:17 -060085 if fn in self.seenfns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050086 return
87
Patrick Williamsc0f7c042017-02-23 20:41:17 -060088 self.seenfns.append(fn)
89
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050090 self.add_extra_deps(fn, dataCache)
91
Patrick Williamsc124f4f2015-09-15 14:41:29 -050092 for task in task_deps['tasks']:
93
Patrick Williamsc0f7c042017-02-23 20:41:17 -060094 tid = "%s:%s" % (fn, task)
95 self.taskentries[tid] = TaskEntry()
96
Patrick Williamsc124f4f2015-09-15 14:41:29 -050097 # Work out task dependencies
98 parentids = []
99 for dep in task_deps['parents'][task]:
100 if dep not in task_deps['tasks']:
101 bb.debug(2, "Not adding dependeny of %s on %s since %s does not exist" % (task, dep, dep))
102 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600103 parentid = "%s:%s" % (fn, dep)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500104 parentids.append(parentid)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600105 self.taskentries[tid].tdepends.extend(parentids)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500106
107 # Touch all intertask dependencies
108 if 'depends' in task_deps and task in task_deps['depends']:
109 ids = []
110 for dep in task_deps['depends'][task].split():
111 if dep:
112 if ":" not in dep:
113 bb.msg.fatal("TaskData", "Error for %s, dependency %s does not contain ':' character\n. Task 'depends' should be specified in the form 'packagename:task'" % (fn, dep))
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600114 ids.append(((dep.split(":")[0]), dep.split(":")[1]))
115 self.seen_build_target(dep.split(":")[0])
116 self.taskentries[tid].idepends.extend(ids)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500117 if 'rdepends' in task_deps and task in task_deps['rdepends']:
118 ids = []
119 for dep in task_deps['rdepends'][task].split():
120 if dep:
121 if ":" not in dep:
122 bb.msg.fatal("TaskData", "Error for %s, dependency %s does not contain ':' character\n. Task 'rdepends' should be specified in the form 'packagename:task'" % (fn, dep))
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600123 ids.append(((dep.split(":")[0]), dep.split(":")[1]))
124 self.seen_run_target(dep.split(":")[0])
125 self.taskentries[tid].irdepends.extend(ids)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500126
127 # Work out build dependencies
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600128 if not fn in self.depids:
129 dependids = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500130 for depend in dataCache.deps[fn]:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600131 dependids.add(depend)
132 self.depids[fn] = list(dependids)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500133 logger.debug(2, "Added dependencies %s for %s", str(dataCache.deps[fn]), fn)
134
135 # Work out runtime dependencies
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600136 if not fn in self.rdepids:
137 rdependids = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500138 rdepends = dataCache.rundeps[fn]
139 rrecs = dataCache.runrecs[fn]
140 rdependlist = []
141 rreclist = []
142 for package in rdepends:
143 for rdepend in rdepends[package]:
144 rdependlist.append(rdepend)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600145 rdependids.add(rdepend)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500146 for package in rrecs:
147 for rdepend in rrecs[package]:
148 rreclist.append(rdepend)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600149 rdependids.add(rdepend)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500150 if rdependlist:
151 logger.debug(2, "Added runtime dependencies %s for %s", str(rdependlist), fn)
152 if rreclist:
153 logger.debug(2, "Added runtime recommendations %s for %s", str(rreclist), fn)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600154 self.rdepids[fn] = list(rdependids)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500155
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600156 for dep in self.depids[fn]:
157 self.seen_build_target(dep)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500158 if dep in self.failed_deps:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600159 self.fail_fn(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500160 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600161 for dep in self.rdepids[fn]:
162 self.seen_run_target(dep)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500163 if dep in self.failed_rdeps:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600164 self.fail_fn(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500165 return
166
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500167 def add_extra_deps(self, fn, dataCache):
168 func = dataCache.extradepsfunc.get(fn, None)
169 if func:
170 bb.providers.buildWorldTargetList(dataCache)
171 pn = dataCache.pkg_fn[fn]
172 params = {'deps': dataCache.deps[fn],
173 'world_target': dataCache.world_target,
174 'pkg_pn': dataCache.pkg_pn,
175 'self_pn': pn}
176 funcname = '_%s_calculate_extra_depends' % pn.replace('-', '_')
177 paramlist = ','.join(params.keys())
178 func = 'def %s(%s):\n%s\n\n%s(%s)' % (funcname, paramlist, func, funcname, paramlist)
179 bb.utils.better_exec(func, params)
180
181
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500182 def have_build_target(self, target):
183 """
184 Have we a build target matching this name?
185 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600186 if target in self.build_targets and self.build_targets[target]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500187 return True
188 return False
189
190 def have_runtime_target(self, target):
191 """
192 Have we a runtime target matching this name?
193 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600194 if target in self.run_targets and self.run_targets[target]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500195 return True
196 return False
197
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600198 def seen_build_target(self, name):
199 """
200 Maintain a list of build targets
201 """
202 if name not in self.build_targets:
203 self.build_targets[name] = []
204
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500205 def add_build_target(self, fn, item):
206 """
207 Add a build target.
208 If already present, append the provider fn to the list
209 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600210 if item in self.build_targets:
211 if fn in self.build_targets[item]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500212 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600213 self.build_targets[item].append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500214 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600215 self.build_targets[item] = [fn]
216
217 def seen_run_target(self, name):
218 """
219 Maintain a list of runtime build targets
220 """
221 if name not in self.run_targets:
222 self.run_targets[name] = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500223
224 def add_runtime_target(self, fn, item):
225 """
226 Add a runtime target.
227 If already present, append the provider fn to the list
228 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600229 if item in self.run_targets:
230 if fn in self.run_targets[item]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500231 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600232 self.run_targets[item].append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500233 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600234 self.run_targets[item] = [fn]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500235
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600236 def mark_external_target(self, target):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500237 """
238 Mark a build target as being externally requested
239 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600240 if target not in self.external_targets:
241 self.external_targets.append(target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500242
243 def get_unresolved_build_targets(self, dataCache):
244 """
245 Return a list of build targets who's providers
246 are unknown.
247 """
248 unresolved = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600249 for target in self.build_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500250 if re_match_strings(target, dataCache.ignored_dependencies):
251 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600252 if target in self.failed_deps:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500253 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600254 if not self.build_targets[target]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500255 unresolved.append(target)
256 return unresolved
257
258 def get_unresolved_run_targets(self, dataCache):
259 """
260 Return a list of runtime targets who's providers
261 are unknown.
262 """
263 unresolved = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600264 for target in self.run_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500265 if re_match_strings(target, dataCache.ignored_dependencies):
266 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600267 if target in self.failed_rdeps:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500268 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600269 if not self.run_targets[target]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500270 unresolved.append(target)
271 return unresolved
272
273 def get_provider(self, item):
274 """
275 Return a list of providers of item
276 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600277 return self.build_targets[item]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500278
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600279 def get_dependees(self, item):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500280 """
281 Return a list of targets which depend on item
282 """
283 dependees = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600284 for fn in self.depids:
285 if item in self.depids[fn]:
286 dependees.append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500287 return dependees
288
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600289 def get_rdependees(self, item):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500290 """
291 Return a list of targets which depend on runtime item
292 """
293 dependees = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600294 for fn in self.rdepids:
295 if item in self.rdepids[fn]:
296 dependees.append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500297 return dependees
298
299 def get_reasons(self, item, runtime=False):
300 """
301 Get the reason(s) for an item not being provided, if any
302 """
303 reasons = []
304 if self.skiplist:
305 for fn in self.skiplist:
306 skipitem = self.skiplist[fn]
307 if skipitem.pn == item:
308 reasons.append("%s was skipped: %s" % (skipitem.pn, skipitem.skipreason))
309 elif runtime and item in skipitem.rprovides:
310 reasons.append("%s RPROVIDES %s but was skipped: %s" % (skipitem.pn, item, skipitem.skipreason))
311 elif not runtime and item in skipitem.provides:
312 reasons.append("%s PROVIDES %s but was skipped: %s" % (skipitem.pn, item, skipitem.skipreason))
313 return reasons
314
315 def get_close_matches(self, item, provider_list):
316 import difflib
317 if self.skiplist:
318 skipped = []
319 for fn in self.skiplist:
320 skipped.append(self.skiplist[fn].pn)
321 full_list = provider_list + skipped
322 else:
323 full_list = provider_list
324 return difflib.get_close_matches(item, full_list, cutoff=0.7)
325
326 def add_provider(self, cfgData, dataCache, item):
327 try:
328 self.add_provider_internal(cfgData, dataCache, item)
329 except bb.providers.NoProvider:
330 if self.abort:
331 raise
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600332 self.remove_buildtarget(item)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500333
334 self.mark_external_target(item)
335
336 def add_provider_internal(self, cfgData, dataCache, item):
337 """
338 Add the providers of item to the task data
339 Mark entries were specifically added externally as against dependencies
340 added internally during dependency resolution
341 """
342
343 if re_match_strings(item, dataCache.ignored_dependencies):
344 return
345
346 if not item in dataCache.providers:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600347 close_matches = self.get_close_matches(item, list(dataCache.providers.keys()))
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500348 # Is it in RuntimeProviders ?
349 all_p = bb.providers.getRuntimeProviders(dataCache, item)
350 for fn in all_p:
351 new = dataCache.pkg_fn[fn] + " RPROVIDES " + item
352 if new not in close_matches:
353 close_matches.append(new)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600354 bb.event.fire(bb.event.NoProvider(item, dependees=self.get_dependees(item), reasons=self.get_reasons(item), close_matches=close_matches), cfgData)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500355 raise bb.providers.NoProvider(item)
356
357 if self.have_build_target(item):
358 return
359
360 all_p = dataCache.providers[item]
361
362 eligible, foundUnique = bb.providers.filterProviders(all_p, item, cfgData, dataCache)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600363 eligible = [p for p in eligible if not p in self.failed_fns]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500364
365 if not eligible:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600366 bb.event.fire(bb.event.NoProvider(item, dependees=self.get_dependees(item), reasons=["No eligible PROVIDERs exist for '%s'" % item]), cfgData)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500367 raise bb.providers.NoProvider(item)
368
369 if len(eligible) > 1 and foundUnique == False:
370 if item not in self.consider_msgs_cache:
371 providers_list = []
372 for fn in eligible:
373 providers_list.append(dataCache.pkg_fn[fn])
374 bb.event.fire(bb.event.MultipleProviders(item, providers_list), cfgData)
375 self.consider_msgs_cache.append(item)
376
377 for fn in eligible:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600378 if fn in self.failed_fns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500379 continue
380 logger.debug(2, "adding %s to satisfy %s", fn, item)
381 self.add_build_target(fn, item)
382 self.add_tasks(fn, dataCache)
383
384
385 #item = dataCache.pkg_fn[fn]
386
387 def add_rprovider(self, cfgData, dataCache, item):
388 """
389 Add the runtime providers of item to the task data
390 (takes item names from RDEPENDS/PACKAGES namespace)
391 """
392
393 if re_match_strings(item, dataCache.ignored_dependencies):
394 return
395
396 if self.have_runtime_target(item):
397 return
398
399 all_p = bb.providers.getRuntimeProviders(dataCache, item)
400
401 if not all_p:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600402 bb.event.fire(bb.event.NoProvider(item, runtime=True, dependees=self.get_rdependees(item), reasons=self.get_reasons(item, True)), cfgData)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500403 raise bb.providers.NoRProvider(item)
404
405 eligible, numberPreferred = bb.providers.filterProvidersRunTime(all_p, item, cfgData, dataCache)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600406 eligible = [p for p in eligible if not p in self.failed_fns]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500407
408 if not eligible:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600409 bb.event.fire(bb.event.NoProvider(item, runtime=True, dependees=self.get_rdependees(item), reasons=["No eligible RPROVIDERs exist for '%s'" % item]), cfgData)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500410 raise bb.providers.NoRProvider(item)
411
412 if len(eligible) > 1 and numberPreferred == 0:
413 if item not in self.consider_msgs_cache:
414 providers_list = []
415 for fn in eligible:
416 providers_list.append(dataCache.pkg_fn[fn])
417 bb.event.fire(bb.event.MultipleProviders(item, providers_list, runtime=True), cfgData)
418 self.consider_msgs_cache.append(item)
419
420 if numberPreferred > 1:
421 if item not in self.consider_msgs_cache:
422 providers_list = []
423 for fn in eligible:
424 providers_list.append(dataCache.pkg_fn[fn])
425 bb.event.fire(bb.event.MultipleProviders(item, providers_list, runtime=True), cfgData)
426 self.consider_msgs_cache.append(item)
427 raise bb.providers.MultipleRProvider(item)
428
429 # run through the list until we find one that we can build
430 for fn in eligible:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600431 if fn in self.failed_fns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500432 continue
433 logger.debug(2, "adding '%s' to satisfy runtime '%s'", fn, item)
434 self.add_runtime_target(fn, item)
435 self.add_tasks(fn, dataCache)
436
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600437 def fail_fn(self, fn, missing_list=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500438 """
439 Mark a file as failed (unbuildable)
440 Remove any references from build and runtime provider lists
441
442 missing_list, A list of missing requirements for this target
443 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600444 if fn in self.failed_fns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500445 return
446 if not missing_list:
447 missing_list = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600448 logger.debug(1, "File '%s' is unbuildable, removing...", fn)
449 self.failed_fns.append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500450 for target in self.build_targets:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600451 if fn in self.build_targets[target]:
452 self.build_targets[target].remove(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500453 if len(self.build_targets[target]) == 0:
454 self.remove_buildtarget(target, missing_list)
455 for target in self.run_targets:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600456 if fn in self.run_targets[target]:
457 self.run_targets[target].remove(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500458 if len(self.run_targets[target]) == 0:
459 self.remove_runtarget(target, missing_list)
460
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600461 def remove_buildtarget(self, target, missing_list=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500462 """
463 Mark a build target as failed (unbuildable)
464 Trigger removal of any files that have this as a dependency
465 """
466 if not missing_list:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600467 missing_list = [target]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500468 else:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600469 missing_list = [target] + missing_list
470 logger.verbose("Target '%s' is unbuildable, removing...\nMissing or unbuildable dependency chain was: %s", target, missing_list)
471 self.failed_deps.append(target)
472 dependees = self.get_dependees(target)
473 for fn in dependees:
474 self.fail_fn(fn, missing_list)
475 for tid in self.taskentries:
476 for (idepend, idependtask) in self.taskentries[tid].idepends:
477 if idepend == target:
478 fn = tid.rsplit(":",1)[0]
479 self.fail_fn(fn, missing_list)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500480
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600481 if self.abort and target in self.external_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500482 logger.error("Required build target '%s' has no buildable providers.\nMissing or unbuildable dependency chain was: %s", target, missing_list)
483 raise bb.providers.NoProvider(target)
484
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600485 def remove_runtarget(self, target, missing_list=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500486 """
487 Mark a run target as failed (unbuildable)
488 Trigger removal of any files that have this as a dependency
489 """
490 if not missing_list:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600491 missing_list = [target]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500492 else:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600493 missing_list = [target] + missing_list
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500494
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600495 logger.info("Runtime target '%s' is unbuildable, removing...\nMissing or unbuildable dependency chain was: %s", target, missing_list)
496 self.failed_rdeps.append(target)
497 dependees = self.get_rdependees(target)
498 for fn in dependees:
499 self.fail_fn(fn, missing_list)
500 for tid in self.taskentries:
501 for (idepend, idependtask) in self.taskentries[tid].irdepends:
502 if idepend == target:
503 fn = tid.rsplit(":",1)[0]
504 self.fail_fn(fn, missing_list)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500505
506 def add_unresolved(self, cfgData, dataCache):
507 """
508 Resolve all unresolved build and runtime targets
509 """
510 logger.info("Resolving any missing task queue dependencies")
511 while True:
512 added = 0
513 for target in self.get_unresolved_build_targets(dataCache):
514 try:
515 self.add_provider_internal(cfgData, dataCache, target)
516 added = added + 1
517 except bb.providers.NoProvider:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600518 if self.abort and target in self.external_targets and not self.allowincomplete:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500519 raise
520 if not self.allowincomplete:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600521 self.remove_buildtarget(target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500522 for target in self.get_unresolved_run_targets(dataCache):
523 try:
524 self.add_rprovider(cfgData, dataCache, target)
525 added = added + 1
526 except (bb.providers.NoRProvider, bb.providers.MultipleRProvider):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600527 self.remove_runtarget(target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500528 logger.debug(1, "Resolved " + str(added) + " extra dependencies")
529 if added == 0:
530 break
531 # self.dump_data()
532
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500533 def get_providermap(self, prefix=None):
534 provmap = {}
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600535 for name in self.build_targets:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500536 if prefix and not name.startswith(prefix):
537 continue
538 if self.have_build_target(name):
539 provider = self.get_provider(name)
540 if provider:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600541 provmap[name] = provider[0]
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500542 return provmap
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500543
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500544 def dump_data(self):
545 """
546 Dump some debug information on the internal data structures
547 """
548 logger.debug(3, "build_names:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600549 logger.debug(3, ", ".join(self.build_targets))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500550
551 logger.debug(3, "run_names:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600552 logger.debug(3, ", ".join(self.run_targets))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500553
554 logger.debug(3, "build_targets:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600555 for target in self.build_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500556 targets = "None"
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600557 if target in self.build_targets:
558 targets = self.build_targets[target]
559 logger.debug(3, " %s: %s", target, targets)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500560
561 logger.debug(3, "run_targets:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600562 for target in self.run_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500563 targets = "None"
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600564 if target in self.run_targets:
565 targets = self.run_targets[target]
566 logger.debug(3, " %s: %s", target, targets)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500567
568 logger.debug(3, "tasks:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600569 for tid in self.taskentries:
570 logger.debug(3, " %s: %s %s %s",
571 tid,
572 self.taskentries[tid].idepends,
573 self.taskentries[tid].irdepends,
574 self.taskentries[tid].tdepends)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500575
576 logger.debug(3, "dependency ids (per fn):")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600577 for fn in self.depids:
578 logger.debug(3, " %s: %s", fn, self.depids[fn])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500579
580 logger.debug(3, "runtime dependency ids (per fn):")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600581 for fn in self.rdepids:
582 logger.debug(3, " %s: %s", fn, self.rdepids[fn])