summaryrefslogtreecommitdiff
path: root/bitbake/lib
diff options
context:
space:
mode:
authorRichard Purdie <richard@openedhand.com>2006-11-16 15:02:15 +0000
committerRichard Purdie <richard@openedhand.com>2006-11-16 15:02:15 +0000
commit306b7c7a9757ead077363074e7bbac2e5c03e7c5 (patch)
tree6935017a9af749c46816881c86258f514384ba1c /bitbake/lib
parent65930a38e415ae4a0182e1cea1be838e0ada50ee (diff)
downloadopenembedded-core-306b7c7a9757ead077363074e7bbac2e5c03e7c5.tar.gz
openembedded-core-306b7c7a9757ead077363074e7bbac2e5c03e7c5.tar.bz2
openembedded-core-306b7c7a9757ead077363074e7bbac2e5c03e7c5.zip
bitbake: Upgrade from 1.4 -> 1.7.4ish
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@863 311d38ba-8fff-0310-9ca6-ca027cbcb966
Diffstat (limited to 'bitbake/lib')
-rw-r--r--bitbake/lib/bb/COW.py305
-rw-r--r--bitbake/lib/bb/__init__.py27
-rw-r--r--bitbake/lib/bb/build.py110
-rw-r--r--bitbake/lib/bb/cache.py207
-rw-r--r--bitbake/lib/bb/data.py49
-rw-r--r--bitbake/lib/bb/data_smart.py43
-rw-r--r--bitbake/lib/bb/fetch/__init__.py167
-rw-r--r--bitbake/lib/bb/fetch/cvs.py255
-rw-r--r--bitbake/lib/bb/fetch/git.py144
-rw-r--r--bitbake/lib/bb/fetch/local.py18
-rw-r--r--bitbake/lib/bb/fetch/perforce.py213
-rw-r--r--bitbake/lib/bb/fetch/ssh.py94
-rw-r--r--bitbake/lib/bb/fetch/svk.py160
-rw-r--r--bitbake/lib/bb/fetch/svn.py203
-rw-r--r--bitbake/lib/bb/fetch/wget.py152
-rw-r--r--bitbake/lib/bb/methodpool.py3
-rw-r--r--bitbake/lib/bb/msg.py108
-rw-r--r--bitbake/lib/bb/parse/__init__.py11
-rw-r--r--bitbake/lib/bb/parse/parse_c/BBHandler.py151
-rw-r--r--bitbake/lib/bb/parse/parse_c/Makefile16
-rw-r--r--bitbake/lib/bb/parse/parse_c/bitbakec.pyx205
-rw-r--r--bitbake/lib/bb/parse/parse_c/bitbakeparser.cc144
-rw-r--r--bitbake/lib/bb/parse/parse_c/bitbakescanner.cc218
-rw-r--r--bitbake/lib/bb/parse/parse_c/bitbakescanner.l30
-rw-r--r--bitbake/lib/bb/parse/parse_c/lexer.h8
-rw-r--r--bitbake/lib/bb/parse/parse_c/lexerc.h2
-rw-r--r--bitbake/lib/bb/parse/parse_py/BBHandler.py28
-rw-r--r--bitbake/lib/bb/parse/parse_py/ConfHandler.py33
-rw-r--r--bitbake/lib/bb/providers.py209
-rw-r--r--bitbake/lib/bb/runqueue.py491
-rw-r--r--bitbake/lib/bb/shell.py113
-rw-r--r--bitbake/lib/bb/taskdata.py558
-rw-r--r--bitbake/lib/bb/utils.py54
33 files changed, 3343 insertions, 1186 deletions
diff --git a/bitbake/lib/bb/COW.py b/bitbake/lib/bb/COW.py
new file mode 100644
index 0000000000..826d435f98
--- /dev/null
+++ b/bitbake/lib/bb/COW.py
@@ -0,0 +1,305 @@
+# ex:ts=4:sw=4:sts=4:et
+# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
+"""
+This is a copy on write dictionary and set which abuses classes to try and be nice and fast.
+
+Please Note:
+ Be careful when using mutable types (ie Dict and Lists) - operations involving these are SLOW.
+ Assign a file to __warn__ to get warnings about slow operations.
+"""
+
+from inspect import getmro
+
+import copy
+import types, sets
+types.ImmutableTypes = tuple([ \
+ types.BooleanType, \
+ types.ComplexType, \
+ types.FloatType, \
+ types.IntType, \
+ types.LongType, \
+ types.NoneType, \
+ types.TupleType, \
+ sets.ImmutableSet] + \
+ list(types.StringTypes))
+
+MUTABLE = "__mutable__"
+
+class COWMeta(type):
+ pass
+
+class COWDictMeta(COWMeta):
+ __warn__ = False
+ __hasmutable__ = False
+ __marker__ = tuple()
+
+ def __str__(cls):
+ # FIXME: I have magic numbers!
+ return "<COWDict Level: %i Current Keys: %i>" % (cls.__count__, len(cls.__dict__) - 3)
+ __repr__ = __str__
+
+ def cow(cls):
+ class C(cls):
+ __count__ = cls.__count__ + 1
+ return C
+ copy = cow
+ __call__ = cow
+
+ def __setitem__(cls, key, value):
+ if not isinstance(value, types.ImmutableTypes):
+ if not isinstance(value, COWMeta):
+ cls.__hasmutable__ = True
+ key += MUTABLE
+ setattr(cls, key, value)
+
+ def __getmutable__(cls, key, readonly=False):
+ nkey = key + MUTABLE
+ try:
+ return cls.__dict__[nkey]
+ except KeyError:
+ pass
+
+ value = getattr(cls, nkey)
+ if readonly:
+ return value
+
+ if not cls.__warn__ is False and not isinstance(value, COWMeta):
+ print >> cls.__warn__, "Warning: Doing a copy because %s is a mutable type." % key
+ try:
+ value = value.copy()
+ except AttributeError, e:
+ value = copy.copy(value)
+ setattr(cls, nkey, value)
+ return value
+
+ __getmarker__ = []
+ def __getreadonly__(cls, key, default=__getmarker__):
+ """\
+ Get a value (even if mutable) which you promise not to change.
+ """
+ return cls.__getitem__(key, default, True)
+
+ def __getitem__(cls, key, default=__getmarker__, readonly=False):
+ try:
+ try:
+ value = getattr(cls, key)
+ except AttributeError:
+ value = cls.__getmutable__(key, readonly)
+
+ # This is for values which have been deleted
+ if value is cls.__marker__:
+ raise AttributeError("key %s does not exist." % key)
+
+ return value
+ except AttributeError, e:
+ if not default is cls.__getmarker__:
+ return default
+
+ raise KeyError(str(e))
+
+ def __delitem__(cls, key):
+ cls.__setitem__(key, cls.__marker__)
+
+ def __revertitem__(cls, key):
+ if not cls.__dict__.has_key(key):
+ key += MUTABLE
+ delattr(cls, key)
+
+ def has_key(cls, key):
+ value = cls.__getreadonly__(key, cls.__marker__)
+ if value is cls.__marker__:
+ return False
+ return True
+
+ def iter(cls, type, readonly=False):
+ for key in dir(cls):
+ if key.startswith("__"):
+ continue
+
+ if key.endswith(MUTABLE):
+ key = key[:-len(MUTABLE)]
+
+ if type == "keys":
+ yield key
+
+ try:
+ if readonly:
+ value = cls.__getreadonly__(key)
+ else:
+ value = cls[key]
+ except KeyError:
+ continue
+
+ if type == "values":
+ yield value
+ if type == "items":
+ yield (key, value)
+ raise StopIteration()
+
+ def iterkeys(cls):
+ return cls.iter("keys")
+ def itervalues(cls, readonly=False):
+ if not cls.__warn__ is False and cls.__hasmutable__ and readonly is False:
+ print >> cls.__warn__, "Warning: If you arn't going to change any of the values call with True."
+ return cls.iter("values", readonly)
+ def iteritems(cls, readonly=False):
+ if not cls.__warn__ is False and cls.__hasmutable__ and readonly is False:
+ print >> cls.__warn__, "Warning: If you arn't going to change any of the values call with True."
+ return cls.iter("items", readonly)
+
+class COWSetMeta(COWDictMeta):
+ def __str__(cls):
+ # FIXME: I have magic numbers!
+ return "<COWSet Level: %i Current Keys: %i>" % (cls.__count__, len(cls.__dict__) -3)
+ __repr__ = __str__
+
+ def cow(cls):
+ class C(cls):
+ __count__ = cls.__count__ + 1
+ return C
+
+ def add(cls, value):
+ COWDictMeta.__setitem__(cls, repr(hash(value)), value)
+
+ def remove(cls, value):
+ COWDictMeta.__delitem__(cls, repr(hash(value)))
+
+ def __in__(cls, value):
+ return COWDictMeta.has_key(repr(hash(value)))
+
+ def iterkeys(cls):
+ raise TypeError("sets don't have keys")
+
+ def iteritems(cls):
+ raise TypeError("sets don't have 'items'")
+
+# These are the actual classes you use!
+class COWDictBase(object):
+ __metaclass__ = COWDictMeta
+ __count__ = 0
+
+class COWSetBase(object):
+ __metaclass__ = COWSetMeta
+ __count__ = 0
+
+if __name__ == "__main__":
+ import sys
+ COWDictBase.__warn__ = sys.stderr
+ a = COWDictBase()
+ print "a", a
+
+ a['a'] = 'a'
+ a['b'] = 'b'
+ a['dict'] = {}
+
+ b = a.copy()
+ print "b", b
+ b['c'] = 'b'
+
+ print
+
+ print "a", a
+ for x in a.iteritems():
+ print x
+ print "--"
+ print "b", b
+ for x in b.iteritems():
+ print x
+ print
+
+ b['dict']['a'] = 'b'
+ b['a'] = 'c'
+
+ print "a", a
+ for x in a.iteritems():
+ print x
+ print "--"
+ print "b", b
+ for x in b.iteritems():
+ print x
+ print
+
+ try:
+ b['dict2']
+ except KeyError, e:
+ print "Okay!"
+
+ a['set'] = COWSetBase()
+ a['set'].add("o1")
+ a['set'].add("o1")
+ a['set'].add("o2")
+
+ print "a", a
+ for x in a['set'].itervalues():
+ print x
+ print "--"
+ print "b", b
+ for x in b['set'].itervalues():
+ print x
+ print
+
+ b['set'].add('o3')
+
+ print "a", a
+ for x in a['set'].itervalues():
+ print x
+ print "--"
+ print "b", b
+ for x in b['set'].itervalues():
+ print x
+ print
+
+ a['set2'] = set()
+ a['set2'].add("o1")
+ a['set2'].add("o1")
+ a['set2'].add("o2")
+
+ print "a", a
+ for x in a.iteritems():
+ print x
+ print "--"
+ print "b", b
+ for x in b.iteritems(readonly=True):
+ print x
+ print
+
+ del b['b']
+ try:
+ print b['b']
+ except KeyError:
+ print "Yay! deleted key raises error"
+
+ if b.has_key('b'):
+ print "Boo!"
+ else:
+ print "Yay - has_key with delete works!"
+
+ print "a", a
+ for x in a.iteritems():
+ print x
+ print "--"
+ print "b", b
+ for x in b.iteritems(readonly=True):
+ print x
+ print
+
+ b.__revertitem__('b')
+
+ print "a", a
+ for x in a.iteritems():
+ print x
+ print "--"
+ print "b", b
+ for x in b.iteritems(readonly=True):
+ print x
+ print
+
+ b.__revertitem__('dict')
+ print "a", a
+ for x in a.iteritems():
+ print x
+ print "--"
+ print "b", b
+ for x in b.iteritems(readonly=True):
+ print x
+ print
diff --git a/bitbake/lib/bb/__init__.py b/bitbake/lib/bb/__init__.py
index c3e7a16658..61eb5f3db8 100644
--- a/bitbake/lib/bb/__init__.py
+++ b/bitbake/lib/bb/__init__.py
@@ -23,7 +23,7 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA.
"""
-__version__ = "1.4.3"
+__version__ = "1.7.4"
__all__ = [
@@ -63,24 +63,24 @@ __all__ = [
"manifest",
"methodpool",
"cache",
+ "runqueue",
+ "taskdata",
+ "providers",
]
whitespace = '\t\n\x0b\x0c\r '
lowercase = 'abcdefghijklmnopqrstuvwxyz'
-import sys, os, types, re, string
+import sys, os, types, re, string, bb
+from bb import msg
#projectdir = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))
projectdir = os.getcwd()
-debug_level = 0
-
if "BBDEBUG" in os.environ:
level = int(os.environ["BBDEBUG"])
if level:
- debug_level = level
- else:
- debug_level = 0
+ bb.msg.set_debug_level(level)
class VarExpandError(Exception):
pass
@@ -99,22 +99,17 @@ class MalformedUrl(Exception):
#######################################################################
#######################################################################
-debug_prepend = ''
-
-
def debug(lvl, *args):
- if debug_level >= lvl:
- print debug_prepend + 'DEBUG:', ''.join(args)
+ bb.msg.std_debug(lvl, ''.join(args))
def note(*args):
- print debug_prepend + 'NOTE:', ''.join(args)
+ bb.msg.std_note(''.join(args))
def error(*args):
- print debug_prepend + 'ERROR:', ''.join(args)
+ bb.msg.std_error(''.join(args))
def fatal(*args):
- print debug_prepend + 'ERROR:', ''.join(args)
- sys.exit(1)
+ bb.msg.std_fatal(''.join(args))
#######################################################################
diff --git a/bitbake/lib/bb/build.py b/bitbake/lib/bb/build.py
index 8e169e002a..942bdc1a39 100644
--- a/bitbake/lib/bb/build.py
+++ b/bitbake/lib/bb/build.py
@@ -25,18 +25,9 @@ You should have received a copy of the GNU General Public License along with
Based on functions from the base bb module, Copyright 2003 Holger Schurig
"""
-from bb import debug, data, fetch, fatal, error, note, event, mkdirhier, utils
+from bb import data, fetch, event, mkdirhier, utils
import bb, os
-# data holds flags and function name for a given task
-_task_data = data.init()
-
-# graph represents task interdependencies
-_task_graph = bb.digraph()
-
-# stack represents execution order, excepting dependencies
-_task_stack = []
-
# events
class FuncFailed(Exception):
"""Executed function failed"""
@@ -76,13 +67,6 @@ class InvalidTask(TaskBase):
# functions
-def init(data):
- global _task_data, _task_graph, _task_stack
- _task_data = data.init()
- _task_graph = bb.digraph()
- _task_stack = []
-
-
def exec_func(func, d, dirs = None):
"""Execute an BB 'function'"""
@@ -163,7 +147,7 @@ def exec_func_shell(func, d):
f = open(runfile, "w")
f.write("#!/bin/sh -e\n")
- if bb.debug_level > 0: f.write("set -x\n")
+ if bb.msg.debug_level['default'] > 0: f.write("set -x\n")
data.emit_env(f, d)
f.write("cd %s\n" % os.getcwd())
@@ -171,18 +155,18 @@ def exec_func_shell(func, d):
f.close()
os.chmod(runfile, 0775)
if not func:
- error("Function not specified")
+ bb.msg.error(bb.msg.domain.Build, "Function not specified")
raise FuncFailed()
# open logs
si = file('/dev/null', 'r')
try:
- if bb.debug_level > 0:
+ if bb.msg.debug_level['default'] > 0:
so = os.popen("tee \"%s\"" % logfile, "w")
else:
so = file(logfile, 'w')
except OSError, e:
- bb.error("opening log file: %s" % e)
+ bb.msg.error(bb.msg.domain.Build, "opening log file: %s" % e)
pass
se = so
@@ -205,7 +189,10 @@ def exec_func_shell(func, d):
else:
maybe_fakeroot = ''
ret = os.system('%ssh -e %s' % (maybe_fakeroot, runfile))
- os.chdir(prevdir)
+ try:
+ os.chdir(prevdir)
+ except:
+ pass
if not interact:
# restore the backups
@@ -224,14 +211,14 @@ def exec_func_shell(func, d):
os.close(ose[0])
if ret==0:
- if bb.debug_level > 0:
+ if bb.msg.debug_level['default'] > 0:
os.remove(runfile)
# os.remove(logfile)
return
else:
- error("function %s failed" % func)
+ bb.msg.error(bb.msg.domain.Build, "function %s failed" % func)
if data.getVar("BBINCLUDELOGS", d):
- error("log data follows (%s)" % logfile)
+ bb.msg.error(bb.msg.domain.Build, "log data follows (%s)" % logfile)
f = open(logfile, "r")
while True:
l = f.readline()
@@ -241,7 +228,7 @@ def exec_func_shell(func, d):
print '| %s' % l
f.close()
else:
- error("see log in %s" % logfile)
+ bb.msg.error(bb.msg.domain.Build, "see log in %s" % logfile)
raise FuncFailed( logfile )
@@ -281,7 +268,7 @@ def exec_task(task, d):
return 1
try:
- debug(1, "Executing task %s" % item)
+ bb.msg.debug(1, bb.msg.domain.Build, "Executing task %s" % item)
old_overrides = data.getVar('OVERRIDES', d, 0)
localdata = data.createCopy(d)
data.setVar('OVERRIDES', 'task_%s:%s' % (item, old_overrides), localdata)
@@ -292,21 +279,63 @@ def exec_task(task, d):
task_cache.append(item)
data.setVar('_task_cache', task_cache, d)
except FuncFailed, reason:
- note( "Task failed: %s" % reason )
+ bb.msg.note(1, bb.msg.domain.Build, "Task failed: %s" % reason )
failedevent = TaskFailed(item, d)
event.fire(failedevent)
raise EventException("Function failed in task: %s" % reason, failedevent)
- # execute
- task_graph.walkdown(task, execute)
+ if data.getVarFlag(task, 'dontrundeps', d):
+ execute(None, task)
+ else:
+ task_graph.walkdown(task, execute)
# make stamp, or cause event and raise exception
if not data.getVarFlag(task, 'nostamp', d):
mkstamp(task, d)
+def stamp_is_current_cache(dataCache, file_name, task, checkdeps = 1):
+ """
+ Check status of a given task's stamp.
+ Returns 0 if it is not current and needs updating.
+ Same as stamp_is_current but works against the dataCache instead of d
+ """
+ task_graph = dataCache.task_queues[file_name]
+
+ if not dataCache.stamp[file_name]:
+ return 0
+
+ stampfile = "%s.%s" % (dataCache.stamp[file_name], task)
+ if not os.access(stampfile, os.F_OK):
+ return 0
+
+ if checkdeps == 0:
+ return 1
+
+ import stat
+ tasktime = os.stat(stampfile)[stat.ST_MTIME]
+
+ _deps = []
+ def checkStamp(graph, task):
+ # check for existance
+ if 'nostamp' in dataCache.task_deps[file_name] and task in dataCache.task_deps[file_name]['nostamp']:
+ return 1
+
+ if not stamp_is_current_cache(dataCache, file_name, task, 0):
+ return 0
+
+ depfile = "%s.%s" % (dataCache.stamp[file_name], task)
+ deptime = os.stat(depfile)[stat.ST_MTIME]
+ if deptime > tasktime:
+ return 0
+ return 1
+
+ return task_graph.walkdown(task, checkStamp)
def stamp_is_current(task, d, checkdeps = 1):
- """Check status of a given task's stamp. returns 0 if it is not current and needs updating."""
+ """
+ Check status of a given task's stamp.
+ Returns 0 if it is not current and needs updating.
+ """
task_graph = data.getVar('_task_graph', d)
if not task_graph:
task_graph = bb.digraph()
@@ -360,7 +389,6 @@ def mkstamp(task, d):
f = open(stamp, "w")
f.close()
-
def add_task(task, deps, d):
task_graph = data.getVar('_task_graph', d)
if not task_graph:
@@ -374,6 +402,21 @@ def add_task(task, deps, d):
# don't assume holding a reference
data.setVar('_task_graph', task_graph, d)
+ task_deps = data.getVar('_task_deps', d)
+ if not task_deps:
+ task_deps = {}
+ def getTask(name):
+ deptask = data.getVarFlag(task, name, d)
+ if deptask:
+ if not name in task_deps:
+ task_deps[name] = {}
+ task_deps[name][task] = deptask
+ getTask('deptask')
+ getTask('rdeptask')
+ getTask('recrdeptask')
+ getTask('nostamp')
+
+ data.setVar('_task_deps', task_deps, d)
def remove_task(task, kill, d):
"""Remove an BB 'task'.
@@ -399,6 +442,3 @@ def task_exists(task, d):
task_graph = bb.digraph()
data.setVar('_task_graph', task_graph, d)
return task_graph.hasnode(task)
-
-def get_task_data():
- return _task_data
diff --git a/bitbake/lib/bb/cache.py b/bitbake/lib/bb/cache.py
index 921a9f7589..05c42518a7 100644
--- a/bitbake/lib/bb/cache.py
+++ b/bitbake/lib/bb/cache.py
@@ -33,15 +33,15 @@ Place, Suite 330, Boston, MA 02111-1307 USA.
import os, re
import bb.data
import bb.utils
+from sets import Set
try:
import cPickle as pickle
except ImportError:
import pickle
- print "NOTE: Importing cPickle failed. Falling back to a very slow implementation."
+ bb.msg.note(1, bb.msg.domain.Cache, "Importing cPickle failed. Falling back to a very slow implementation.")
-# __cache_version__ = "123"
-__cache_version__ = "124" # changes the __depends structure
+__cache_version__ = "125"
class Cache:
"""
@@ -58,14 +58,12 @@ class Cache:
if self.cachedir in [None, '']:
self.has_cache = False
- if cooker.cb is not None:
- print "NOTE: Not using a cache. Set CACHE = <directory> to enable."
+ bb.msg.note(1, bb.msg.domain.Cache, "Not using a cache. Set CACHE = <directory> to enable.")
else:
self.has_cache = True
self.cachefile = os.path.join(self.cachedir,"bb_cache.dat")
- if cooker.cb is not None:
- print "NOTE: Using cache in '%s'" % self.cachedir
+ bb.msg.debug(1, bb.msg.domain.Cache, "Using cache in '%s'" % self.cachedir)
try:
os.stat( self.cachedir )
except OSError:
@@ -80,7 +78,7 @@ class Cache:
if version_data['BITBAKE_VER'] != bb.__version__:
raise ValueError, 'Bitbake Version Mismatch'
except (ValueError, KeyError):
- bb.note("Invalid cache found, rebuilding...")
+ bb.msg.note(1, bb.msg.domain.Cache, "Invalid cache found, rebuilding...")
self.depends_cache = {}
if self.depends_cache:
@@ -108,7 +106,7 @@ class Cache:
if fn != self.data_fn:
# We're trying to access data in the cache which doesn't exist
# yet setData hasn't been called to setup the right access. Very bad.
- bb.error("Parsing error data_fn %s and fn %s don't match" % (self.data_fn, fn))
+ bb.msg.error(bb.msg.domain.Cache, "Parsing error data_fn %s and fn %s don't match" % (self.data_fn, fn))
result = bb.data.getVar(var, self.data, exp)
self.depends_cache[fn][var] = result
@@ -127,15 +125,15 @@ class Cache:
self.getVar("__depends", fn, True)
self.depends_cache[fn]["CACHETIMESTAMP"] = bb.parse.cached_mtime(fn)
- def loadDataFull(self, fn, cooker):
+ def loadDataFull(self, fn, cfgData):
"""
Return a complete set of data for fn.
To do this, we need to parse the file.
"""
- bb_data, skipped = self.load_bbfile(fn, cooker)
+ bb_data, skipped = self.load_bbfile(fn, cfgData)
return bb_data
- def loadData(self, fn, cooker):
+ def loadData(self, fn, cfgData):
"""
Load a subset of data for fn.
If the cached data is valid we do nothing,
@@ -148,7 +146,7 @@ class Cache:
return True, True
return True, False
- bb_data, skipped = self.load_bbfile(fn, cooker)
+ bb_data, skipped = self.load_bbfile(fn, cfgData)
self.setData(fn, bb_data)
return False, skipped
@@ -175,32 +173,36 @@ class Cache:
# Check file still exists
if self.mtime(fn) == 0:
- bb.debug(2, "Cache: %s not longer exists" % fn)
+ bb.msg.debug(2, bb.msg.domain.Cache, "Cache: %s not longer exists" % fn)
self.remove(fn)
return False
# File isn't in depends_cache
if not fn in self.depends_cache:
- bb.debug(2, "Cache: %s is not cached" % fn)
+ bb.msg.debug(2, bb.msg.domain.Cache, "Cache: %s is not cached" % fn)
self.remove(fn)
return False
# Check the file's timestamp
if bb.parse.cached_mtime(fn) > self.getVar("CACHETIMESTAMP", fn, True):
- bb.debug(2, "Cache: %s changed" % fn)
+ bb.msg.debug(2, bb.msg.domain.Cache, "Cache: %s changed" % fn)
self.remove(fn)
return False
# Check dependencies are still valid
depends = self.getVar("__depends", fn, True)
for f,old_mtime in depends:
+ # Check if file still exists
+ if self.mtime(f) == 0:
+ return False
+
new_mtime = bb.parse.cached_mtime(f)
if (new_mtime > old_mtime):
- bb.debug(2, "Cache: %s's dependency %s changed" % (fn, f))
+ bb.msg.debug(2, bb.msg.domain.Cache, "Cache: %s's dependency %s changed" % (fn, f))
self.remove(fn)
return False
- bb.debug(2, "Depends Cache: %s is clean" % fn)
+ bb.msg.debug(2, bb.msg.domain.Cache, "Depends Cache: %s is clean" % fn)
if not fn in self.clean:
self.clean[fn] = ""
@@ -220,7 +222,7 @@ class Cache:
Remove a fn from the cache
Called from the parser in error cases
"""
- bb.debug(1, "Removing %s from cache" % fn)
+ bb.msg.debug(1, bb.msg.domain.Cache, "Removing %s from cache" % fn)
if fn in self.depends_cache:
del self.depends_cache[fn]
if fn in self.clean:
@@ -229,7 +231,7 @@ class Cache:
def sync(self):
"""
Save the cache
- Called from the parser when complete (or exitting)
+ Called from the parser when complete (or exiting)
"""
if not self.has_cache:
@@ -243,12 +245,103 @@ class Cache:
p.dump([self.depends_cache, version_data])
def mtime(self, cachefile):
- try:
- return os.stat(cachefile)[8]
- except OSError:
- return 0
+ return bb.parse.cached_mtime_noerror(cachefile)
- def load_bbfile( self, bbfile , cooker):
+ def handle_data(self, file_name, cacheData):
+ """
+ Save data we need into the cache
+ """
+
+ pn = self.getVar('PN', file_name, True)
+ 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")
+ provides = Set([pn] + (self.getVar("PROVIDES", file_name, True) or "").split())
+ depends = bb.utils.explode_deps(self.getVar("DEPENDS", file_name, True) or "")
+ packages = (self.getVar('PACKAGES', file_name, True) or "").split()
+ packages_dynamic = (self.getVar('PACKAGES_DYNAMIC', file_name, True) or "").split()
+ rprovides = (self.getVar("RPROVIDES", file_name, True) or "").split()
+
+ cacheData.task_queues[file_name] = self.getVar("_task_graph", file_name, True)
+ cacheData.task_deps[file_name] = self.getVar("_task_deps", file_name, True)
+
+ # build PackageName to FileName lookup table
+ if pn not in cacheData.pkg_pn:
+ cacheData.pkg_pn[pn] = []
+ cacheData.pkg_pn[pn].append(file_name)
+
+ cacheData.stamp[file_name] = self.getVar('STAMP', file_name, True)
+
+ # build FileName to PackageName lookup table
+ cacheData.pkg_fn[file_name] = pn
+ cacheData.pkg_pvpr[file_name] = (pv,pr)
+ cacheData.pkg_dp[file_name] = dp
+
+ # Build forward and reverse provider hashes
+ # Forward: virtual -> [filenames]
+ # Reverse: PN -> [virtuals]
+ if pn not in cacheData.pn_provides:
+ cacheData.pn_provides[pn] = Set()
+ cacheData.pn_provides[pn] |= provides
+
+ for provide in provides:
+ if provide not in cacheData.providers:
+ cacheData.providers[provide] = []
+ cacheData.providers[provide].append(file_name)
+
+ cacheData.deps[file_name] = Set()
+ for dep in depends:
+ cacheData.all_depends.add(dep)
+ cacheData.deps[file_name].add(dep)
+
+ # Build reverse hash f