diff options
Diffstat (limited to 'bitbake/bin')
-rwxr-xr-x | bitbake/bin/bitbake | 244 | ||||
-rw-r--r-- | bitbake/bin/bitbakec | bin | 27715 -> 38998 bytes |
2 files changed, 216 insertions, 28 deletions
diff --git a/bitbake/bin/bitbake b/bitbake/bin/bitbake index dac3c93749..09417f6eca 100755 --- a/bitbake/bin/bitbake +++ b/bitbake/bin/bitbake | |||
@@ -46,9 +46,12 @@ class BBParsingStatus: | |||
46 | def __init__(self): | 46 | def __init__(self): |
47 | self.cache_dirty = False | 47 | self.cache_dirty = False |
48 | self.providers = {} | 48 | self.providers = {} |
49 | self.rproviders = {} | ||
50 | self.packages = {} | ||
51 | self.packages_dynamic = {} | ||
49 | self.bbfile_priority = {} | 52 | self.bbfile_priority = {} |
50 | self.bbfile_config_priorities = [] | 53 | self.bbfile_config_priorities = [] |
51 | self.ignored_depedencies = None | 54 | self.ignored_dependencies = None |
52 | self.possible_world = [] | 55 | self.possible_world = [] |
53 | self.world_target = Set() | 56 | self.world_target = Set() |
54 | self.pkg_pn = {} | 57 | self.pkg_pn = {} |
@@ -74,7 +77,10 @@ class BBParsingStatus: | |||
74 | pr = bb.data.getVar('PR', bb_data, True) | 77 | pr = bb.data.getVar('PR', bb_data, True) |
75 | dp = int(bb.data.getVar('DEFAULT_PREFERENCE', bb_data, True) or "0") | 78 | dp = int(bb.data.getVar('DEFAULT_PREFERENCE', bb_data, True) or "0") |
76 | provides = Set([pn] + (bb.data.getVar("PROVIDES", bb_data, 1) or "").split()) | 79 | provides = Set([pn] + (bb.data.getVar("PROVIDES", bb_data, 1) or "").split()) |
80 | rprovides = (bb.data.getVar("RPROVIDES", bb_data, 1) or "").split() | ||
77 | depends = (bb.data.getVar("DEPENDS", bb_data, True) or "").split() | 81 | depends = (bb.data.getVar("DEPENDS", bb_data, True) or "").split() |
82 | packages = (bb.data.getVar('PACKAGES', bb_data, True) or "").split() | ||
83 | packages_dynamic = (bb.data.getVar('PACKAGES_DYNAMIC', bb_data, True) or "").split() | ||
78 | 84 | ||
79 | 85 | ||
80 | # build PackageName to FileName lookup table | 86 | # build PackageName to FileName lookup table |
@@ -102,6 +108,24 @@ class BBParsingStatus: | |||
102 | for dep in depends: | 108 | for dep in depends: |
103 | self.all_depends.add(dep) | 109 | self.all_depends.add(dep) |
104 | 110 | ||
111 | # Build reverse hash for PACKAGES, so runtime dependencies | ||
112 | # can be be resolved (RDEPENDS, RRECOMMENDS etc.) | ||
113 | |||
114 | for package in packages: | ||
115 | if not package in self.packages: | ||
116 | self.packages[package] = [] | ||
117 | self.packages[package].append(file_name) | ||
118 | |||
119 | for package in packages_dynamic: | ||
120 | if not package in self.packages_dynamic: | ||
121 | self.packages_dynamic[package] = [] | ||
122 | self.packages_dynamic[package].append(file_name) | ||
123 | |||
124 | for rprovide in rprovides: | ||
125 | if not rprovide in self.rproviders: | ||
126 | self.rproviders[rprovide] = [] | ||
127 | self.rproviders[rprovide].append(file_name) | ||
128 | |||
105 | # Collect files we may need for possible world-dep | 129 | # Collect files we may need for possible world-dep |
106 | # calculations | 130 | # calculations |
107 | if not bb.data.getVar('BROKEN', bb_data, True) and not bb.data.getVar('EXCLUDE_FROM_WORLD', bb_data, True): | 131 | if not bb.data.getVar('BROKEN', bb_data, True) and not bb.data.getVar('EXCLUDE_FROM_WORLD', bb_data, True): |
@@ -158,6 +182,7 @@ class BBCooker: | |||
158 | def __init__( self ): | 182 | def __init__( self ): |
159 | self.build_cache_fail = [] | 183 | self.build_cache_fail = [] |
160 | self.build_cache = [] | 184 | self.build_cache = [] |
185 | self.rbuild_cache = [] | ||
161 | self.building_list = [] | 186 | self.building_list = [] |
162 | self.build_path = [] | 187 | self.build_path = [] |
163 | self.consider_msgs_cache = [] | 188 | self.consider_msgs_cache = [] |
@@ -194,14 +219,29 @@ class BBCooker: | |||
194 | self.build_cache_fail.append(fn) | 219 | self.build_cache_fail.append(fn) |
195 | raise | 220 | raise |
196 | 221 | ||
197 | def tryBuild( self, fn, virtual ): | 222 | def tryBuild( self, fn, virtual , buildAllDeps , build_depends = []): |
198 | """Build a provider and its dependencies""" | 223 | """ |
199 | if fn in self.building_list: | 224 | Build a provider and its dependencies. |
225 | build_depends is a list of previous build dependencies (not runtime) | ||
226 | If build_depends is empty, we're dealing with a runtime depends | ||
227 | """ | ||
228 | |||
229 | the_data = self.pkgdata[fn] | ||
230 | |||
231 | if not buildAllDeps: | ||
232 | buildAllDeps = bb.data.getVar('BUILD_ALL_DEPS', the_data, True) or False | ||
233 | |||
234 | # Error on build time dependency loops | ||
235 | if build_depends and build_depends.count(fn) > 1: | ||
200 | bb.error("%s depends on itself (eventually)" % fn) | 236 | bb.error("%s depends on itself (eventually)" % fn) |
201 | bb.error("upwards chain is: %s" % (" -> ".join(self.build_path))) | 237 | bb.error("upwards chain is: %s" % (" -> ".join(self.build_path))) |
202 | return False | 238 | return False |
203 | 239 | ||
204 | the_data = self.pkgdata[fn] | 240 | # See if this is a runtime dependency we've already built |
241 | # Or a build dependency being handled in a different build chain | ||
242 | if fn in self.building_list: | ||
243 | return self.addRunDeps(fn, virtual , buildAllDeps) | ||
244 | |||
205 | item = self.status.pkg_fn[fn] | 245 | item = self.status.pkg_fn[fn] |
206 | 246 | ||
207 | self.building_list.append(fn) | 247 | self.building_list.append(fn) |
@@ -209,7 +249,8 @@ class BBCooker: | |||
209 | pathstr = "%s (%s)" % (item, virtual) | 249 | pathstr = "%s (%s)" % (item, virtual) |
210 | self.build_path.append(pathstr) | 250 | self.build_path.append(pathstr) |
211 | 251 | ||
212 | depends_list = (bb.data.getVar('DEPENDS', the_data, 1) or "").split() | 252 | depends_list = (bb.data.getVar('DEPENDS', the_data, True) or "").split() |
253 | |||
213 | if self.configuration.verbose: | 254 | if self.configuration.verbose: |
214 | bb.note("current path: %s" % (" -> ".join(self.build_path))) | 255 | bb.note("current path: %s" % (" -> ".join(self.build_path))) |
215 | bb.note("dependencies for %s are: %s" % (item, " ".join(depends_list))) | 256 | bb.note("dependencies for %s are: %s" % (item, " ".join(depends_list))) |
@@ -234,7 +275,7 @@ class BBCooker: | |||
234 | continue | 275 | continue |
235 | if not depcmd: | 276 | if not depcmd: |
236 | continue | 277 | continue |
237 | if self.buildProvider( dependency ) == 0: | 278 | if self.buildProvider( dependency , buildAllDeps , build_depends ) == 0: |
238 | bb.error("dependency %s (for %s) not satisfied" % (dependency,item)) | 279 | bb.error("dependency %s (for %s) not satisfied" % (dependency,item)) |
239 | failed = True | 280 | failed = True |
240 | if self.configuration.abort: | 281 | if self.configuration.abort: |
@@ -247,6 +288,9 @@ class BBCooker: | |||
247 | self.stats.deps += 1 | 288 | self.stats.deps += 1 |
248 | return False | 289 | return False |
249 | 290 | ||
291 | if not self.addRunDeps(fn, virtual , buildAllDeps): | ||
292 | return False | ||
293 | |||
250 | if bb.build.stamp_is_current('do_%s' % self.configuration.cmd, the_data): | 294 | if bb.build.stamp_is_current('do_%s' % self.configuration.cmd, the_data): |
251 | self.build_cache.append(fn) | 295 | self.build_cache.append(fn) |
252 | return True | 296 | return True |
@@ -285,7 +329,7 @@ class BBCooker: | |||
285 | bb.data.setVar('OVERRIDES', "%s:%s" % (pn, data.getVar('OVERRIDES', localdata)), localdata) | 329 | bb.data.setVar('OVERRIDES', "%s:%s" % (pn, data.getVar('OVERRIDES', localdata)), localdata) |
286 | bb.data.update_data(localdata) | 330 | bb.data.update_data(localdata) |
287 | 331 | ||
288 | preferred_v = bb.data.getVar('PREFERRED_VERSION_%s' % pn, localdata, 1) | 332 | preferred_v = bb.data.getVar('PREFERRED_VERSION_%s' % pn, localdata, True) |
289 | if preferred_v: | 333 | if preferred_v: |
290 | m = re.match('(.*)_(.*)', preferred_v) | 334 | m = re.match('(.*)_(.*)', preferred_v) |
291 | if m: | 335 | if m: |
@@ -379,28 +423,17 @@ class BBCooker: | |||
379 | if data.getVarFlag( e, 'python', self.configuration.data ): | 423 | if data.getVarFlag( e, 'python', self.configuration.data ): |
380 | sys.__stdout__.write("\npython %s () {\n%s}\n" % (e, data.getVar(e, self.configuration.data, 1))) | 424 | sys.__stdout__.write("\npython %s () {\n%s}\n" % (e, data.getVar(e, self.configuration.data, 1))) |
381 | 425 | ||
382 | def buildProvider( self, item ): | 426 | def filterProviders(self, providers, item): |
383 | fn = None | 427 | """ |
384 | 428 | Take a list of providers and filter/reorder according to the | |
385 | discriminated = False | 429 | environment variables and previous build results |
386 | 430 | """ | |
387 | if item not in self.status.providers: | ||
388 | bb.error("Nothing provides %s" % item) | ||
389 | return 0 | ||
390 | |||
391 | all_p = self.status.providers[item] | ||
392 | |||
393 | for p in all_p: | ||
394 | if p in self.build_cache: | ||
395 | bb.debug(1, "already built %s in this run\n" % p) | ||
396 | return 1 | ||
397 | |||
398 | eligible = [] | 431 | eligible = [] |
399 | preferred_versions = {} | 432 | preferred_versions = {} |
400 | 433 | ||
401 | # Collate providers by PN | 434 | # Collate providers by PN |
402 | pkg_pn = {} | 435 | pkg_pn = {} |
403 | for p in all_p: | 436 | for p in providers: |
404 | pn = self.status.pkg_fn[p] | 437 | pn = self.status.pkg_fn[p] |
405 | if pn not in pkg_pn: | 438 | if pn not in pkg_pn: |
406 | pkg_pn[pn] = [] | 439 | pkg_pn[pn] = [] |
@@ -423,7 +456,7 @@ class BBCooker: | |||
423 | 456 | ||
424 | # look to see if one of them is already staged, or marked as preferred. | 457 | # look to see if one of them is already staged, or marked as preferred. |
425 | # if so, bump it to the head of the queue | 458 | # if so, bump it to the head of the queue |
426 | for p in all_p: | 459 | for p in providers: |
427 | the_data = self.pkgdata[p] | 460 | the_data = self.pkgdata[p] |
428 | pn = bb.data.getVar('PN', the_data, 1) | 461 | pn = bb.data.getVar('PN', the_data, 1) |
429 | pv = bb.data.getVar('PV', the_data, 1) | 462 | pv = bb.data.getVar('PV', the_data, 1) |
@@ -448,6 +481,33 @@ class BBCooker: | |||
448 | discriminated = True | 481 | discriminated = True |
449 | break | 482 | break |
450 | 483 | ||
484 | return eligible | ||
485 | |||
486 | def buildProvider( self, item , buildAllDeps , build_depends = [] ): | ||
487 | """ | ||
488 | Build something to provide a named build requirement | ||
489 | (takes item names from DEPENDS namespace) | ||
490 | """ | ||
491 | |||
492 | fn = None | ||
493 | discriminated = False | ||
494 | |||
495 | if not item in self.status.providers: | ||
496 | bb.error("Nothing provides dependency %s" % item) | ||
497 | return 0 | ||
498 | |||
499 | all_p = self.status.providers[item] | ||
500 | |||
501 | for p in all_p: | ||
502 | if p in self.build_cache: | ||
503 | bb.debug(1, "already built %s in this run\n" % p) | ||
504 | return 1 | ||
505 | |||
506 | eligible = self.filterProviders(all_p, item) | ||
507 | |||
508 | if not eligible: | ||
509 | return 0 | ||
510 | |||
451 | prefervar = bb.data.getVar('PREFERRED_PROVIDER_%s' % item, self.configuration.data, 1) | 511 | prefervar = bb.data.getVar('PREFERRED_PROVIDER_%s' % item, self.configuration.data, 1) |
452 | if prefervar: | 512 | if prefervar: |
453 | self.preferred[item] = prefervar | 513 | self.preferred[item] = prefervar |
@@ -476,12 +536,140 @@ class BBCooker: | |||
476 | # run through the list until we find one that we can build | 536 | # run through the list until we find one that we can build |
477 | for fn in eligible: | 537 | for fn in eligible: |
478 | bb.debug(2, "selecting %s to satisfy %s" % (fn, item)) | 538 | bb.debug(2, "selecting %s to satisfy %s" % (fn, item)) |
479 | if self.tryBuild(fn, item): | 539 | if self.tryBuild(fn, item, buildAllDeps, build_depends + [fn]): |
480 | return 1 | 540 | return 1 |
481 | 541 | ||
482 | bb.note("no buildable providers for %s" % item) | 542 | bb.note("no buildable providers for %s" % item) |
483 | return 0 | 543 | return 0 |
484 | 544 | ||
545 | def buildRProvider( self, item , buildAllDeps ): | ||
546 | """ | ||
547 | Build something to provide a named runtime requirement | ||
548 | (takes item names from RDEPENDS/PACKAGES namespace) | ||
549 | """ | ||
550 | |||
551 | fn = None | ||
552 | all_p = [] | ||
553 | discriminated = False | ||
554 | |||
555 | if not buildAllDeps: | ||
556 | return True | ||
557 | |||
558 | all_p = self.getProvidersRun(item) | ||
559 | |||
560 | if not all_p: | ||
561 | bb.error("Nothing provides runtime dependency %s" % (item)) | ||
562 | return False | ||
563 | |||
564 | for p in all_p: | ||
565 | if p in self.rbuild_cache: | ||
566 | bb.debug(2, "Already built %s providing runtime %s\n" % (p,item)) | ||
567 | return True | ||
568 | if p in self.build_cache: | ||
569 | bb.debug(2, "Already built %s but adding any further RDEPENDS for %s\n" % (p, item)) | ||
570 | return self.addRunDeps(p, item , buildAllDeps) | ||
571 | |||
572 | eligible = self.filterProviders(all_p, item) | ||
573 | if not eligible: | ||
574 | return 0 | ||
575 | |||
576 | preferred = [] | ||
577 | for p in eligible: | ||
578 | pn = self.status.pkg_fn[p] | ||
579 | provides = self.status.pn_provides[pn] | ||
580 | for provide in provides: | ||
581 | prefervar = bb.data.getVar('PREFERRED_PROVIDER_%s' % provide, self.configuration.data, 1) | ||
582 | if prefervar == pn: | ||
583 | if self.configuration.verbose: | ||
584 | bb.note("selecting %s to satisfy runtime %s due to PREFERRED_PROVIDERS" % (pn, item)) | ||
585 | eligible.remove(p) | ||
586 | eligible = [p] + eligible | ||
587 | preferred.append(p) | ||
588 | |||
589 | if len(eligible) > 1 and len(preferred) == 0: | ||
590 | if item not in self.consider_msgs_cache: | ||
591 | providers_list = [] | ||
592 | for fn in eligible: | ||
593 | providers_list.append(self.status.pkg_fn[fn]) | ||
594 | bb.note("multiple providers are available (%s);" % ", ".join(providers_list)) | ||
595 | bb.note("consider defining a PREFERRED_PROVIDER to match runtime %s" % item) | ||
596 | self.consider_msgs_cache.append(item) | ||
597 | |||
598 | if len(preferred) > 1: | ||
599 | if item not in self.consider_msgs_cache: | ||
600 | providers_list = [] | ||
601 | for fn in preferred: | ||
602 | providers_list.append(self.status.pkg_fn[fn]) | ||
603 | bb.note("multiple preferred providers are available (%s);" % ", ".join(providers_list)) | ||
604 | bb.note("consider defining only one PREFERRED_PROVIDER to match runtime %s" % item) | ||
605 | self.consider_msgs_cache.append(item) | ||
606 | |||
607 | # run through the list until we find one that we can build | ||
608 | for fn in eligible: | ||
609 | bb.debug(2, "selecting %s to satisfy runtime %s" % (fn, item)) | ||
610 | if self.tryBuild(fn, item, buildAllDeps): | ||
611 | return True | ||
612 | |||
613 | bb.error("No buildable providers for runtime %s" % item) | ||
614 | return False | ||
615 | |||
616 | def getProvidersRun(self, rdepend): | ||
617 | """ | ||
618 | Return any potential providers of runtime rdepend | ||
619 | """ | ||
620 | rproviders = [] | ||
621 | |||
622 | if rdepend in self.status.rproviders: | ||
623 | rproviders += self.status.rproviders[rdepend] | ||
624 | |||
625 | if rdepend in self.status.packages: | ||
626 | rproviders += self.status.packages[rdepend] | ||
627 | |||
628 | if rproviders: | ||
629 | return rproviders | ||
630 | |||
631 | # Only search dynamic packages if we can't find anything in other variables | ||
632 | for pattern in self.status.packages_dynamic: | ||
633 | regexp = re.compile(pattern) | ||
634 | if regexp.match(rdepend): | ||
635 | rproviders += self.status.packages_dynamic[pattern] | ||
636 | |||
637 | return rproviders | ||
638 | |||
639 | def addRunDeps(self , fn, item , buildAllDeps): | ||
640 | """ | ||
641 | Add any runtime dependencies of runtime item provided by fn | ||
642 | as long as item has't previously been processed by this function. | ||
643 | """ | ||
644 | |||
645 | if item in self.rbuild_cache: | ||
646 | return True | ||
647 | |||
648 | if not buildAllDeps: | ||
649 | return True | ||
650 | |||
651 | rdepends = [] | ||
652 | self.rbuild_cache.append(item) | ||
653 | the_data = self.pkgdata[fn] | ||
654 | pn = self.status.pkg_fn[fn] | ||
655 | |||
656 | if (item == pn): | ||
657 | rdepends += bb.utils.explode_deps(bb.data.getVar('RDEPENDS', the_data, True) or "") | ||
658 | rdepends += bb.utils.explode_deps(bb.data.getVar('RRECOMMENDS', the_data, True) or "") | ||
659 | else: | ||
660 | packages = (bb.data.getVar('PACKAGES', the_data, 1).split() or "") | ||
661 | for package in packages: | ||
662 | if package == item: | ||
663 | rdepends += bb.utils.explode_deps(bb.data.getVar("RDEPENDS_%s" % package, the_data, True) or "") | ||
664 | rdepends += bb.utils.explode_deps(bb.data.getVar("RRECOMMENDS_%s" % package, the_data, True) or "") | ||
665 | |||
666 | bb.debug(2, "Additional runtime dependencies for %s are: %s" % (item, " ".join(rdepends))) | ||
667 | |||
668 | for rdepend in rdepends: | ||
669 | if not self.buildRProvider(rdepend, buildAllDeps): | ||
670 | return False | ||
671 | return True | ||
672 | |||
485 | def buildDepgraph( self ): | 673 | def buildDepgraph( self ): |
486 | all_depends = self.status.all_depends | 674 | all_depends = self.status.all_depends |
487 | pn_provides = self.status.pn_provides | 675 | pn_provides = self.status.pn_provides |
@@ -694,7 +882,7 @@ class BBCooker: | |||
694 | for k in pkgs_to_build: | 882 | for k in pkgs_to_build: |
695 | failed = False | 883 | failed = False |
696 | try: | 884 | try: |
697 | if self.buildProvider( k ) == 0: | 885 | if self.buildProvider( k , False ) == 0: |
698 | # already diagnosed | 886 | # already diagnosed |
699 | failed = True | 887 | failed = True |
700 | except bb.build.EventException: | 888 | except bb.build.EventException: |
diff --git a/bitbake/bin/bitbakec b/bitbake/bin/bitbakec index dc2e0a9fa9..db6a160303 100644 --- a/bitbake/bin/bitbakec +++ b/bitbake/bin/bitbakec | |||
Binary files differ | |||