blob: d13bd7c3bff08ad80dd0a0868e32466437eab4b7 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001#!/usr/bin/env python
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002"""
3BitBake 'TaskData' implementation
4
5Task data collection and handling
6
7"""
8
9# Copyright (C) 2006 Richard Purdie
10#
Brad Bishopc342db32019-05-15 21:57:59 -040011# SPDX-License-Identifier: GPL-2.0-only
Patrick Williamsc124f4f2015-09-15 14:41:29 -050012#
Patrick Williamsc124f4f2015-09-15 14:41:29 -050013
14import logging
15import re
16import bb
17
18logger = logging.getLogger("BitBake.TaskData")
19
20def re_match_strings(target, strings):
21 """
22 Whether or not the string 'target' matches
23 any one string of the strings which can be regular expression string
24 """
25 return any(name == target or re.match(name, target)
26 for name in strings)
27
Patrick Williamsc0f7c042017-02-23 20:41:17 -060028class TaskEntry:
29 def __init__(self):
30 self.tdepends = []
31 self.idepends = []
32 self.irdepends = []
33
Patrick Williamsc124f4f2015-09-15 14:41:29 -050034class TaskData:
35 """
36 BitBake Task Data implementation
37 """
Brad Bishopd7bf8c12018-02-25 22:55:05 -050038 def __init__(self, abort = True, skiplist = None, allowincomplete = False):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050039 self.build_targets = {}
40 self.run_targets = {}
41
42 self.external_targets = []
43
Patrick Williamsc0f7c042017-02-23 20:41:17 -060044 self.seenfns = []
45 self.taskentries = {}
Patrick Williamsc124f4f2015-09-15 14:41:29 -050046
47 self.depids = {}
48 self.rdepids = {}
49
50 self.consider_msgs_cache = []
51
52 self.failed_deps = []
53 self.failed_rdeps = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -060054 self.failed_fns = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -050055
56 self.abort = abort
Patrick Williamsc124f4f2015-09-15 14:41:29 -050057 self.allowincomplete = allowincomplete
58
59 self.skiplist = skiplist
60
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080061 self.mcdepends = []
62
Patrick Williamsc124f4f2015-09-15 14:41:29 -050063 def add_tasks(self, fn, dataCache):
64 """
65 Add tasks for a given fn to the database
66 """
67
68 task_deps = dataCache.task_deps[fn]
69
Patrick Williamsc0f7c042017-02-23 20:41:17 -060070 if fn in self.failed_fns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050071 bb.msg.fatal("TaskData", "Trying to re-add a failed file? Something is broken...")
72
73 # Check if we've already seen this fn
Patrick Williamsc0f7c042017-02-23 20:41:17 -060074 if fn in self.seenfns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050075 return
76
Patrick Williamsc0f7c042017-02-23 20:41:17 -060077 self.seenfns.append(fn)
78
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050079 self.add_extra_deps(fn, dataCache)
80
Brad Bishop1a4b7ee2018-12-16 17:11:34 -080081 def add_mcdepends(task):
82 for dep in task_deps['mcdepends'][task].split():
83 if len(dep.split(':')) != 5:
Brad Bishop15ae2502019-06-18 21:44:24 -040084 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 -080085 if dep not in self.mcdepends:
86 self.mcdepends.append(dep)
87
Brad Bishop6e60e8b2018-02-01 10:27:11 -050088 # Common code for dep_name/depends = 'depends'/idepends and 'rdepends'/irdepends
89 def handle_deps(task, dep_name, depends, seen):
90 if dep_name in task_deps and task in task_deps[dep_name]:
91 ids = []
92 for dep in task_deps[dep_name][task].split():
93 if dep:
94 parts = dep.split(":")
95 if len(parts) != 2:
96 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))
97 ids.append((parts[0], parts[1]))
98 seen(parts[0])
99 depends.extend(ids)
100
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500101 for task in task_deps['tasks']:
102
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600103 tid = "%s:%s" % (fn, task)
104 self.taskentries[tid] = TaskEntry()
105
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500106 # Work out task dependencies
107 parentids = []
108 for dep in task_deps['parents'][task]:
109 if dep not in task_deps['tasks']:
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800110 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 -0500111 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600112 parentid = "%s:%s" % (fn, dep)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500113 parentids.append(parentid)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600114 self.taskentries[tid].tdepends.extend(parentids)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500115
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800116
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500117 # Touch all intertask dependencies
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500118 handle_deps(task, 'depends', self.taskentries[tid].idepends, self.seen_build_target)
119 handle_deps(task, 'rdepends', self.taskentries[tid].irdepends, self.seen_run_target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500120
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800121 if 'mcdepends' in task_deps and task in task_deps['mcdepends']:
122 add_mcdepends(task)
123
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500124 # Work out build dependencies
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600125 if not fn in self.depids:
126 dependids = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500127 for depend in dataCache.deps[fn]:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600128 dependids.add(depend)
129 self.depids[fn] = list(dependids)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500130 logger.debug(2, "Added dependencies %s for %s", str(dataCache.deps[fn]), fn)
131
132 # Work out runtime dependencies
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600133 if not fn in self.rdepids:
134 rdependids = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500135 rdepends = dataCache.rundeps[fn]
136 rrecs = dataCache.runrecs[fn]
137 rdependlist = []
138 rreclist = []
139 for package in rdepends:
140 for rdepend in rdepends[package]:
141 rdependlist.append(rdepend)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600142 rdependids.add(rdepend)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500143 for package in rrecs:
144 for rdepend in rrecs[package]:
145 rreclist.append(rdepend)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600146 rdependids.add(rdepend)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500147 if rdependlist:
148 logger.debug(2, "Added runtime dependencies %s for %s", str(rdependlist), fn)
149 if rreclist:
150 logger.debug(2, "Added runtime recommendations %s for %s", str(rreclist), fn)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600151 self.rdepids[fn] = list(rdependids)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500152
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600153 for dep in self.depids[fn]:
154 self.seen_build_target(dep)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500155 if dep in self.failed_deps:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600156 self.fail_fn(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500157 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600158 for dep in self.rdepids[fn]:
159 self.seen_run_target(dep)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500160 if dep in self.failed_rdeps:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600161 self.fail_fn(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500162 return
163
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500164 def add_extra_deps(self, fn, dataCache):
165 func = dataCache.extradepsfunc.get(fn, None)
166 if func:
167 bb.providers.buildWorldTargetList(dataCache)
168 pn = dataCache.pkg_fn[fn]
169 params = {'deps': dataCache.deps[fn],
170 'world_target': dataCache.world_target,
171 'pkg_pn': dataCache.pkg_pn,
172 'self_pn': pn}
173 funcname = '_%s_calculate_extra_depends' % pn.replace('-', '_')
174 paramlist = ','.join(params.keys())
175 func = 'def %s(%s):\n%s\n\n%s(%s)' % (funcname, paramlist, func, funcname, paramlist)
176 bb.utils.better_exec(func, params)
177
178
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500179 def have_build_target(self, target):
180 """
181 Have we a build target matching this name?
182 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600183 if target in self.build_targets and self.build_targets[target]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500184 return True
185 return False
186
187 def have_runtime_target(self, target):
188 """
189 Have we a runtime target matching this name?
190 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600191 if target in self.run_targets and self.run_targets[target]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500192 return True
193 return False
194
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600195 def seen_build_target(self, name):
196 """
197 Maintain a list of build targets
198 """
199 if name not in self.build_targets:
200 self.build_targets[name] = []
201
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500202 def add_build_target(self, fn, item):
203 """
204 Add a build target.
205 If already present, append the provider fn to the list
206 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600207 if item in self.build_targets:
208 if fn in self.build_targets[item]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500209 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600210 self.build_targets[item].append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500211 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600212 self.build_targets[item] = [fn]
213
214 def seen_run_target(self, name):
215 """
216 Maintain a list of runtime build targets
217 """
218 if name not in self.run_targets:
219 self.run_targets[name] = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500220
221 def add_runtime_target(self, fn, item):
222 """
223 Add a runtime target.
224 If already present, append the provider fn to the list
225 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600226 if item in self.run_targets:
227 if fn in self.run_targets[item]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500228 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600229 self.run_targets[item].append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500230 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600231 self.run_targets[item] = [fn]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500232
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600233 def mark_external_target(self, target):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500234 """
235 Mark a build target as being externally requested
236 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600237 if target not in self.external_targets:
238 self.external_targets.append(target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500239
240 def get_unresolved_build_targets(self, dataCache):
241 """
242 Return a list of build targets who's providers
243 are unknown.
244 """
245 unresolved = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600246 for target in self.build_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500247 if re_match_strings(target, dataCache.ignored_dependencies):
248 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600249 if target in self.failed_deps:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500250 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600251 if not self.build_targets[target]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500252 unresolved.append(target)
253 return unresolved
254
255 def get_unresolved_run_targets(self, dataCache):
256 """
257 Return a list of runtime targets who's providers
258 are unknown.
259 """
260 unresolved = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600261 for target in self.run_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500262 if re_match_strings(target, dataCache.ignored_dependencies):
263 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600264 if target in self.failed_rdeps:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500265 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600266 if not self.run_targets[target]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500267 unresolved.append(target)
268 return unresolved
269
270 def get_provider(self, item):
271 """
272 Return a list of providers of item
273 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600274 return self.build_targets[item]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500275
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600276 def get_dependees(self, item):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500277 """
278 Return a list of targets which depend on item
279 """
280 dependees = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600281 for fn in self.depids:
282 if item in self.depids[fn]:
283 dependees.append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500284 return dependees
285
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600286 def get_rdependees(self, item):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500287 """
288 Return a list of targets which depend on runtime item
289 """
290 dependees = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600291 for fn in self.rdepids:
292 if item in self.rdepids[fn]:
293 dependees.append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500294 return dependees
295
296 def get_reasons(self, item, runtime=False):
297 """
298 Get the reason(s) for an item not being provided, if any
299 """
300 reasons = []
301 if self.skiplist:
302 for fn in self.skiplist:
303 skipitem = self.skiplist[fn]
304 if skipitem.pn == item:
305 reasons.append("%s was skipped: %s" % (skipitem.pn, skipitem.skipreason))
306 elif runtime and item in skipitem.rprovides:
307 reasons.append("%s RPROVIDES %s but was skipped: %s" % (skipitem.pn, item, skipitem.skipreason))
308 elif not runtime and item in skipitem.provides:
309 reasons.append("%s PROVIDES %s but was skipped: %s" % (skipitem.pn, item, skipitem.skipreason))
310 return reasons
311
312 def get_close_matches(self, item, provider_list):
313 import difflib
314 if self.skiplist:
315 skipped = []
316 for fn in self.skiplist:
317 skipped.append(self.skiplist[fn].pn)
318 full_list = provider_list + skipped
319 else:
320 full_list = provider_list
321 return difflib.get_close_matches(item, full_list, cutoff=0.7)
322
323 def add_provider(self, cfgData, dataCache, item):
324 try:
325 self.add_provider_internal(cfgData, dataCache, item)
326 except bb.providers.NoProvider:
327 if self.abort:
328 raise
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600329 self.remove_buildtarget(item)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500330
331 self.mark_external_target(item)
332
333 def add_provider_internal(self, cfgData, dataCache, item):
334 """
335 Add the providers of item to the task data
336 Mark entries were specifically added externally as against dependencies
337 added internally during dependency resolution
338 """
339
340 if re_match_strings(item, dataCache.ignored_dependencies):
341 return
342
343 if not item in dataCache.providers:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600344 close_matches = self.get_close_matches(item, list(dataCache.providers.keys()))
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500345 # Is it in RuntimeProviders ?
346 all_p = bb.providers.getRuntimeProviders(dataCache, item)
347 for fn in all_p:
348 new = dataCache.pkg_fn[fn] + " RPROVIDES " + item
349 if new not in close_matches:
350 close_matches.append(new)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600351 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 -0500352 raise bb.providers.NoProvider(item)
353
354 if self.have_build_target(item):
355 return
356
357 all_p = dataCache.providers[item]
358
359 eligible, foundUnique = bb.providers.filterProviders(all_p, item, cfgData, dataCache)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600360 eligible = [p for p in eligible if not p in self.failed_fns]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500361
362 if not eligible:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600363 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 -0500364 raise bb.providers.NoProvider(item)
365
366 if len(eligible) > 1 and foundUnique == False:
367 if item not in self.consider_msgs_cache:
368 providers_list = []
369 for fn in eligible:
370 providers_list.append(dataCache.pkg_fn[fn])
371 bb.event.fire(bb.event.MultipleProviders(item, providers_list), cfgData)
372 self.consider_msgs_cache.append(item)
373
374 for fn in eligible:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600375 if fn in self.failed_fns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500376 continue
377 logger.debug(2, "adding %s to satisfy %s", fn, item)
378 self.add_build_target(fn, item)
379 self.add_tasks(fn, dataCache)
380
381
382 #item = dataCache.pkg_fn[fn]
383
384 def add_rprovider(self, cfgData, dataCache, item):
385 """
386 Add the runtime providers of item to the task data
387 (takes item names from RDEPENDS/PACKAGES namespace)
388 """
389
390 if re_match_strings(item, dataCache.ignored_dependencies):
391 return
392
393 if self.have_runtime_target(item):
394 return
395
396 all_p = bb.providers.getRuntimeProviders(dataCache, item)
397
398 if not all_p:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600399 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 -0500400 raise bb.providers.NoRProvider(item)
401
402 eligible, numberPreferred = bb.providers.filterProvidersRunTime(all_p, item, cfgData, dataCache)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600403 eligible = [p for p in eligible if not p in self.failed_fns]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500404
405 if not eligible:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600406 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 -0500407 raise bb.providers.NoRProvider(item)
408
409 if len(eligible) > 1 and numberPreferred == 0:
410 if item not in self.consider_msgs_cache:
411 providers_list = []
412 for fn in eligible:
413 providers_list.append(dataCache.pkg_fn[fn])
414 bb.event.fire(bb.event.MultipleProviders(item, providers_list, runtime=True), cfgData)
415 self.consider_msgs_cache.append(item)
416
417 if numberPreferred > 1:
418 if item not in self.consider_msgs_cache:
419 providers_list = []
420 for fn in eligible:
421 providers_list.append(dataCache.pkg_fn[fn])
422 bb.event.fire(bb.event.MultipleProviders(item, providers_list, runtime=True), cfgData)
423 self.consider_msgs_cache.append(item)
424 raise bb.providers.MultipleRProvider(item)
425
426 # run through the list until we find one that we can build
427 for fn in eligible:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600428 if fn in self.failed_fns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500429 continue
430 logger.debug(2, "adding '%s' to satisfy runtime '%s'", fn, item)
431 self.add_runtime_target(fn, item)
432 self.add_tasks(fn, dataCache)
433
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600434 def fail_fn(self, fn, missing_list=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500435 """
436 Mark a file as failed (unbuildable)
437 Remove any references from build and runtime provider lists
438
439 missing_list, A list of missing requirements for this target
440 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600441 if fn in self.failed_fns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500442 return
443 if not missing_list:
444 missing_list = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600445 logger.debug(1, "File '%s' is unbuildable, removing...", fn)
446 self.failed_fns.append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500447 for target in self.build_targets:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600448 if fn in self.build_targets[target]:
449 self.build_targets[target].remove(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500450 if len(self.build_targets[target]) == 0:
451 self.remove_buildtarget(target, missing_list)
452 for target in self.run_targets:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600453 if fn in self.run_targets[target]:
454 self.run_targets[target].remove(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500455 if len(self.run_targets[target]) == 0:
456 self.remove_runtarget(target, missing_list)
457
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600458 def remove_buildtarget(self, target, missing_list=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500459 """
460 Mark a build target as failed (unbuildable)
461 Trigger removal of any files that have this as a dependency
462 """
463 if not missing_list:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600464 missing_list = [target]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500465 else:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600466 missing_list = [target] + missing_list
467 logger.verbose("Target '%s' is unbuildable, removing...\nMissing or unbuildable dependency chain was: %s", target, missing_list)
468 self.failed_deps.append(target)
469 dependees = self.get_dependees(target)
470 for fn in dependees:
471 self.fail_fn(fn, missing_list)
472 for tid in self.taskentries:
473 for (idepend, idependtask) in self.taskentries[tid].idepends:
474 if idepend == target:
475 fn = tid.rsplit(":",1)[0]
476 self.fail_fn(fn, missing_list)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500477
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600478 if self.abort and target in self.external_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500479 logger.error("Required build target '%s' has no buildable providers.\nMissing or unbuildable dependency chain was: %s", target, missing_list)
480 raise bb.providers.NoProvider(target)
481
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600482 def remove_runtarget(self, target, missing_list=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500483 """
484 Mark a run target as failed (unbuildable)
485 Trigger removal of any files that have this as a dependency
486 """
487 if not missing_list:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600488 missing_list = [target]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500489 else:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600490 missing_list = [target] + missing_list
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500491
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600492 logger.info("Runtime target '%s' is unbuildable, removing...\nMissing or unbuildable dependency chain was: %s", target, missing_list)
493 self.failed_rdeps.append(target)
494 dependees = self.get_rdependees(target)
495 for fn in dependees:
496 self.fail_fn(fn, missing_list)
497 for tid in self.taskentries:
498 for (idepend, idependtask) in self.taskentries[tid].irdepends:
499 if idepend == target:
500 fn = tid.rsplit(":",1)[0]
501 self.fail_fn(fn, missing_list)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500502
503 def add_unresolved(self, cfgData, dataCache):
504 """
505 Resolve all unresolved build and runtime targets
506 """
507 logger.info("Resolving any missing task queue dependencies")
508 while True:
509 added = 0
510 for target in self.get_unresolved_build_targets(dataCache):
511 try:
512 self.add_provider_internal(cfgData, dataCache, target)
513 added = added + 1
514 except bb.providers.NoProvider:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600515 if self.abort and target in self.external_targets and not self.allowincomplete:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500516 raise
517 if not self.allowincomplete:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600518 self.remove_buildtarget(target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500519 for target in self.get_unresolved_run_targets(dataCache):
520 try:
521 self.add_rprovider(cfgData, dataCache, target)
522 added = added + 1
523 except (bb.providers.NoRProvider, bb.providers.MultipleRProvider):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600524 self.remove_runtarget(target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500525 logger.debug(1, "Resolved " + str(added) + " extra dependencies")
526 if added == 0:
527 break
528 # self.dump_data()
529
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500530 def get_providermap(self, prefix=None):
531 provmap = {}
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600532 for name in self.build_targets:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500533 if prefix and not name.startswith(prefix):
534 continue
535 if self.have_build_target(name):
536 provider = self.get_provider(name)
537 if provider:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600538 provmap[name] = provider[0]
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500539 return provmap
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500540
Brad Bishop1a4b7ee2018-12-16 17:11:34 -0800541 def get_mcdepends(self):
542 return self.mcdepends
543
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])