diff options
author | Richard Purdie <richard@openedhand.com> | 2006-11-29 22:52:37 +0000 |
---|---|---|
committer | Richard Purdie <richard@openedhand.com> | 2006-11-29 22:52:37 +0000 |
commit | 681d6c18ad59dac9e53f769a568835241d7fa9b7 (patch) | |
tree | 243418a546b89650d28580f7721b8324586146e4 /bitbake/bin | |
parent | adabf6c0931af1282a7c75321cd8b050e8d05c95 (diff) | |
download | poky-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')
-rwxr-xr-x | bitbake/bin/bitbake | 223 |
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() ) |