blob: ffbaf362e8834b94430bc38309fada2e7732709c [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001"""
2BitBake 'TaskData' implementation
3
4Task data collection and handling
5
6"""
7
8# Copyright (C) 2006 Richard Purdie
9#
Brad Bishopc342db32019-05-15 21:57:59 -040010# SPDX-License-Identifier: GPL-2.0-only
Patrick Williamsc124f4f2015-09-15 14:41:29 -050011#
Patrick Williamsc124f4f2015-09-15 14:41:29 -050012
13import logging
14import re
15import bb
16
17logger = logging.getLogger("BitBake.TaskData")
18
19def re_match_strings(target, strings):
20 """
21 Whether or not the string 'target' matches
22 any one string of the strings which can be regular expression string
23 """
Andrew Geissler475cb722020-07-10 16:00:51 -050024 for name in strings:
25 if name.startswith("^") or name.endswith("$"):
26 if re.match(name, target):
27 return True
28 elif name == target:
29 return True
30 return False
Patrick Williamsc124f4f2015-09-15 14:41:29 -050031
Patrick Williamsc0f7c042017-02-23 20:41:17 -060032class TaskEntry:
33 def __init__(self):
34 self.tdepends = []
35 self.idepends = []
36 self.irdepends = []
37
Patrick Williamsc124f4f2015-09-15 14:41:29 -050038class TaskData:
39 """
40 BitBake Task Data implementation
41 """
Brad Bishopd7bf8c12018-02-25 22:55:05 -050042 def __init__(self, abort = True, skiplist = None, allowincomplete = False):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050043 self.build_targets = {}
44 self.run_targets = {}
45
46 self.external_targets = []
47
Patrick Williamsc0f7c042017-02-23 20:41:17 -060048 self.seenfns = []
49 self.taskentries = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -050050
51 self.depids = {}
52 self.rdepids = {}
53
54 self.consider_msgs_cache = []
55
56 self.failed_deps = []
57 self.failed_rdeps = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -060058 self.failed_fns = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -050059
60 self.abort = abort
Patrick Williamsc124f4f2015-09-15 14:41:29 -050061 self.allowincomplete = allowincomplete
62
63 self.skiplist = skiplist
64
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080065 self.mcdepends = []
66
Patrick Williamsc124f4f2015-09-15 14:41:29 -050067 def add_tasks(self, fn, dataCache):
68 """
69 Add tasks for a given fn to the database
70 """
71
72 task_deps = dataCache.task_deps[fn]
73
Patrick Williamsc0f7c042017-02-23 20:41:17 -060074 if fn in self.failed_fns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050075 bb.msg.fatal("TaskData", "Trying to re-add a failed file? Something is broken...")
76
77 # Check if we've already seen this fn
Patrick Williamsc0f7c042017-02-23 20:41:17 -060078 if fn in self.seenfns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050079 return
80
Patrick Williamsc0f7c042017-02-23 20:41:17 -060081 self.seenfns.append(fn)
82
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050083 self.add_extra_deps(fn, dataCache)
84
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080085 def add_mcdepends(task):
86 for dep in task_deps['mcdepends'][task].split():
87 if len(dep.split(':')) != 5:
Brad Bishop15ae2502019-06-18 21:44:24 -040088 bb.msg.fatal("TaskData", "Error for %s:%s[%s], multiconfig dependency %s does not contain exactly four ':' characters.\n Task '%s' should be specified in the form 'mc:fromMC:toMC:packagename:task'" % (fn, task, 'mcdepends', dep, 'mcdepends'))
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080089 if dep not in self.mcdepends:
90 self.mcdepends.append(dep)
91
Brad Bishop6e60e8b2018-02-01 10:27:11 -050092 # Common code for dep_name/depends = 'depends'/idepends and 'rdepends'/irdepends
93 def handle_deps(task, dep_name, depends, seen):
94 if dep_name in task_deps and task in task_deps[dep_name]:
95 ids = []
96 for dep in task_deps[dep_name][task].split():
97 if dep:
98 parts = dep.split(":")
99 if len(parts) != 2:
100 bb.msg.fatal("TaskData", "Error for %s:%s[%s], dependency %s in '%s' does not contain exactly one ':' character.\n Task '%s' should be specified in the form 'packagename:task'" % (fn, task, dep_name, dep, task_deps[dep_name][task], dep_name))
101 ids.append((parts[0], parts[1]))
102 seen(parts[0])
103 depends.extend(ids)
104
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500105 for task in task_deps['tasks']:
106
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600107 tid = "%s:%s" % (fn, task)
108 self.taskentries[tid] = TaskEntry()
109
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500110 # Work out task dependencies
111 parentids = []
112 for dep in task_deps['parents'][task]:
113 if dep not in task_deps['tasks']:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800114 bb.debug(2, "Not adding dependency of %s on %s since %s does not exist" % (task, dep, dep))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500115 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600116 parentid = "%s:%s" % (fn, dep)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500117 parentids.append(parentid)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600118 self.taskentries[tid].tdepends.extend(parentids)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500119
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800120
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500121 # Touch all intertask dependencies
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500122 handle_deps(task, 'depends', self.taskentries[tid].idepends, self.seen_build_target)
123 handle_deps(task, 'rdepends', self.taskentries[tid].irdepends, self.seen_run_target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500124
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800125 if 'mcdepends' in task_deps and task in task_deps['mcdepends']:
126 add_mcdepends(task)
127
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500128 # Work out build dependencies
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600129 if not fn in self.depids:
130 dependids = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500131 for depend in dataCache.deps[fn]:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600132 dependids.add(depend)
133 self.depids[fn] = list(dependids)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500134 logger.debug(2, "Added dependencies %s for %s", str(dataCache.deps[fn]), fn)
135
136 # Work out runtime dependencies
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600137 if not fn in self.rdepids:
138 rdependids = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500139 rdepends = dataCache.rundeps[fn]
140 rrecs = dataCache.runrecs[fn]
141 rdependlist = []
142 rreclist = []
143 for package in rdepends:
144 for rdepend in rdepends[package]:
145 rdependlist.append(rdepend)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600146 rdependids.add(rdepend)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500147 for package in rrecs:
148 for rdepend in rrecs[package]:
149 rreclist.append(rdepend)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600150 rdependids.add(rdepend)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500151 if rdependlist:
152 logger.debug(2, "Added runtime dependencies %s for %s", str(rdependlist), fn)
153 if rreclist:
154 logger.debug(2, "Added runtime recommendations %s for %s", str(rreclist), fn)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600155 self.rdepids[fn] = list(rdependids)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500156
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600157 for dep in self.depids[fn]:
158 self.seen_build_target(dep)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500159 if dep in self.failed_deps:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600160 self.fail_fn(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500161 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600162 for dep in self.rdepids[fn]:
163 self.seen_run_target(dep)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500164 if dep in self.failed_rdeps:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600165 self.fail_fn(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500166 return
167
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500168 def add_extra_deps(self, fn, dataCache):
169 func = dataCache.extradepsfunc.get(fn, None)
170 if func:
171 bb.providers.buildWorldTargetList(dataCache)
172 pn = dataCache.pkg_fn[fn]
173 params = {'deps': dataCache.deps[fn],
174 'world_target': dataCache.world_target,
175 'pkg_pn': dataCache.pkg_pn,
176 'self_pn': pn}
177 funcname = '_%s_calculate_extra_depends' % pn.replace('-', '_')
178 paramlist = ','.join(params.keys())
179 func = 'def %s(%s):\n%s\n\n%s(%s)' % (funcname, paramlist, func, funcname, paramlist)
180 bb.utils.better_exec(func, params)
181
182
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500183 def have_build_target(self, target):
184 """
185 Have we a build target matching this name?
186 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600187 if target in self.build_targets and self.build_targets[target]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500188 return True
189 return False
190
191 def have_runtime_target(self, target):
192 """
193 Have we a runtime target matching this name?
194 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600195 if target in self.run_targets and self.run_targets[target]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500196 return True
197 return False
198
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600199 def seen_build_target(self, name):
200 """
201 Maintain a list of build targets
202 """
203 if name not in self.build_targets:
204 self.build_targets[name] = []
205
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500206 def add_build_target(self, fn, item):
207 """
208 Add a build target.
209 If already present, append the provider fn to the list
210 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600211 if item in self.build_targets:
212 if fn in self.build_targets[item]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500213 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600214 self.build_targets[item].append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500215 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600216 self.build_targets[item] = [fn]
217
218 def seen_run_target(self, name):
219 """
220 Maintain a list of runtime build targets
221 """
222 if name not in self.run_targets:
223 self.run_targets[name] = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500224
225 def add_runtime_target(self, fn, item):
226 """
227 Add a runtime target.
228 If already present, append the provider fn to the list
229 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600230 if item in self.run_targets:
231 if fn in self.run_targets[item]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500232 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600233 self.run_targets[item].append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500234 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600235 self.run_targets[item] = [fn]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500236
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600237 def mark_external_target(self, target):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500238 """
239 Mark a build target as being externally requested
240 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600241 if target not in self.external_targets:
242 self.external_targets.append(target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500243
244 def get_unresolved_build_targets(self, dataCache):
245 """
246 Return a list of build targets who's providers
247 are unknown.
248 """
249 unresolved = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600250 for target in self.build_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500251 if re_match_strings(target, dataCache.ignored_dependencies):
252 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600253 if target in self.failed_deps:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500254 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600255 if not self.build_targets[target]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500256 unresolved.append(target)
257 return unresolved
258
259 def get_unresolved_run_targets(self, dataCache):
260 """
261 Return a list of runtime targets who's providers
262 are unknown.
263 """
264 unresolved = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600265 for target in self.run_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500266 if re_match_strings(target, dataCache.ignored_dependencies):
267 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600268 if target in self.failed_rdeps:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500269 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600270 if not self.run_targets[target]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500271 unresolved.append(target)
272 return unresolved
273
274 def get_provider(self, item):
275 """
276 Return a list of providers of item
277 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600278 return self.build_targets[item]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500279
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600280 def get_dependees(self, item):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500281 """
282 Return a list of targets which depend on item
283 """
284 dependees = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600285 for fn in self.depids:
286 if item in self.depids[fn]:
287 dependees.append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500288 return dependees
289
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600290 def get_rdependees(self, item):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500291 """
292 Return a list of targets which depend on runtime item
293 """
294 dependees = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600295 for fn in self.rdepids:
296 if item in self.rdepids[fn]:
297 dependees.append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500298 return dependees
299
300 def get_reasons(self, item, runtime=False):
301 """
302 Get the reason(s) for an item not being provided, if any
303 """
304 reasons = []
305 if self.skiplist:
306 for fn in self.skiplist:
307 skipitem = self.skiplist[fn]
308 if skipitem.pn == item:
309 reasons.append("%s was skipped: %s" % (skipitem.pn, skipitem.skipreason))
310 elif runtime and item in skipitem.rprovides:
311 reasons.append("%s RPROVIDES %s but was skipped: %s" % (skipitem.pn, item, skipitem.skipreason))
312 elif not runtime and item in skipitem.provides:
313 reasons.append("%s PROVIDES %s but was skipped: %s" % (skipitem.pn, item, skipitem.skipreason))
314 return reasons
315
316 def get_close_matches(self, item, provider_list):
317 import difflib
318 if self.skiplist:
319 skipped = []
320 for fn in self.skiplist:
321 skipped.append(self.skiplist[fn].pn)
322 full_list = provider_list + skipped
323 else:
324 full_list = provider_list
325 return difflib.get_close_matches(item, full_list, cutoff=0.7)
326
327 def add_provider(self, cfgData, dataCache, item):
328 try:
329 self.add_provider_internal(cfgData, dataCache, item)
330 except bb.providers.NoProvider:
331 if self.abort:
332 raise
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600333 self.remove_buildtarget(item)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500334
335 self.mark_external_target(item)
336
337 def add_provider_internal(self, cfgData, dataCache, item):
338 """
339 Add the providers of item to the task data
340 Mark entries were specifically added externally as against dependencies
341 added internally during dependency resolution
342 """
343
344 if re_match_strings(item, dataCache.ignored_dependencies):
345 return
346
347 if not item in dataCache.providers:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600348 close_matches = self.get_close_matches(item, list(dataCache.providers.keys()))
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500349 # Is it in RuntimeProviders ?
350 all_p = bb.providers.getRuntimeProviders(dataCache, item)
351 for fn in all_p:
352 new = dataCache.pkg_fn[fn] + " RPROVIDES " + item
353 if new not in close_matches:
354 close_matches.append(new)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600355 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 -0500356 raise bb.providers.NoProvider(item)
357
358 if self.have_build_target(item):
359 return
360
361 all_p = dataCache.providers[item]
362
363 eligible, foundUnique = bb.providers.filterProviders(all_p, item, cfgData, dataCache)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600364 eligible = [p for p in eligible if not p in self.failed_fns]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500365
366 if not eligible:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600367 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 -0500368 raise bb.providers.NoProvider(item)
369
Andrew Geissler82c905d2020-04-13 13:39:40 -0500370 if len(eligible) > 1 and not foundUnique:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500371 if item not in self.consider_msgs_cache:
372 providers_list = []
373 for fn in eligible:
374 providers_list.append(dataCache.pkg_fn[fn])
375 bb.event.fire(bb.event.MultipleProviders(item, providers_list), cfgData)
376 self.consider_msgs_cache.append(item)
377
378 for fn in eligible:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600379 if fn in self.failed_fns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500380 continue
381 logger.debug(2, "adding %s to satisfy %s", fn, item)
382 self.add_build_target(fn, item)
383 self.add_tasks(fn, dataCache)
384
385
386 #item = dataCache.pkg_fn[fn]
387
388 def add_rprovider(self, cfgData, dataCache, item):
389 """
390 Add the runtime providers of item to the task data
391 (takes item names from RDEPENDS/PACKAGES namespace)
392 """
393
394 if re_match_strings(item, dataCache.ignored_dependencies):
395 return
396
397 if self.have_runtime_target(item):
398 return
399
400 all_p = bb.providers.getRuntimeProviders(dataCache, item)
401
402 if not all_p:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600403 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 -0500404 raise bb.providers.NoRProvider(item)
405
406 eligible, numberPreferred = bb.providers.filterProvidersRunTime(all_p, item, cfgData, dataCache)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600407 eligible = [p for p in eligible if not p in self.failed_fns]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500408
409 if not eligible:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600410 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 -0500411 raise bb.providers.NoRProvider(item)
412
413 if len(eligible) > 1 and numberPreferred == 0:
414 if item not in self.consider_msgs_cache:
415 providers_list = []
416 for fn in eligible:
417 providers_list.append(dataCache.pkg_fn[fn])
418 bb.event.fire(bb.event.MultipleProviders(item, providers_list, runtime=True), cfgData)
419 self.consider_msgs_cache.append(item)
420
421 if numberPreferred > 1:
422 if item not in self.consider_msgs_cache:
423 providers_list = []
424 for fn in eligible:
425 providers_list.append(dataCache.pkg_fn[fn])
426 bb.event.fire(bb.event.MultipleProviders(item, providers_list, runtime=True), cfgData)
427 self.consider_msgs_cache.append(item)
428 raise bb.providers.MultipleRProvider(item)
429
430 # run through the list until we find one that we can build
431 for fn in eligible:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600432 if fn in self.failed_fns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500433 continue
434 logger.debug(2, "adding '%s' to satisfy runtime '%s'", fn, item)
435 self.add_runtime_target(fn, item)
436 self.add_tasks(fn, dataCache)
437
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600438 def fail_fn(self, fn, missing_list=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500439 """
440 Mark a file as failed (unbuildable)
441 Remove any references from build and runtime provider lists
442
443 missing_list, A list of missing requirements for this target
444 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600445 if fn in self.failed_fns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500446 return
447 if not missing_list:
448 missing_list = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600449 logger.debug(1, "File '%s' is unbuildable, removing...", fn)
450 self.failed_fns.append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500451 for target in self.build_targets:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600452 if fn in self.build_targets[target]:
453 self.build_targets[target].remove(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500454 if len(self.build_targets[target]) == 0:
455 self.remove_buildtarget(target, missing_list)
456 for target in self.run_targets:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600457 if fn in self.run_targets[target]:
458 self.run_targets[target].remove(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500459 if len(self.run_targets[target]) == 0:
460 self.remove_runtarget(target, missing_list)
461
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600462 def remove_buildtarget(self, target, missing_list=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500463 """
464 Mark a build target as failed (unbuildable)
465 Trigger removal of any files that have this as a dependency
466 """
467 if not missing_list:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600468 missing_list = [target]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500469 else:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600470 missing_list = [target] + missing_list
471 logger.verbose("Target '%s' is unbuildable, removing...\nMissing or unbuildable dependency chain was: %s", target, missing_list)
472 self.failed_deps.append(target)
473 dependees = self.get_dependees(target)
474 for fn in dependees:
475 self.fail_fn(fn, missing_list)
476 for tid in self.taskentries:
477 for (idepend, idependtask) in self.taskentries[tid].idepends:
478 if idepend == target:
479 fn = tid.rsplit(":",1)[0]
480 self.fail_fn(fn, missing_list)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500481
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600482 if self.abort and target in self.external_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500483 logger.error("Required build target '%s' has no buildable providers.\nMissing or unbuildable dependency chain was: %s", target, missing_list)
484 raise bb.providers.NoProvider(target)
485
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600486 def remove_runtarget(self, target, missing_list=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500487 """
488 Mark a run target as failed (unbuildable)
489 Trigger removal of any files that have this as a dependency
490 """
491 if not missing_list:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600492 missing_list = [target]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500493 else:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600494 missing_list = [target] + missing_list
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500495
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600496 logger.info("Runtime target '%s' is unbuildable, removing...\nMissing or unbuildable dependency chain was: %s", target, missing_list)
497 self.failed_rdeps.append(target)
498 dependees = self.get_rdependees(target)
499 for fn in dependees:
500 self.fail_fn(fn, missing_list)
501 for tid in self.taskentries:
502 for (idepend, idependtask) in self.taskentries[tid].irdepends:
503 if idepend == target:
504 fn = tid.rsplit(":",1)[0]
505 self.fail_fn(fn, missing_list)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500506
507 def add_unresolved(self, cfgData, dataCache):
508 """
509 Resolve all unresolved build and runtime targets
510 """
511 logger.info("Resolving any missing task queue dependencies")
512 while True:
513 added = 0
514 for target in self.get_unresolved_build_targets(dataCache):
515 try:
516 self.add_provider_internal(cfgData, dataCache, target)
517 added = added + 1
518 except bb.providers.NoProvider:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600519 if self.abort and target in self.external_targets and not self.allowincomplete:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500520 raise
521 if not self.allowincomplete:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600522 self.remove_buildtarget(target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500523 for target in self.get_unresolved_run_targets(dataCache):
524 try:
525 self.add_rprovider(cfgData, dataCache, target)
526 added = added + 1
527 except (bb.providers.NoRProvider, bb.providers.MultipleRProvider):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600528 self.remove_runtarget(target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500529 logger.debug(1, "Resolved " + str(added) + " extra dependencies")
530 if added == 0:
531 break
532 # self.dump_data()
533
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500534 def get_providermap(self, prefix=None):
535 provmap = {}
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600536 for name in self.build_targets:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500537 if prefix and not name.startswith(prefix):
538 continue
539 if self.have_build_target(name):
540 provider = self.get_provider(name)
541 if provider:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600542 provmap[name] = provider[0]
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500543 return provmap
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500544
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800545 def get_mcdepends(self):
546 return self.mcdepends
547
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500548 def dump_data(self):
549 """
550 Dump some debug information on the internal data structures
551 """
552 logger.debug(3, "build_names:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600553 logger.debug(3, ", ".join(self.build_targets))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500554
555 logger.debug(3, "run_names:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600556 logger.debug(3, ", ".join(self.run_targets))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500557
558 logger.debug(3, "build_targets:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600559 for target in self.build_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500560 targets = "None"
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600561 if target in self.build_targets:
562 targets = self.build_targets[target]
563 logger.debug(3, " %s: %s", target, targets)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500564
565 logger.debug(3, "run_targets:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600566 for target in self.run_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500567 targets = "None"
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600568 if target in self.run_targets:
569 targets = self.run_targets[target]
570 logger.debug(3, " %s: %s", target, targets)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500571
572 logger.debug(3, "tasks:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600573 for tid in self.taskentries:
574 logger.debug(3, " %s: %s %s %s",
575 tid,
576 self.taskentries[tid].idepends,
577 self.taskentries[tid].irdepends,
578 self.taskentries[tid].tdepends)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500579
580 logger.debug(3, "dependency ids (per fn):")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600581 for fn in self.depids:
582 logger.debug(3, " %s: %s", fn, self.depids[fn])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500583
584 logger.debug(3, "runtime dependency ids (per fn):")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600585 for fn in self.rdepids:
586 logger.debug(3, " %s: %s", fn, self.rdepids[fn])