diff options
Diffstat (limited to 'bitbake/lib/bb/cache.py')
-rw-r--r-- | bitbake/lib/bb/cache.py | 99 |
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) |