summaryrefslogtreecommitdiffstats
path: root/bitbake/bin/bitbake
diff options
context:
space:
mode:
authorRichard Purdie <richard@openedhand.com>2006-11-29 22:52:37 +0000
committerRichard Purdie <richard@openedhand.com>2006-11-29 22:52:37 +0000
commit681d6c18ad59dac9e53f769a568835241d7fa9b7 (patch)
tree243418a546b89650d28580f7721b8324586146e4 /bitbake/bin/bitbake
parentadabf6c0931af1282a7c75321cd8b050e8d05c95 (diff)
downloadpoky-681d6c18ad59dac9e53f769a568835241d7fa9b7.tar.gz
bitbake: Sync with bitbake trunk for bugfixes and improved dot file generation code
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@987 311d38ba-8fff-0310-9ca6-ca027cbcb966
Diffstat (limited to 'bitbake/bin/bitbake')
-rwxr-xr-xbitbake/bin/bitbake223
1 files changed, 67 insertions, 156 deletions
diff --git a/bitbake/bin/bitbake b/bitbake/bin/bitbake
index 85a0cbc398..36322d2a0e 100755
--- a/bitbake/bin/bitbake
+++ b/bitbake/bin/bitbake
@@ -186,171 +186,82 @@ class BBCooker:
186 186
187 def generateDotGraph( self, pkgs_to_build, ignore_deps ): 187 def generateDotGraph( self, pkgs_to_build, ignore_deps ):
188 """ 188 """
189 Generate two graphs one for the DEPENDS and RDEPENDS. The current 189 Generate a task dependency graph.
190 implementation creates crappy graphs ;)
191 190
192 pkgs_to_build A list of packages that needs to be built 191 pkgs_to_build A list of packages that needs to be built
193 ignore_deps A list of names where processing of dependencies 192 ignore_deps A list of names where processing of dependencies
194 should be stopped. e.g. dependencies that get 193 should be stopped. e.g. dependencies that get
195 """ 194 """
196 195
197 def myFilterProvider( providers, item): 196 for dep in ignore_deps:
198 """ 197 self.status.ignored_dependencies.add(dep)
199 Take a list of providers and filter according to environment
200 variables. In contrast to filterProviders we do not discriminate
201 and take PREFERRED_PROVIDER into account.
202 """
203 eligible = []
204 preferred_versions = {}
205
206 # Collate providers by PN
207 pkg_pn = {}
208 for p in providers:
209 pn = self.status.pkg_fn[p]
210 if pn not in pkg_pn:
211 pkg_pn[pn] = []
212 pkg_pn[pn].append(p)
213
214 bb.msg.debug(1, bb.msg.domain.Provider, "providers for %s are: %s" % (item, pkg_pn.keys()))
215
216 for pn in pkg_pn.keys():
217 preferred_versions[pn] = bb.providers.findBestProvider(pn, self.configuration.data, self.status, pkg_pn)[2:4]
218 eligible.append(preferred_versions[pn][1])
219
220 for p in eligible:
221 if p in self.build_cache_fail:
222 bb.msg.debug(1, bb.msg.domain.Provider, "rejecting already-failed %s" % p)
223 eligible.remove(p)
224
225 if len(eligible) == 0:
226 bb.msg.error(bb.msg.domain.Provider, "no eligible providers for %s" % item)
227 return 0
228
229 prefervar = bb.data.getVar('PREFERRED_PROVIDER_%s' % item, self.configuration.data, 1)
230
231 # try the preferred provider first
232 if prefervar:
233 for p in eligible:
234 if prefervar == self.status.pkg_fn[p]:
235 bb.msg.note(1, bb.msg.domain.Provider, "Selecting PREFERRED_PROVIDER %s" % prefervar)
236 eligible.remove(p)
237 eligible = [p] + eligible
238
239 return eligible
240
241
242 # try to avoid adding the same rdepends over an over again
243 seen_depends = []
244 seen_rdepends = []
245
246
247 def add_depends(package_list):
248 """
249 Add all depends of all packages from this list
250 """
251 for package in package_list:
252 if package in seen_depends or package in ignore_deps:
253 continue
254
255 seen_depends.append( package )
256 if not package in self.status.providers:
257 """
258 We have not seen this name -> error in
259 dependency handling
260 """
261 bb.msg.note(1, bb.msg.domain.Depends, "ERROR with provider: %(package)s" % vars() )
262 print >> depends_file, '"%(package)s" -> ERROR' % vars()
263 continue
264
265 # get all providers for this package
266 providers = self.status.providers[package]
267
268 # now let us find the bestProvider for it
269 fn = myFilterProvider(providers, package)[0]
270
271 depends = bb.utils.explode_deps(self.bb_cache.getVar('DEPENDS', fn, True) or "")
272 version = self.bb_cache.getVar('PV', fn, True ) + '-' + self.bb_cache.getVar('PR', fn, True)
273 add_depends ( depends )
274
275 # now create the node
276 print >> depends_file, '"%(package)s" [label="%(package)s\\n%(version)s"]' % vars()
277
278 depends = filter( (lambda x: x not in ignore_deps), depends )
279 for depend in depends:
280 print >> depends_file, '"%(package)s" -> "%(depend)s"' % vars()
281
282
283 def add_all_depends( the_depends, the_rdepends ):
284 """
285 Add both DEPENDS and RDEPENDS. RDEPENDS will get dashed
286 lines
287 """
288 package_list = the_depends + the_rdepends
289 for package in package_list:
290 if package in seen_rdepends or package in ignore_deps:
291 continue
292
293 seen_rdepends.append( package )
294
295 # Let us find out if the package is a DEPENDS or RDEPENDS
296 # and we will set 'providers' with the avilable providers
297 # for the package.
298 if package in the_depends:
299 if not package in self.status.providers:
300 bb.msg.note(1, bb.msg.domain.Depends, "ERROR with provider: %(package)s" % vars() )
301 print >> alldepends_file, '"%(package)s" -> ERROR' % vars()
302 continue
303
304 providers = self.status.providers[package]
305 elif package in the_rdepends:
306 if len(bb.providers.getRuntimeProviders(self.status, package)) == 0:
307 bb.msg.note(1, bb.msg.domain.Depends, "ERROR with rprovider: %(package)s" % vars() )
308 print >> alldepends_file, '"%(package)s" -> ERROR [style="dashed"]' % vars()
309 continue
310
311 providers = bb.providers.getRuntimeProviders(self.status, package)
312 else:
313 # something went wrong...
314 print "Complete ERROR! %s" % package
315 continue
316
317 # now let us find the bestProvider for it
318 fn = myFilterProvider(providers, package)[0]
319
320 # Now we have a filename let us get the depends and RDEPENDS of it
321 depends = bb.utils.explode_deps(self.bb_cache.getVar('DEPENDS', fn, True) or "")
322 if fn in self.status.rundeps and package in self.status.rundeps[fn]:
323 rdepends= self.status.rundeps[fn][package].keys()
324 else:
325 rdepends = []
326 version = self.bb_cache.getVar('PV', fn, True ) + '-' + self.bb_cache.getVar('PR', fn, True)
327 198
328 # handle all the depends and rdepends of package 199 localdata = data.createCopy(self.configuration.data)
329 add_all_depends ( depends, rdepends ) 200 bb.data.update_data(localdata)
330 201 bb.data.expandKeys(localdata)
331 # now create the node using package name 202 taskdata = bb.taskdata.TaskData(self.configuration.abort)
332 print >> alldepends_file, '"%(package)s" [label="%(package)s\\n%(version)s"]' % vars()
333
334 # remove the stuff we want to ignore and add the edges
335 depends = filter( (lambda x: x not in ignore_deps), depends )
336 rdepends = filter( (lambda x: x not in ignore_deps), rdepends )
337 for depend in depends:
338 print >> alldepends_file, '"%(package)s" -> "%(depend)s"' % vars()
339 for depend in rdepends:
340 print >> alldepends_file, '"%(package)s" -> "%(depend)s" [style=dashed]' % vars()
341 203
204 runlist = []
205 try:
206 for k in pkgs_to_build:
207 taskdata.add_provider(localdata, self.status, k)
208 runlist.append([k, "do_%s" % self.configuration.cmd])
209 taskdata.add_unresolved(localdata, self.status)
210 except bb.providers.NoProvider:
211 sys.exit(1)
212 rq = bb.runqueue.RunQueue()
213 rq.prepare_runqueue(self.configuration.data, self.status, taskdata, runlist)
342 214
343 # Add depends now 215 seen_fnids = []
344 depends_file = file('depends.dot', 'w' ) 216 depends_file = file('depends.dot', 'w' )
217 tdepends_file = file('task-depends.dot', 'w' )
345 print >> depends_file, "digraph depends {" 218 print >> depends_file, "digraph depends {"
346 add_depends( pkgs_to_build ) 219 print >> tdepends_file, "digraph depends {"
220 rq.prio_map.reverse()
221 for task1 in range(len(rq.runq_fnid)):
222 task = rq.prio_map[task1]
223 taskname = rq.runq_task[task]
224 fnid = rq.runq_fnid[task]
225 fn = taskdata.fn_index[fnid]
226 pn = self.status.pkg_fn[fn]
227 version = self.bb_cache.getVar('PV', fn, True ) + '-' + self.bb_cache.getVar('PR', fn, True)
228 print >> tdepends_file, '"%s.%s" [label="%s %s\\n%s\\n%s"]' % (pn, taskname, pn, taskname, version, fn)
229 for dep in rq.runq_depends[task]:
230 depfn = taskdata.fn_index[rq.runq_fnid[dep]]
231 deppn = self.status.pkg_fn[depfn]
232 print >> tdepends_file, '"%s.%s" -> "%s.%s"' % (pn, rq.runq_task[task], deppn, rq.runq_task[dep])
233 if fnid not in seen_fnids:
234 seen_fnids.append(fnid)
235 packages = []
236 print >> depends_file, '"%s" [label="%s %s\\n%s"]' % (pn, pn, version, fn)
237 for depend in self.status.deps[fn]:
238 print >> depends_file, '"%s" -> "%s"' % (pn, depend)
239 rdepends = self.status.rundeps[fn]
240 for package in rdepends:
241 for rdepend in rdepends[package]:
242 print >> depends_file, '"%s" -> "%s" [style=dashed]' % (package, rdepend)
243 packages.append(package)
244 rrecs = self.status.runrecs[fn]
245 for package in rrecs:
246 for rdepend in rrecs[package]:
247 print >> depends_file, '"%s" -> "%s" [style=dashed]' % (package, rdepend)
248 if not package in packages:
249 packages.append(package)
250 for package in packages:
251 if package != pn:
252 print >> depends_file, '"%s" [label="%s(%s) %s\\n%s"]' % (package, package, pn, version, fn)
253 for depend in self.status.deps[fn]:
254 print >> depends_file, '"%s" -> "%s"' % (package, depend)
255 # Prints a flattened form of the above where subpackages of a package are merged into the main pn
256 #print >> depends_file, '"%s" [label="%s %s\\n%s\\n%s"]' % (pn, pn, taskname, version, fn)
257 #for rdep in taskdata.rdepids[fnid]:
258 # print >> depends_file, '"%s" -> "%s" [style=dashed]' % (pn, taskdata.run_names_index[rdep])
259 #for dep in taskdata.depids[fnid]:
260 # print >> depends_file, '"%s" -> "%s"' % (pn, taskdata.build_names_index[dep])
347 print >> depends_file, "}" 261 print >> depends_file, "}"
348 262 print >> tdepends_file, "}"
349 # Add all depends now 263 bb.msg.note(1, bb.msg.domain.Collection, "Dependencies saved to 'depends.dot'")
350 alldepends_file = file('alldepends.dot', 'w' ) 264 bb.msg.note(1, bb.msg.domain.Collection, "Task dependencies saved to 'task-depends.dot'")
351 print >> alldepends_file, "digraph alldepends {"
352 add_all_depends( pkgs_to_build, [] )
353 print >> alldepends_file, "}"
354 265
355 def buildDepgraph( self ): 266 def buildDepgraph( self ):
356 all_depends = self.status.all_depends 267 all_depends = self.status.all_depends
@@ -643,10 +554,10 @@ class BBCooker:
643 rq.prepare_runqueue(self.configuration.data, self.status, taskdata, runlist) 554 rq.prepare_runqueue(self.configuration.data, self.status, taskdata, runlist)
644 try: 555 try:
645 failures = rq.execute_runqueue(self, self.configuration.data, self.status, taskdata, runlist) 556 failures = rq.execute_runqueue(self, self.configuration.data, self.status, taskdata, runlist)
646 except runqueue.TaskFailure, (fnid, fn, taskname): 557 except runqueue.TaskFailure, fnids:
647 bb.msg.error(bb.msg.domain.Build, "'%s, %s' failed" % (fn, taskname)) 558 for fnid in fnids:
559 bb.msg.error(bb.msg.domain.Build, "'%s' failed" % taskdata.fn_index[fnid])
648 sys.exit(1) 560 sys.exit(1)
649
650 bb.event.fire(bb.event.BuildCompleted(buildname, pkgs_to_build, self.configuration.event_data, failures)) 561 bb.event.fire(bb.event.BuildCompleted(buildname, pkgs_to_build, self.configuration.event_data, failures))
651 562
652 sys.exit( self.stats.show() ) 563 sys.exit( self.stats.show() )