blob: 8c96a562858266c1c2d8122f4562afc29c3dc2cb [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
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']:
114 bb.debug(2, "Not adding dependeny of %s on %s since %s does not exist" % (task, dep, dep))
115 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
120 # Touch all intertask dependencies
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500121 handle_deps(task, 'depends', self.taskentries[tid].idepends, self.seen_build_target)
122 handle_deps(task, 'rdepends', self.taskentries[tid].irdepends, self.seen_run_target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500123
124 # 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
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500541 def dump_data(self):
542 """
543 Dump some debug information on the internal data structures
544 """
545 logger.debug(3, "build_names:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600546 logger.debug(3, ", ".join(self.build_targets))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500547
548 logger.debug(3, "run_names:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600549 logger.debug(3, ", ".join(self.run_targets))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500550
551 logger.debug(3, "build_targets:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600552 for target in self.build_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500553 targets = "None"
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600554 if target in self.build_targets:
555 targets = self.build_targets[target]
556 logger.debug(3, " %s: %s", target, targets)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500557
558 logger.debug(3, "run_targets:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600559 for target in self.run_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500560 targets = "None"
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600561 if target in self.run_targets:
562 targets = self.run_targets[target]
563 logger.debug(3, " %s: %s", target, targets)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500564
565 logger.debug(3, "tasks:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600566 for tid in self.taskentries:
567 logger.debug(3, " %s: %s %s %s",
568 tid,
569 self.taskentries[tid].idepends,
570 self.taskentries[tid].irdepends,
571 self.taskentries[tid].tdepends)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500572
573 logger.debug(3, "dependency ids (per fn):")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600574 for fn in self.depids:
575 logger.debug(3, " %s: %s", fn, self.depids[fn])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500576
577 logger.debug(3, "runtime dependency ids (per fn):")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600578 for fn in self.rdepids:
579 logger.debug(3, " %s: %s", fn, self.rdepids[fn])