blob: 0ea6c0bfd6c1e5d02a213e35fdad6618e636af54 [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 """
Brad Bishopd7bf8c12018-02-25 22:55:05 -050050 def __init__(self, abort = True, 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
Patrick Williamsc124f4f2015-09-15 14:41:29 -050069 self.allowincomplete = allowincomplete
70
71 self.skiplist = skiplist
72
Patrick Williamsc124f4f2015-09-15 14:41:29 -050073 def add_tasks(self, fn, dataCache):
74 """
75 Add tasks for a given fn to the database
76 """
77
78 task_deps = dataCache.task_deps[fn]
79
Patrick Williamsc0f7c042017-02-23 20:41:17 -060080 if fn in self.failed_fns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050081 bb.msg.fatal("TaskData", "Trying to re-add a failed file? Something is broken...")
82
83 # Check if we've already seen this fn
Patrick Williamsc0f7c042017-02-23 20:41:17 -060084 if fn in self.seenfns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -050085 return
86
Patrick Williamsc0f7c042017-02-23 20:41:17 -060087 self.seenfns.append(fn)
88
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050089 self.add_extra_deps(fn, dataCache)
90
Brad Bishop6e60e8b2018-02-01 10:27:11 -050091 # Common code for dep_name/depends = 'depends'/idepends and 'rdepends'/irdepends
92 def handle_deps(task, dep_name, depends, seen):
93 if dep_name in task_deps and task in task_deps[dep_name]:
94 ids = []
95 for dep in task_deps[dep_name][task].split():
96 if dep:
97 parts = dep.split(":")
98 if len(parts) != 2:
99 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))
100 ids.append((parts[0], parts[1]))
101 seen(parts[0])
102 depends.extend(ids)
103
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500104 for task in task_deps['tasks']:
105
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600106 tid = "%s:%s" % (fn, task)
107 self.taskentries[tid] = TaskEntry()
108
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500109 # Work out task dependencies
110 parentids = []
111 for dep in task_deps['parents'][task]:
112 if dep not in task_deps['tasks']:
113 bb.debug(2, "Not adding dependeny of %s on %s since %s does not exist" % (task, dep, dep))
114 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600115 parentid = "%s:%s" % (fn, dep)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500116 parentids.append(parentid)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600117 self.taskentries[tid].tdepends.extend(parentids)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500118
119 # Touch all intertask dependencies
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500120 handle_deps(task, 'depends', self.taskentries[tid].idepends, self.seen_build_target)
121 handle_deps(task, 'rdepends', self.taskentries[tid].irdepends, self.seen_run_target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500122
123 # Work out build dependencies
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600124 if not fn in self.depids:
125 dependids = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500126 for depend in dataCache.deps[fn]:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600127 dependids.add(depend)
128 self.depids[fn] = list(dependids)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500129 logger.debug(2, "Added dependencies %s for %s", str(dataCache.deps[fn]), fn)
130
131 # Work out runtime dependencies
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600132 if not fn in self.rdepids:
133 rdependids = set()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500134 rdepends = dataCache.rundeps[fn]
135 rrecs = dataCache.runrecs[fn]
136 rdependlist = []
137 rreclist = []
138 for package in rdepends:
139 for rdepend in rdepends[package]:
140 rdependlist.append(rdepend)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600141 rdependids.add(rdepend)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500142 for package in rrecs:
143 for rdepend in rrecs[package]:
144 rreclist.append(rdepend)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600145 rdependids.add(rdepend)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500146 if rdependlist:
147 logger.debug(2, "Added runtime dependencies %s for %s", str(rdependlist), fn)
148 if rreclist:
149 logger.debug(2, "Added runtime recommendations %s for %s", str(rreclist), fn)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600150 self.rdepids[fn] = list(rdependids)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500151
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600152 for dep in self.depids[fn]:
153 self.seen_build_target(dep)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500154 if dep in self.failed_deps:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600155 self.fail_fn(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500156 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600157 for dep in self.rdepids[fn]:
158 self.seen_run_target(dep)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500159 if dep in self.failed_rdeps:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600160 self.fail_fn(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500161 return
162
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500163 def add_extra_deps(self, fn, dataCache):
164 func = dataCache.extradepsfunc.get(fn, None)
165 if func:
166 bb.providers.buildWorldTargetList(dataCache)
167 pn = dataCache.pkg_fn[fn]
168 params = {'deps': dataCache.deps[fn],
169 'world_target': dataCache.world_target,
170 'pkg_pn': dataCache.pkg_pn,
171 'self_pn': pn}
172 funcname = '_%s_calculate_extra_depends' % pn.replace('-', '_')
173 paramlist = ','.join(params.keys())
174 func = 'def %s(%s):\n%s\n\n%s(%s)' % (funcname, paramlist, func, funcname, paramlist)
175 bb.utils.better_exec(func, params)
176
177
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500178 def have_build_target(self, target):
179 """
180 Have we a build target matching this name?
181 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600182 if target in self.build_targets and self.build_targets[target]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500183 return True
184 return False
185
186 def have_runtime_target(self, target):
187 """
188 Have we a runtime target matching this name?
189 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600190 if target in self.run_targets and self.run_targets[target]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500191 return True
192 return False
193
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600194 def seen_build_target(self, name):
195 """
196 Maintain a list of build targets
197 """
198 if name not in self.build_targets:
199 self.build_targets[name] = []
200
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500201 def add_build_target(self, fn, item):
202 """
203 Add a build target.
204 If already present, append the provider fn to the list
205 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600206 if item in self.build_targets:
207 if fn in self.build_targets[item]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500208 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600209 self.build_targets[item].append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500210 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600211 self.build_targets[item] = [fn]
212
213 def seen_run_target(self, name):
214 """
215 Maintain a list of runtime build targets
216 """
217 if name not in self.run_targets:
218 self.run_targets[name] = []
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500219
220 def add_runtime_target(self, fn, item):
221 """
222 Add a runtime target.
223 If already present, append the provider fn to the list
224 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600225 if item in self.run_targets:
226 if fn in self.run_targets[item]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500227 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600228 self.run_targets[item].append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500229 return
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600230 self.run_targets[item] = [fn]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500231
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600232 def mark_external_target(self, target):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500233 """
234 Mark a build target as being externally requested
235 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600236 if target not in self.external_targets:
237 self.external_targets.append(target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500238
239 def get_unresolved_build_targets(self, dataCache):
240 """
241 Return a list of build targets who's providers
242 are unknown.
243 """
244 unresolved = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600245 for target in self.build_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500246 if re_match_strings(target, dataCache.ignored_dependencies):
247 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600248 if target in self.failed_deps:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500249 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600250 if not self.build_targets[target]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500251 unresolved.append(target)
252 return unresolved
253
254 def get_unresolved_run_targets(self, dataCache):
255 """
256 Return a list of runtime targets who's providers
257 are unknown.
258 """
259 unresolved = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600260 for target in self.run_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500261 if re_match_strings(target, dataCache.ignored_dependencies):
262 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600263 if target in self.failed_rdeps:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500264 continue
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600265 if not self.run_targets[target]:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500266 unresolved.append(target)
267 return unresolved
268
269 def get_provider(self, item):
270 """
271 Return a list of providers of item
272 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600273 return self.build_targets[item]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500274
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600275 def get_dependees(self, item):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500276 """
277 Return a list of targets which depend on item
278 """
279 dependees = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600280 for fn in self.depids:
281 if item in self.depids[fn]:
282 dependees.append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500283 return dependees
284
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600285 def get_rdependees(self, item):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500286 """
287 Return a list of targets which depend on runtime item
288 """
289 dependees = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600290 for fn in self.rdepids:
291 if item in self.rdepids[fn]:
292 dependees.append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500293 return dependees
294
295 def get_reasons(self, item, runtime=False):
296 """
297 Get the reason(s) for an item not being provided, if any
298 """
299 reasons = []
300 if self.skiplist:
301 for fn in self.skiplist:
302 skipitem = self.skiplist[fn]
303 if skipitem.pn == item:
304 reasons.append("%s was skipped: %s" % (skipitem.pn, skipitem.skipreason))
305 elif runtime and item in skipitem.rprovides:
306 reasons.append("%s RPROVIDES %s but was skipped: %s" % (skipitem.pn, item, skipitem.skipreason))
307 elif not runtime and item in skipitem.provides:
308 reasons.append("%s PROVIDES %s but was skipped: %s" % (skipitem.pn, item, skipitem.skipreason))
309 return reasons
310
311 def get_close_matches(self, item, provider_list):
312 import difflib
313 if self.skiplist:
314 skipped = []
315 for fn in self.skiplist:
316 skipped.append(self.skiplist[fn].pn)
317 full_list = provider_list + skipped
318 else:
319 full_list = provider_list
320 return difflib.get_close_matches(item, full_list, cutoff=0.7)
321
322 def add_provider(self, cfgData, dataCache, item):
323 try:
324 self.add_provider_internal(cfgData, dataCache, item)
325 except bb.providers.NoProvider:
326 if self.abort:
327 raise
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600328 self.remove_buildtarget(item)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500329
330 self.mark_external_target(item)
331
332 def add_provider_internal(self, cfgData, dataCache, item):
333 """
334 Add the providers of item to the task data
335 Mark entries were specifically added externally as against dependencies
336 added internally during dependency resolution
337 """
338
339 if re_match_strings(item, dataCache.ignored_dependencies):
340 return
341
342 if not item in dataCache.providers:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600343 close_matches = self.get_close_matches(item, list(dataCache.providers.keys()))
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500344 # Is it in RuntimeProviders ?
345 all_p = bb.providers.getRuntimeProviders(dataCache, item)
346 for fn in all_p:
347 new = dataCache.pkg_fn[fn] + " RPROVIDES " + item
348 if new not in close_matches:
349 close_matches.append(new)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600350 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 -0500351 raise bb.providers.NoProvider(item)
352
353 if self.have_build_target(item):
354 return
355
356 all_p = dataCache.providers[item]
357
358 eligible, foundUnique = bb.providers.filterProviders(all_p, item, cfgData, dataCache)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600359 eligible = [p for p in eligible if not p in self.failed_fns]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500360
361 if not eligible:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600362 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 -0500363 raise bb.providers.NoProvider(item)
364
365 if len(eligible) > 1 and foundUnique == False:
366 if item not in self.consider_msgs_cache:
367 providers_list = []
368 for fn in eligible:
369 providers_list.append(dataCache.pkg_fn[fn])
370 bb.event.fire(bb.event.MultipleProviders(item, providers_list), cfgData)
371 self.consider_msgs_cache.append(item)
372
373 for fn in eligible:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600374 if fn in self.failed_fns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500375 continue
376 logger.debug(2, "adding %s to satisfy %s", fn, item)
377 self.add_build_target(fn, item)
378 self.add_tasks(fn, dataCache)
379
380
381 #item = dataCache.pkg_fn[fn]
382
383 def add_rprovider(self, cfgData, dataCache, item):
384 """
385 Add the runtime providers of item to the task data
386 (takes item names from RDEPENDS/PACKAGES namespace)
387 """
388
389 if re_match_strings(item, dataCache.ignored_dependencies):
390 return
391
392 if self.have_runtime_target(item):
393 return
394
395 all_p = bb.providers.getRuntimeProviders(dataCache, item)
396
397 if not all_p:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600398 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 -0500399 raise bb.providers.NoRProvider(item)
400
401 eligible, numberPreferred = bb.providers.filterProvidersRunTime(all_p, item, cfgData, dataCache)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600402 eligible = [p for p in eligible if not p in self.failed_fns]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500403
404 if not eligible:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600405 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 -0500406 raise bb.providers.NoRProvider(item)
407
408 if len(eligible) > 1 and numberPreferred == 0:
409 if item not in self.consider_msgs_cache:
410 providers_list = []
411 for fn in eligible:
412 providers_list.append(dataCache.pkg_fn[fn])
413 bb.event.fire(bb.event.MultipleProviders(item, providers_list, runtime=True), cfgData)
414 self.consider_msgs_cache.append(item)
415
416 if numberPreferred > 1:
417 if item not in self.consider_msgs_cache:
418 providers_list = []
419 for fn in eligible:
420 providers_list.append(dataCache.pkg_fn[fn])
421 bb.event.fire(bb.event.MultipleProviders(item, providers_list, runtime=True), cfgData)
422 self.consider_msgs_cache.append(item)
423 raise bb.providers.MultipleRProvider(item)
424
425 # run through the list until we find one that we can build
426 for fn in eligible:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600427 if fn in self.failed_fns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500428 continue
429 logger.debug(2, "adding '%s' to satisfy runtime '%s'", fn, item)
430 self.add_runtime_target(fn, item)
431 self.add_tasks(fn, dataCache)
432
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600433 def fail_fn(self, fn, missing_list=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500434 """
435 Mark a file as failed (unbuildable)
436 Remove any references from build and runtime provider lists
437
438 missing_list, A list of missing requirements for this target
439 """
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600440 if fn in self.failed_fns:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500441 return
442 if not missing_list:
443 missing_list = []
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600444 logger.debug(1, "File '%s' is unbuildable, removing...", fn)
445 self.failed_fns.append(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500446 for target in self.build_targets:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600447 if fn in self.build_targets[target]:
448 self.build_targets[target].remove(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500449 if len(self.build_targets[target]) == 0:
450 self.remove_buildtarget(target, missing_list)
451 for target in self.run_targets:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600452 if fn in self.run_targets[target]:
453 self.run_targets[target].remove(fn)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500454 if len(self.run_targets[target]) == 0:
455 self.remove_runtarget(target, missing_list)
456
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600457 def remove_buildtarget(self, target, missing_list=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500458 """
459 Mark a build target as failed (unbuildable)
460 Trigger removal of any files that have this as a dependency
461 """
462 if not missing_list:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600463 missing_list = [target]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500464 else:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600465 missing_list = [target] + missing_list
466 logger.verbose("Target '%s' is unbuildable, removing...\nMissing or unbuildable dependency chain was: %s", target, missing_list)
467 self.failed_deps.append(target)
468 dependees = self.get_dependees(target)
469 for fn in dependees:
470 self.fail_fn(fn, missing_list)
471 for tid in self.taskentries:
472 for (idepend, idependtask) in self.taskentries[tid].idepends:
473 if idepend == target:
474 fn = tid.rsplit(":",1)[0]
475 self.fail_fn(fn, missing_list)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500476
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600477 if self.abort and target in self.external_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500478 logger.error("Required build target '%s' has no buildable providers.\nMissing or unbuildable dependency chain was: %s", target, missing_list)
479 raise bb.providers.NoProvider(target)
480
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600481 def remove_runtarget(self, target, missing_list=None):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500482 """
483 Mark a run target as failed (unbuildable)
484 Trigger removal of any files that have this as a dependency
485 """
486 if not missing_list:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600487 missing_list = [target]
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500488 else:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600489 missing_list = [target] + missing_list
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500490
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600491 logger.info("Runtime target '%s' is unbuildable, removing...\nMissing or unbuildable dependency chain was: %s", target, missing_list)
492 self.failed_rdeps.append(target)
493 dependees = self.get_rdependees(target)
494 for fn in dependees:
495 self.fail_fn(fn, missing_list)
496 for tid in self.taskentries:
497 for (idepend, idependtask) in self.taskentries[tid].irdepends:
498 if idepend == target:
499 fn = tid.rsplit(":",1)[0]
500 self.fail_fn(fn, missing_list)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500501
502 def add_unresolved(self, cfgData, dataCache):
503 """
504 Resolve all unresolved build and runtime targets
505 """
506 logger.info("Resolving any missing task queue dependencies")
507 while True:
508 added = 0
509 for target in self.get_unresolved_build_targets(dataCache):
510 try:
511 self.add_provider_internal(cfgData, dataCache, target)
512 added = added + 1
513 except bb.providers.NoProvider:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600514 if self.abort and target in self.external_targets and not self.allowincomplete:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500515 raise
516 if not self.allowincomplete:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600517 self.remove_buildtarget(target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500518 for target in self.get_unresolved_run_targets(dataCache):
519 try:
520 self.add_rprovider(cfgData, dataCache, target)
521 added = added + 1
522 except (bb.providers.NoRProvider, bb.providers.MultipleRProvider):
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600523 self.remove_runtarget(target)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500524 logger.debug(1, "Resolved " + str(added) + " extra dependencies")
525 if added == 0:
526 break
527 # self.dump_data()
528
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500529 def get_providermap(self, prefix=None):
530 provmap = {}
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600531 for name in self.build_targets:
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500532 if prefix and not name.startswith(prefix):
533 continue
534 if self.have_build_target(name):
535 provider = self.get_provider(name)
536 if provider:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600537 provmap[name] = provider[0]
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500538 return provmap
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500539
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500540 def dump_data(self):
541 """
542 Dump some debug information on the internal data structures
543 """
544 logger.debug(3, "build_names:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600545 logger.debug(3, ", ".join(self.build_targets))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500546
547 logger.debug(3, "run_names:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600548 logger.debug(3, ", ".join(self.run_targets))
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500549
550 logger.debug(3, "build_targets:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600551 for target in self.build_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500552 targets = "None"
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600553 if target in self.build_targets:
554 targets = self.build_targets[target]
555 logger.debug(3, " %s: %s", target, targets)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500556
557 logger.debug(3, "run_targets:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600558 for target in self.run_targets:
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500559 targets = "None"
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600560 if target in self.run_targets:
561 targets = self.run_targets[target]
562 logger.debug(3, " %s: %s", target, targets)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500563
564 logger.debug(3, "tasks:")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600565 for tid in self.taskentries:
566 logger.debug(3, " %s: %s %s %s",
567 tid,
568 self.taskentries[tid].idepends,
569 self.taskentries[tid].irdepends,
570 self.taskentries[tid].tdepends)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500571
572 logger.debug(3, "dependency ids (per fn):")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600573 for fn in self.depids:
574 logger.debug(3, " %s: %s", fn, self.depids[fn])
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500575
576 logger.debug(3, "runtime dependency ids (per fn):")
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600577 for fn in self.rdepids:
578 logger.debug(3, " %s: %s", fn, self.rdepids[fn])