summaryrefslogtreecommitdiff
path: root/bitbake/lib/bb/cache.py
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/bb/cache.py')
-rw-r--r--bitbake/lib/bb/cache.py99
1 files changed, 50 insertions, 49 deletions
diff --git a/bitbake/lib/bb/cache.py b/bitbake/lib/bb/cache.py
index 1f180012e..da4546640 100644
--- a/bitbake/lib/bb/cache.py
+++ b/bitbake/lib/bb/cache.py
@@ -28,7 +28,7 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-import os, re
+import os
import bb.data
import bb.utils
@@ -44,10 +44,10 @@ class Cache:
"""
BitBake Cache implementation
"""
- def __init__(self, cooker):
+ def __init__(self, data):
- self.cachedir = bb.data.getVar("CACHE", cooker.configuration.data, True)
+ self.cachedir = bb.data.getVar("CACHE", data, True)
self.clean = {}
self.checked = {}
self.depends_cache = {}
@@ -61,30 +61,28 @@ class Cache:
return
self.has_cache = True
- self.cachefile = os.path.join(self.cachedir,"bb_cache.dat")
+ self.cachefile = os.path.join(self.cachedir, "bb_cache.dat")
bb.msg.debug(1, bb.msg.domain.Cache, "Using cache in '%s'" % self.cachedir)
- try:
- os.stat( self.cachedir )
- except OSError:
- bb.mkdirhier( self.cachedir )
+ bb.utils.mkdirhier(self.cachedir)
# If any of configuration.data's dependencies are newer than the
# cache there isn't even any point in loading it...
newest_mtime = 0
- deps = bb.data.getVar("__depends", cooker.configuration.data, True)
- for f,old_mtime in deps:
- if old_mtime > newest_mtime:
- newest_mtime = old_mtime
+ deps = bb.data.getVar("__depends", data)
+
+ old_mtimes = [old_mtime for f, old_mtime in deps]
+ old_mtimes.append(newest_mtime)
+ newest_mtime = max(old_mtimes)
if bb.parse.cached_mtime_noerror(self.cachefile) >= newest_mtime:
try:
p = pickle.Unpickler(file(self.cachefile, "rb"))
self.depends_cache, version_data = p.load()
if version_data['CACHE_VER'] != __cache_version__:
- raise ValueError, 'Cache Version Mismatch'
+ raise ValueError('Cache Version Mismatch')
if version_data['BITBAKE_VER'] != bb.__version__:
- raise ValueError, 'Bitbake Version Mismatch'
+ raise ValueError('Bitbake Version Mismatch')
except EOFError:
bb.msg.note(1, bb.msg.domain.Cache, "Truncated cache found, rebuilding...")
self.depends_cache = {}
@@ -92,27 +90,23 @@ class Cache:
bb.msg.note(1, bb.msg.domain.Cache, "Invalid cache found, rebuilding...")
self.depends_cache = {}
else:
- try:
- os.stat( self.cachefile )
+ if os.path.isfile(self.cachefile):
bb.msg.note(1, bb.msg.domain.Cache, "Out of date cache found, rebuilding...")
- except OSError:
- pass
def getVar(self, var, fn, exp = 0):
"""
Gets the value of a variable
(similar to getVar in the data class)
-
+
There are two scenarios:
1. We have cached data - serve from depends_cache[fn]
- 2. We're learning what data to cache - serve from data
+ 2. We're learning what data to cache - serve from data
backend but add a copy of the data to the cache.
"""
if fn in self.clean:
return self.depends_cache[fn][var]
- if not fn in self.depends_cache:
- self.depends_cache[fn] = {}
+ self.depends_cache.setdefault(fn, {})
if fn != self.data_fn:
# We're trying to access data in the cache which doesn't exist
@@ -134,14 +128,14 @@ class Cache:
self.data = data
# Make sure __depends makes the depends_cache
- # If we're a virtual class we need to make sure all our depends are appended
+ # If we're a virtual class we need to make sure all our depends are appended
# to the depends of fn.
- depends = self.getVar("__depends", virtualfn, True) or []
+ depends = self.getVar("__depends", virtualfn) or set()
+ self.depends_cache.setdefault(fn, {})
if "__depends" not in self.depends_cache[fn] or not self.depends_cache[fn]["__depends"]:
self.depends_cache[fn]["__depends"] = depends
- for dep in depends:
- if dep not in self.depends_cache[fn]["__depends"]:
- self.depends_cache[fn]["__depends"].append(dep)
+ else:
+ self.depends_cache[fn]["__depends"].update(depends)
# Make sure the variants always make it into the cache too
self.getVar('__VARIANTS', virtualfn, True)
@@ -217,7 +211,7 @@ class Cache:
for data in bb_data:
virtualfn = self.realfn2virtual(fn, data)
self.setData(virtualfn, fn, bb_data[data])
- if self.getVar("__SKIPPED", virtualfn, True):
+ if self.getVar("__SKIPPED", virtualfn):
skipped += 1
bb.msg.debug(1, bb.msg.domain.Cache, "Skipping %s" % virtualfn)
else:
@@ -258,11 +252,11 @@ class Cache:
self.remove(fn)
return False
- mtime = bb.parse.cached_mtime_noerror(fn)
+ mtime = bb.parse.cached_mtime_noerror(fn)
# Check file still exists
if mtime == 0:
- bb.msg.debug(2, bb.msg.domain.Cache, "Cache: %s not longer exists" % fn)
+ bb.msg.debug(2, bb.msg.domain.Cache, "Cache: %s no longer exists" % fn)
self.remove(fn)
return False
@@ -275,7 +269,7 @@ class Cache:
# Check dependencies are still valid
depends = self.getVar("__depends", fn, True)
if depends:
- for f,old_mtime in depends:
+ for f, old_mtime in depends:
fmtime = bb.parse.cached_mtime_noerror(f)
# Check if file still exists
if old_mtime != 0 and fmtime == 0:
@@ -345,14 +339,14 @@ class Cache:
def handle_data(self, file_name, cacheData):
"""
- Save data we need into the cache
+ Save data we need into the cache
"""
pn = self.getVar('PN', file_name, True)
pe = self.getVar('PE', file_name, True) or "0"
pv = self.getVar('PV', file_name, True)
if 'SRCREVINACTION' in pv:
- bb.note("Found SRCREVINACTION in PV (%s) or %s. Please report this bug." % (pv, file_name))
+ bb.msg.note(1, bb.msg.domain.Cache, "Found SRCREVINACTION in PV (%s) or %s. Please report this bug." % (pv, file_name))
pr = self.getVar('PR', file_name, True)
dp = int(self.getVar('DEFAULT_PREFERENCE', file_name, True) or "0")
depends = bb.utils.explode_deps(self.getVar("DEPENDS", file_name, True) or "")
@@ -360,7 +354,7 @@ class Cache:
packages_dynamic = (self.getVar('PACKAGES_DYNAMIC', file_name, True) or "").split()
rprovides = (self.getVar("RPROVIDES", file_name, True) or "").split()
- cacheData.task_deps[file_name] = self.getVar("_task_deps", file_name, True)
+ cacheData.task_deps[file_name] = self.getVar("_task_deps", file_name)
# build PackageName to FileName lookup table
if pn not in cacheData.pkg_pn:
@@ -371,7 +365,7 @@ class Cache:
# build FileName to PackageName lookup table
cacheData.pkg_fn[file_name] = pn
- cacheData.pkg_pepvpr[file_name] = (pe,pv,pr)
+ cacheData.pkg_pepvpr[file_name] = (pe, pv, pr)
cacheData.pkg_dp[file_name] = dp
provides = [pn]
@@ -400,13 +394,13 @@ class Cache:
if not dep in cacheData.all_depends:
cacheData.all_depends.append(dep)
- # Build reverse hash for PACKAGES, so runtime dependencies
+ # Build reverse hash for PACKAGES, so runtime dependencies
# can be be resolved (RDEPENDS, RRECOMMENDS etc.)
for package in packages:
if not package in cacheData.packages:
cacheData.packages[package] = []
cacheData.packages[package].append(file_name)
- rprovides += (self.getVar("RPROVIDES_%s" % package, file_name, 1) or "").split()
+ rprovides += (self.getVar("RPROVIDES_%s" % package, file_name, 1) or "").split()
for package in packages_dynamic:
if not package in cacheData.packages_dynamic:
@@ -445,38 +439,45 @@ class Cache:
self.getVar('__BB_DONT_CACHE', file_name, True)
self.getVar('__VARIANTS', file_name, True)
- def load_bbfile( self, bbfile , config):
+ def load_bbfile( self, bbfile, config):
"""
Load and parse one .bb build file
Return the data and whether parsing resulted in the file being skipped
"""
+ chdir_back = False
- import bb
- from bb import utils, data, parse, debug, event, fatal
+ from bb import data, parse
# expand tmpdir to include this topdir
data.setVar('TMPDIR', data.getVar('TMPDIR', config, 1) or "", config)
bbfile_loc = os.path.abspath(os.path.dirname(bbfile))
oldpath = os.path.abspath(os.getcwd())
- if bb.parse.cached_mtime_noerror(bbfile_loc):
- os.chdir(bbfile_loc)
+ parse.cached_mtime_noerror(bbfile_loc)
bb_data = data.init_db(config)
+ # The ConfHandler first looks if there is a TOPDIR and if not
+ # then it would call getcwd().
+ # Previously, we chdir()ed to bbfile_loc, called the handler
+ # and finally chdir()ed back, a couple of thousand times. We now
+ # just fill in TOPDIR to point to bbfile_loc if there is no TOPDIR yet.
+ if not data.getVar('TOPDIR', bb_data):
+ chdir_back = True
+ data.setVar('TOPDIR', bbfile_loc, bb_data)
try:
bb_data = parse.handle(bbfile, bb_data) # read .bb data
- os.chdir(oldpath)
+ if chdir_back: os.chdir(oldpath)
return bb_data
except:
- os.chdir(oldpath)
+ if chdir_back: os.chdir(oldpath)
raise
def init(cooker):
"""
- The Objective: Cache the minimum amount of data possible yet get to the
+ The Objective: Cache the minimum amount of data possible yet get to the
stage of building packages (i.e. tryBuild) without reparsing any .bb files.
- To do this, we intercept getVar calls and only cache the variables we see
- being accessed. We rely on the cache getVar calls being made for all
- variables bitbake might need to use to reach this stage. For each cached
+ To do this, we intercept getVar calls and only cache the variables we see
+ being accessed. We rely on the cache getVar calls being made for all
+ variables bitbake might need to use to reach this stage. For each cached
file we need to track:
* Its mtime
@@ -486,7 +487,7 @@ def init(cooker):
Files causing parsing errors are evicted from the cache.
"""
- return Cache(cooker)
+ return Cache(cooker.configuration.data)