summaryrefslogtreecommitdiffstats
path: root/bitbake/bin/bitbake
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/bin/bitbake')
-rwxr-xr-xbitbake/bin/bitbake244
1 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: