diff options
| author | Richard Purdie <richard@openedhand.com> | 2007-04-01 15:04:49 +0000 |
|---|---|---|
| committer | Richard Purdie <richard@openedhand.com> | 2007-04-01 15:04:49 +0000 |
| commit | 7371e6323c3fb6b0545712e3cf84606644073e77 (patch) | |
| tree | e08f25669ec0f0e9d11334909f3b68c0ab6aca19 /bitbake/lib/bb | |
| parent | 8b36dc217443aeeec8493d39561d2bb010336774 (diff) | |
| download | openembedded-core-7371e6323c3fb6b0545712e3cf84606644073e77.tar.gz openembedded-core-7371e6323c3fb6b0545712e3cf84606644073e77.tar.bz2 openembedded-core-7371e6323c3fb6b0545712e3cf84606644073e77.zip | |
bitbake: Update to 1.8.1 (inc. various bug fixes, epoch support)
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@1419 311d38ba-8fff-0310-9ca6-ca027cbcb966
Diffstat (limited to 'bitbake/lib/bb')
| -rw-r--r-- | bitbake/lib/bb/__init__.py | 2 | ||||
| -rw-r--r-- | bitbake/lib/bb/build.py | 3 | ||||
| -rw-r--r-- | bitbake/lib/bb/cache.py | 10 | ||||
| -rw-r--r-- | bitbake/lib/bb/cooker.py | 318 | ||||
| -rw-r--r-- | bitbake/lib/bb/event.py | 5 | ||||
| -rw-r--r-- | bitbake/lib/bb/fetch/svn.py | 6 | ||||
| -rw-r--r-- | bitbake/lib/bb/msg.py | 31 | ||||
| -rw-r--r-- | bitbake/lib/bb/parse/parse_py/ConfHandler.py | 16 | ||||
| -rw-r--r-- | bitbake/lib/bb/providers.py | 47 | ||||
| -rw-r--r-- | bitbake/lib/bb/runqueue.py | 355 | ||||
| -rw-r--r-- | bitbake/lib/bb/shell.py | 25 | ||||
| -rw-r--r-- | bitbake/lib/bb/taskdata.py | 13 | ||||
| -rw-r--r-- | bitbake/lib/bb/utils.py | 8 |
13 files changed, 465 insertions, 374 deletions
diff --git a/bitbake/lib/bb/__init__.py b/bitbake/lib/bb/__init__.py index a11af84b12..e34122a61e 100644 --- a/bitbake/lib/bb/__init__.py +++ b/bitbake/lib/bb/__init__.py @@ -21,7 +21,7 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -__version__ = "1.7.4" +__version__ = "1.8.1" __all__ = [ diff --git a/bitbake/lib/bb/build.py b/bitbake/lib/bb/build.py index bf6b612f32..3494c0a28e 100644 --- a/bitbake/lib/bb/build.py +++ b/bitbake/lib/bb/build.py @@ -188,7 +188,8 @@ def exec_func_shell(func, d): maybe_fakeroot = "PATH=\"%s\" fakeroot " % bb.data.getVar("PATH", d, 1) else: maybe_fakeroot = '' - ret = os.system('%ssh -e %s' % (maybe_fakeroot, runfile)) + lang_environment = "LC_ALL=C " + ret = os.system('%s%ssh -e %s' % (lang_environment, maybe_fakeroot, runfile)) try: os.chdir(prevdir) except: diff --git a/bitbake/lib/bb/cache.py b/bitbake/lib/bb/cache.py index 934d230e6a..335b221979 100644 --- a/bitbake/lib/bb/cache.py +++ b/bitbake/lib/bb/cache.py @@ -39,7 +39,7 @@ except ImportError: import pickle bb.msg.note(1, bb.msg.domain.Cache, "Importing cPickle failed. Falling back to a very slow implementation.") -__cache_version__ = "125" +__cache_version__ = "126" class Cache: """ @@ -75,6 +75,9 @@ class Cache: raise ValueError, 'Cache Version Mismatch' if version_data['BITBAKE_VER'] != bb.__version__: raise ValueError, 'Bitbake Version Mismatch' + except EOFError: + bb.msg.note(1, bb.msg.domain.Cache, "Truncated cache found, rebuilding...") + self.depends_cache = {} except (ValueError, KeyError): bb.msg.note(1, bb.msg.domain.Cache, "Invalid cache found, rebuilding...") self.depends_cache = {} @@ -251,6 +254,7 @@ class Cache: """ pn = self.getVar('PN', file_name, True) + pe = self.getVar('PE', file_name, True) or "0" pv = self.getVar('PV', file_name, True) pr = self.getVar('PR', file_name, True) dp = int(self.getVar('DEFAULT_PREFERENCE', file_name, True) or "0") @@ -272,7 +276,7 @@ class Cache: # build FileName to PackageName lookup table cacheData.pkg_fn[file_name] = pn - cacheData.pkg_pvpr[file_name] = (pv,pr) + cacheData.pkg_pepvpr[file_name] = (pe,pv,pr) cacheData.pkg_dp[file_name] = dp # Build forward and reverse provider hashes @@ -407,7 +411,7 @@ class CacheData: self.possible_world = [] self.pkg_pn = {} self.pkg_fn = {} - self.pkg_pvpr = {} + self.pkg_pepvpr = {} self.pkg_dp = {} self.pn_provides = {} self.all_depends = Set() diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py index 8a9c588633..4b2a906133 100644 --- a/bitbake/lib/bb/cooker.py +++ b/bitbake/lib/bb/cooker.py @@ -31,29 +31,6 @@ import itertools parsespin = itertools.cycle( r'|/-\\' ) #============================================================================# -# BBStatistics -#============================================================================# -class BBStatistics: - """ - Manage build statistics for one run - """ - def __init__(self ): - self.attempt = 0 - self.success = 0 - self.fail = 0 - self.deps = 0 - - def show( self ): - print "Build statistics:" - print " Attempted builds: %d" % self.attempt - if self.fail: - print " Failed builds: %d" % self.fail - if self.deps: - print " Dependencies not satisfied: %d" % self.deps - if self.fail or self.deps: return 1 - else: return 0 - -#============================================================================# # BBCooker #============================================================================# class BBCooker: @@ -61,43 +38,61 @@ class BBCooker: Manages one bitbake build run """ - Statistics = BBStatistics # make it visible from the shell - - def __init__( self ): - self.build_cache_fail = [] - self.build_cache = [] - self.stats = BBStatistics() + def __init__(self, configuration): self.status = None self.cache = None self.bb_cache = None + self.configuration = configuration + + if self.configuration.verbose: + bb.msg.set_verbose(True) + + if self.configuration.debug: + bb.msg.set_debug_level(self.configuration.debug) + else: + bb.msg.set_debug_level(0) + + if self.configuration.debug_domains: + bb.msg.set_debug_domains(self.configuration.debug_domains) + + self.configuration.data = bb.data.init() + + for f in self.configuration.file: + self.parseConfigurationFile( f ) + + self.parseConfigurationFile( os.path.join( "conf", "bitbake.conf" ) ) + + if not self.configuration.cmd: + self.configuration.cmd = bb.data.getVar("BB_DEFAULT_TASK", self.configuration.data) or "build" + + # + # Special updated configuration we use for firing events + # + self.configuration.event_data = bb.data.createCopy(self.configuration.data) + bb.data.update_data(self.configuration.event_data) + def tryBuildPackage(self, fn, item, task, the_data, build_depends): """ Build one task of a package, optionally build following task depends """ bb.event.fire(bb.event.PkgStarted(item, the_data)) try: - self.stats.attempt += 1 if not build_depends: bb.data.setVarFlag('do_%s' % task, 'dontrundeps', 1, the_data) if not self.configuration.dry_run: bb.build.exec_task('do_%s' % task, the_data) bb.event.fire(bb.event.PkgSucceeded(item, the_data)) - self.build_cache.append(fn) return True except bb.build.FuncFailed: - self.stats.fail += 1 bb.msg.error(bb.msg.domain.Build, "task stack execution failed") bb.event.fire(bb.event.PkgFailed(item, the_data)) - self.build_cache_fail.append(fn) raise except bb.build.EventException, e: - self.stats.fail += 1 event = e.args[1] bb.msg.error(bb.msg.domain.Build, "%s event exception, aborting" % bb.event.getName(event)) bb.event.fire(bb.event.PkgFailed(item, the_data)) - self.build_cache_fail.append(fn) raise def tryBuild( self, fn, build_depends): @@ -112,12 +107,11 @@ class BBCooker: item = self.status.pkg_fn[fn] if bb.build.stamp_is_current('do_%s' % self.configuration.cmd, the_data): - self.build_cache.append(fn) return True return self.tryBuildPackage(fn, item, self.configuration.cmd, the_data, build_depends) - def showVersions( self ): + def showVersions(self): pkg_pn = self.status.pkg_pn preferred_versions = {} latest_versions = {} @@ -136,11 +130,11 @@ class BBCooker: latest = latest_versions[p] if pref != latest: - prefstr = pref[0][0] + "-" + pref[0][1] + prefstr = pref[0][0] + ":" + pref[0][1] + '-' + pref[0][2] else: prefstr = "" - print "%-30s %20s %20s" % (p, latest[0][0] + "-" + latest[0][1], + print "%-30s %20s %20s" % (p, latest[0][0] + ":" + latest[0][1] + "-" + latest[0][2], prefstr) @@ -192,8 +186,8 @@ class BBCooker: taskdata.add_unresolved(localdata, self.status) except bb.providers.NoProvider: sys.exit(1) - rq = bb.runqueue.RunQueue() - rq.prepare_runqueue(self, self.configuration.data, self.status, taskdata, runlist) + rq = bb.runqueue.RunQueue(self, self.configuration.data, self.status, taskdata, runlist) + rq.prepare_runqueue() seen_fnids = [] depends_file = file('depends.dot', 'w' ) @@ -371,98 +365,138 @@ class BBCooker: except ValueError: bb.msg.error(bb.msg.domain.Parsing, "invalid value for BBFILE_PRIORITY_%s: \"%s\"" % (c, priority)) + def buildSetVars(self): + """ + Setup any variables needed before starting a build + """ + if not bb.data.getVar("BUILDNAME", self.configuration.data): + bb.data.setVar("BUILDNAME", os.popen('date +%Y%m%d%H%M').readline().strip(), self.configuration.data) + bb.data.setVar("BUILDSTART", time.strftime('%m/%d/%Y %H:%M:%S',time.gmtime()),self.configuration.data) - def cook(self, configuration): + def buildFile(self, buildfile): """ - We are building stuff here. We do the building - from here. By default we try to execute task - build. + Build the file matching regexp buildfile """ - self.configuration = configuration + bf = os.path.abspath(buildfile) + try: + os.stat(bf) + except OSError: + (filelist, masked) = self.collect_bbfiles() + regexp = re.compile(buildfile) + matches = [] + for f in filelist: + if regexp.search(f) and os.path.isfile(f): + bf = f + matches.append(f) + if len(matches) != 1: + bb.msg.error(bb.msg.domain.Parsing, "Unable to match %s (%s matches found):" % (buildfile, len(matches))) + for f in matches: + bb.msg.error(bb.msg.domain.Parsing, " %s" % f) + sys.exit(1) + bf = matches[0] - if self.configuration.verbose: - bb.msg.set_verbose(True) + bbfile_data = bb.parse.handle(bf, self.configuration.data) - if self.configuration.debug: - bb.msg.set_debug_level(self.configuration.debug) + # Remove stamp for target if force mode active + if self.configuration.force: + bb.msg.note(2, bb.msg.domain.RunQueue, "Remove stamp %s, %s" % (self.configuration.cmd, bf)) + bb.build.del_stamp('do_%s' % self.configuration.cmd, bbfile_data) + + item = bb.data.getVar('PN', bbfile_data, 1) + try: + self.tryBuildPackage(bf, item, self.configuration.cmd, bbfile_data, True) + except bb.build.EventException: + bb.msg.error(bb.msg.domain.Build, "Build of '%s' failed" % item ) + + sys.exit(0) + + def buildTargets(self, targets): + """ + Attempt to build the targets specified + """ + + buildname = bb.data.getVar("BUILDNAME", self.configuration.data) + bb.event.fire(bb.event.BuildStarted(buildname, targets, self.configuration.event_data)) + + localdata = data.createCopy(self.configuration.data) + bb.data.update_data(localdata) + bb.data.expandKeys(localdata) + + taskdata = bb.taskdata.TaskData(self.configuration.abort) + + runlist = [] + try: + for k in targets: + taskdata.add_provider(localdata, self.status, k) + runlist.append([k, "do_%s" % self.configuration.cmd]) + taskdata.add_unresolved(localdata, self.status) + except bb.providers.NoProvider: + sys.exit(1) + + rq = bb.runqueue.RunQueue(self, self.configuration.data, self.status, taskdata, runlist) + rq.prepare_runqueue() + try: + failures = rq.execute_runqueue() + except runqueue.TaskFailure, fnids: + for fnid in fnids: + bb.msg.error(bb.msg.domain.Build, "'%s' failed" % taskdata.fn_index[fnid]) + sys.exit(1) + bb.event.fire(bb.event.BuildCompleted(buildname, targets, self.configuration.event_data, failures)) + + sys.exit(0) + + def updateCache(self): + # Import Psyco if available and not disabled + if not self.configuration.disable_psyco: + try: + import psyco + except ImportError: + bb.msg.note(1, bb.msg.domain.Collection, "Psyco JIT Compiler (http://psyco.sf.net) not available. Install it to increase performance.") + else: + psyco.bind( self.parse_bbfiles ) else: - bb.msg.set_debug_level(0) + bb.msg.note(1, bb.msg.domain.Collection, "You have disabled Psyco. This decreases performance.") - if self.configuration.debug_domains: - bb.msg.set_debug_domains(self.configuration.debug_domains) + self.status = bb.cache.CacheData() - self.configuration.data = bb.data.init() + ignore = bb.data.getVar("ASSUME_PROVIDED", self.configuration.data, 1) or "" + self.status.ignored_dependencies = Set( ignore.split() ) - for f in self.configuration.file: - self.parseConfigurationFile( f ) + self.handleCollections( bb.data.getVar("BBFILE_COLLECTIONS", self.configuration.data, 1) ) - self.parseConfigurationFile( os.path.join( "conf", "bitbake.conf" ) ) + bb.msg.debug(1, bb.msg.domain.Collection, "collecting .bb files") + (filelist, masked) = self.collect_bbfiles() + self.parse_bbfiles(filelist, masked, self.myProgressCallback) + bb.msg.debug(1, bb.msg.domain.Collection, "parsing complete") - if not self.configuration.cmd: - self.configuration.cmd = bb.data.getVar("BB_DEFAULT_TASK", self.configuration.data) or "build" + self.buildDepgraph() - # - # Special updated configuration we use for firing events - # - self.configuration.event_data = bb.data.createCopy(self.configuration.data) - bb.data.update_data(self.configuration.event_data) + def cook(self): + """ + We are building stuff here. We do the building + from here. By default we try to execute task + build. + """ if self.configuration.show_environment: self.showEnvironment() sys.exit( 0 ) - # inject custom variables - if not bb.data.getVar("BUILDNAME", self.configuration.data): - bb.data.setVar("BUILDNAME", os.popen('date +%Y%m%d%H%M').readline().strip(), self.configuration.data) - bb.data.setVar("BUILDSTART", time.strftime('%m/%d/%Y %H:%M:%S',time.gmtime()),self.configuration.data) - - buildname = bb.data.getVar("BUILDNAME", self.configuration.data) + self.buildSetVars() if self.configuration.interactive: self.interactiveMode() if self.configuration.buildfile is not None: - bf = os.path.abspath( self.configuration.buildfile ) - try: - os.stat(bf) - except OSError: - (filelist, masked) = self.collect_bbfiles() - regexp = re.compile(self.configuration.buildfile) - matches = [] - for f in filelist: - if regexp.search(f) and os.path.isfile(f): - bf = f - matches.append(f) - if len(matches) != 1: - bb.msg.error(bb.msg.domain.Parsing, "Unable to match %s (%s matches found):" % (self.configuration.buildfile, len(matches))) - for f in matches: - bb.msg.error(bb.msg.domain.Parsing, " %s" % f) - sys.exit(1) - bf = matches[0] - - bbfile_data = bb.parse.handle(bf, self.configuration.data) - - # Remove stamp for target if force mode active - if self.configuration.force: - bb.msg.note(2, bb.msg.domain.RunQueue, "Remove stamp %s, %s" % (self.configuration.cmd, bf)) - bb.build.del_stamp('do_%s' % self.configuration.cmd, bbfile_data) - - item = bb.data.getVar('PN', bbfile_data, 1) - try: - self.tryBuildPackage(bf, item, self.configuration.cmd, bbfile_data, True) - except bb.build.EventException: - bb.msg.error(bb.msg.domain.Build, "Build of '%s' failed" % item ) - - sys.exit( self.stats.show() ) + return self.buildFile(self.configuration.buildfile) # initialise the parsing status now we know we will need deps - self.status = bb.cache.CacheData() + self.updateCache() - ignore = bb.data.getVar("ASSUME_PROVIDED", self.configuration.data, 1) or "" - self.status.ignored_dependencies = Set( ignore.split() ) - - self.handleCollections( bb.data.getVar("BBFILE_COLLECTIONS", self.configuration.data, 1) ) + if self.configuration.parse_only: + bb.msg.note(1, bb.msg.domain.Collection, "Requested parsing .bb files only. Exiting.") + return 0 pkgs_to_build = self.configuration.pkgs_to_build @@ -475,30 +509,7 @@ class BBCooker: print "for usage information." sys.exit(0) - # Import Psyco if available and not disabled - if not self.configuration.disable_psyco: - try: - import psyco - except ImportError: - bb.msg.note(1, bb.msg.domain.Collection, "Psyco JIT Compiler (http://psyco.sf.net) not available. Install it to increase performance.") - else: - psyco.bind( self.parse_bbfiles ) - else: - bb.msg.note(1, bb.msg.domain.Collection, "You have disabled Psyco. This decreases performance.") - try: - bb.msg.debug(1, bb.msg.domain.Collection, "collecting .bb files") - (filelist, masked) = self.collect_bbfiles() - self.parse_bbfiles(filelist, masked, self.myProgressCallback) - bb.msg.debug(1, bb.msg.domain.Collection, "parsing complete") - print - if self.configuration.parse_only: - bb.msg.note(1, bb.msg.domain.Collection, "Requested parsing .bb files only. Exiting.") - return - - - self.buildDepgraph() - if self.configuration.show_versions: self.showVersions() sys.exit( 0 ) @@ -512,34 +523,7 @@ class BBCooker: self.generateDotGraph( pkgs_to_build, self.configuration.ignored_dot_deps ) sys.exit( 0 ) - bb.event.fire(bb.event.BuildStarted(buildname, pkgs_to_build, self.configuration.event_data)) - - localdata = data.createCopy(self.configuration.data) - bb.data.update_data(localdata) - bb.data.expandKeys(localdata) - - taskdata = bb.taskdata.TaskData(self.configuration.abort) - - runlist = [] - try: - for k in pkgs_to_build: - taskdata.add_provider(localdata, self.status, k) - runlist.append([k, "do_%s" % self.configuration.cmd]) - taskdata.add_unresolved(localdata, self.status) - except bb.providers.NoProvider: - sys.exit(1) - - rq = bb.runqueue.RunQueue() - rq.prepare_runqueue(self, self.configuration.data, self.status, taskdata, runlist) - try: - failures = rq.execute_runqueue(self, self.configuration.data, self.status, taskdata, runlist) - except runqueue.TaskFailure, fnids: - for fnid in fnids: - bb.msg.error(bb.msg.domain.Build, "'%s' failed" % taskdata.fn_index[fnid]) - sys.exit(1) - bb.event.fire(bb.event.BuildCompleted(buildname, pkgs_to_build, self.configuration.event_data, failures)) - - sys.exit( self.stats.show() ) + return self.buildTargets(pkgs_to_build) except KeyboardInterrupt: bb.msg.note(1, bb.msg.domain.Collection, "KeyboardInterrupt - Build not completed.") @@ -556,13 +540,17 @@ class BBCooker: return bbfiles def find_bbfiles( self, path ): - """Find all the .bb files in a directory (uses find)""" - findcmd = 'find ' + path + ' -name *.bb | grep -v SCCS/' - try: - finddata = os.popen(findcmd) - except OSError: - return [] - return finddata.readlines() + """Find all the .bb files in a directory""" + from os.path import join + + found = [] + for dir, dirs, files in os.walk(path): + for ignored in ('SCCS', 'CVS', '.svn'): + if ignored in dirs: + dirs.remove(ignored) + found += [join(dir,f) for f in files if f.endswith('.bb')] + + return found def collect_bbfiles( self ): """Collect all available .bb build files""" diff --git a/bitbake/lib/bb/event.py b/bitbake/lib/bb/event.py index f1da98fd45..cfbda3e9fc 100644 --- a/bitbake/lib/bb/event.py +++ b/bitbake/lib/bb/event.py @@ -23,14 +23,13 @@ BitBake build tools. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import os, re -import bb.data import bb.utils class Event: """Base class for events""" type = "Event" - def __init__(self, d = bb.data.init()): + def __init__(self, d): self._data = d def getData(self): @@ -129,7 +128,7 @@ def getName(e): class PkgBase(Event): """Base class for package events""" - def __init__(self, t, d = bb.data.init()): + def __init__(self, t, d): self._pkg = t Event.__init__(self, d) diff --git a/bitbake/lib/bb/fetch/svn.py b/bitbake/lib/bb/fetch/svn.py index 21be1412a6..120f4f8539 100644 --- a/bitbake/lib/bb/fetch/svn.py +++ b/bitbake/lib/bb/fetch/svn.py @@ -91,6 +91,12 @@ class Svn(Fetch): elif ud.date != "now": options.append("-r {%s}" % ud.date) + if ud.user: + options.append("--username %s" % ud.user) + + if ud.pswd: + options.append("--password %s" % ud.pswd) + localdata = data.createCopy(d) data.setVar('OVERRIDES', "svn:%s" % data.getVar('OVERRIDES', localdata), localdata) data.update_data(localdata) diff --git a/bitbake/lib/bb/msg.py b/bitbake/lib/bb/msg.py index bd7729731a..71b0b05b77 100644 --- a/bitbake/lib/bb/msg.py +++ b/bitbake/lib/bb/msg.py @@ -23,7 +23,7 @@ Message handling infrastructure for bitbake # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. import sys, os, re, bb -from bb import utils +from bb import utils, event debug_level = {} @@ -42,6 +42,29 @@ domain = bb.utils.Enum( 'TaskData', 'Util') + +class MsgBase(bb.event.Event): + """Base class for messages""" + + def __init__(self, msg, d ): + self._message = msg + event.Event.__init__(self, d) + +class MsgDebug(MsgBase): + """Debug Message""" + +class MsgNote(MsgBase): + """Note Message""" + +class MsgWarn(MsgBase): + """Warning Message""" + +class MsgError(MsgBase): + """Error Message""" + +class MsgFatal(MsgBase): + """Fatal Message""" + # # Message control functions # @@ -71,6 +94,7 @@ def set_debug_domains(domains): def debug(level, domain, msg, fn = None): if debug_level[domain] >= level: + bb.event.fire(MsgDebug(msg, None)) print 'DEBUG: ' + msg def note(level, domain, msg, fn = None): @@ -91,17 +115,22 @@ def fatal(domain, msg, fn = None): # def std_debug(lvl, msg): if debug_level['default'] >= lvl: + bb.event.fire(MsgDebug(msg, None)) print 'DEBUG: ' + msg def std_note(msg): + bb.event.fire(MsgNote(msg, None)) print 'NOTE: ' + msg def std_warn(msg): + bb.event.fire(MsgWarn(msg, None)) print 'WARNING: ' + msg def std_error(msg): + bb.event.fire(MsgError(msg, None)) print 'ERROR: ' + msg def std_fatal(msg): + bb.event.fire(MsgFatal(msg, None)) print 'ERROR: ' + msg sys.exit(1) diff --git a/bitbake/lib/bb/parse/parse_py/ConfHandler.py b/bitbake/lib/bb/parse/parse_py/ConfHandler.py index 1ae673079d..0e05928d84 100644 --- a/bitbake/lib/bb/parse/parse_py/ConfHandler.py +++ b/bitbake/lib/bb/parse/parse_py/ConfHandler.py @@ -161,6 +161,12 @@ def handle(fn, data, include = 0): return data def feeder(lineno, s, fn, data): + def getFunc(groupd, key, data): + if 'flag' in groupd and groupd['flag'] != None: + return bb.data.getVarFlag(key, groupd['flag'], data) + else: + return bb.data.getVar(key, data) + m = __config_regexp__.match(s) if m: groupd = m.groupdict() @@ -168,19 +174,19 @@ def feeder(lineno, s, fn, data): if "exp" in groupd and groupd["exp"] != None: bb.data.setVarFlag(key, "export", 1, data) if "ques" in groupd and groupd["ques"] != None: - val = bb.data.getVar(key, data) + val = getFunc(groupd, key, data) if val == None: val = groupd["value"] elif "colon" in groupd and groupd["colon"] != None: val = bb.data.expand(groupd["value"], data) elif "append" in groupd and groupd["append"] != None: - val = "%s %s" % ((bb.data.getVar(key, data) or ""), groupd["value"]) + val = "%s %s" % ((getFunc(groupd, key, data) or ""), groupd["value"]) elif "prepend" in groupd and groupd["prepend"] != None: - val = "%s %s" % (groupd["value"], (bb.data.getVar(key, data) or "")) + val = "%s %s" % (groupd["value"], (getFunc(groupd, key, data) or "")) elif "postdot" in groupd and groupd["postdot"] != None: - val = "%s%s" % ((bb.data.getVar(key, data) or ""), groupd["value"]) + val = "%s%s" % ((getFunc(groupd, key, data) or ""), groupd["value"]) elif "predot" in groupd and groupd["predot"] != None: - val = "%s%s" % (groupd["value"], (bb.data.getVar(key, data) or "")) + val = "%s%s" % (groupd["value"], (getFunc(groupd, key, data) or "")) else: val = groupd["value"] if 'flag' in groupd and groupd['flag'] != None: diff --git a/bitbake/lib/bb/providers.py b/bitbake/lib/bb/providers.py index fdd6cd10d1..78f45122ff 100644 --- a/bitbake/lib/bb/providers.py +++ b/bitbake/lib/bb/providers.py @@ -61,19 +61,27 @@ def findBestProvider(pn, cfgData, dataCache, pkg_pn = None, item = None): preferred_v = bb.data.getVar('PREFERRED_VERSION_%s' % pn, localdata, True) if preferred_v: - m = re.match('(.*)_(.*)', preferred_v) + m = re.match('(\d+:)*(.*)(_.*)*', preferred_v) if m: - preferred_v = m.group(1) - preferred_r = m.group(2) + if m.group(1): + preferred_e = int(m.group(1)[:-1]) + else: + preferred_e = None + preferred_v = m.group(2) + if m.group(3): + preferred_r = m.group(3)[1:] + else: + preferred_r = None else: + preferred_e = None preferred_r = None for file_set in tmp_pn: for f in file_set: - pv,pr = dataCache.pkg_pvpr[f] - if preferred_v == pv and (preferred_r == pr or preferred_r == None): + pe,pv,pr = dataCache.pkg_pepvpr[f] + if preferred_v == pv and (preferred_r == pr or preferred_r == None) and (preferred_e == pe or preferred_e == None): preferred_file = f - preferred_ver = (pv, pr) + preferred_ver = (pe, pv, pr) break if preferred_file: break; @@ -81,6 +89,8 @@ def findBestProvider(pn, cfgData, dataCache, pkg_pn = None, item = None): pv_str = '%s-%s' % (preferred_v, preferred_r) else: pv_str = preferred_v + if not (preferred_e is None): + pv_str = '%s:%s' % (preferred_e, pv_str) itemstr = "" if item: itemstr = " (for item %s)" % item @@ -97,11 +107,11 @@ def findBestProvider(pn, cfgData, dataCache, pkg_pn = None, item = None): latest_p = 0 latest_f = None for file_name in files: - pv,pr = dataCache.pkg_pvpr[file_name] + pe,pv,pr = dataCache.pkg_pepvpr[file_name] dp = dataCache.pkg_dp[file_name] - if (latest is None) or ((latest_p == dp) and (utils.vercmp(latest, (pv, pr)) < 0)) or (dp > latest_p): - latest = (pv, pr) + if (latest is None) or ((latest_p == dp) and (utils.vercmp(latest, (pe, pv, pr)) < 0)) or (dp > latest_p): + latest = (pe, pv, pr) latest_f = file_name latest_p = dp if preferred_file is None: @@ -110,10 +120,7 @@ def findBestProvider(pn, cfgData, dataCache, pkg_pn = None, item = None): return (latest,latest_f,preferred_ver, preferred_file) -# -# RP - build_cache_fail needs to move elsewhere -# -def filterProviders(providers, item, cfgData, dataCache, build_cache_fail = {}): +def filterProviders(providers, item, cfgData, dataCache): """ Take a list of providers and filter/reorder according to the environment variables and previous build results @@ -135,12 +142,6 @@ def filterProviders(providers, item, cfgData, dataCache, build_cache_fail = {}): preferred_versions[pn] = bb.providers.findBestProvider(pn, cfgData, dataCache, pkg_pn, item)[2:4] eligible.append(preferred_versions[pn][1]) - - for p in eligible: - if p in build_cache_fail: - bb.msg.debug(1, bb.msg.domain.Provider, "rejecting already-failed %s" % p) - eligible.remove(p) - if len(eligible) == 0: bb.msg.error(bb.msg.domain.Provider, "no eligible providers for %s" % item) return 0 @@ -162,7 +163,7 @@ def filterProviders(providers, item, cfgData, dataCache, build_cache_fail = {}): # if so, bump it to the head of the queue for p in providers: pn = dataCache.pkg_fn[p] - pv, pr = dataCache.pkg_pvpr[p] + pe, pv, pr = dataCache.pkg_pepvpr[p] stamp = '%s.do_populate_staging' % dataCache.stamp[p] if os.path.exists(stamp): @@ -171,7 +172,11 @@ def filterProviders(providers, item, cfgData, dataCache, build_cache_fail = {}): # package was made ineligible by already-failed check continue oldver = "%s-%s" % (pv, pr) - newver = '-'.join(newvers) + if pe > 0: + oldver = "%s:%s" % (pe, oldver) + newver = "%s-%s" % (newvers[1], newvers[2]) + if newvers[0] > 0: + newver = "%s:%s" % (newvers[0], newver) if (newver != oldver): extra_chat = "%s (%s) already staged but upgrading to %s to satisfy %s" % (pn, oldver, newver, item) else: diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py index ec94b0f8ba..059f800b65 100644 --- a/bitbake/lib/bb/runqueue.py +++ b/bitbake/lib/bb/runqueue.py @@ -25,20 +25,47 @@ Handles preparation and execution of a queue of tasks from bb import msg, data, fetch, event, mkdirhier, utils from sets import Set import bb, os, sys +import signal class TaskFailure(Exception): """Exception raised when a task in a runqueue fails""" def __init__(self, x): self.args = x + +class RunQueueStats: + """ + Holds statistics on the tasks handled by the associated runQueue + """ + def __init__(self): + self.completed = 0 + self.skipped = 0 + self.failed = 0 + + def taskFailed(self): + self.failed = self.failed + 1 + + def taskCompleted(self): + self.completed = self.completed + 1 + + def taskSkipped(self): + self.skipped = self.skipped + 1 + class RunQueue: """ BitBake Run Queue implementation """ - def __init__(self): + def __init__(self, cooker, cfgData, dataCache, taskData, targets): self.rese |
