diff options
| author | Richard Purdie <richard@openedhand.com> | 2008-03-03 22:01:45 +0000 |
|---|---|---|
| committer | Richard Purdie <richard@openedhand.com> | 2008-03-03 22:01:45 +0000 |
| commit | ab191d21e2e5e1609206146d238af6ec0b3f0554 (patch) | |
| tree | 728fa74dbf00f6b11964aa53b8427a0d221d6e91 /bitbake/lib | |
| parent | e88b4753781d54dc2625c3260c611d30ad76dbed (diff) | |
| download | openembedded-core-ab191d21e2e5e1609206146d238af6ec0b3f0554.tar.gz openembedded-core-ab191d21e2e5e1609206146d238af6ec0b3f0554.tar.bz2 openembedded-core-ab191d21e2e5e1609206146d238af6ec0b3f0554.zip | |
bitbake: Update to bitbake 1.8 branch head
git-svn-id: https://svn.o-hand.com/repos/poky/trunk@3892 311d38ba-8fff-0310-9ca6-ca027cbcb966
Diffstat (limited to 'bitbake/lib')
| -rw-r--r-- | bitbake/lib/bb/__init__.py | 179 | ||||
| -rw-r--r-- | bitbake/lib/bb/build.py | 208 | ||||
| -rw-r--r-- | bitbake/lib/bb/cache.py | 63 | ||||
| -rw-r--r-- | bitbake/lib/bb/cooker.py | 97 | ||||
| -rw-r--r-- | bitbake/lib/bb/data_smart.py | 4 | ||||
| -rw-r--r-- | bitbake/lib/bb/event.py | 17 | ||||
| -rw-r--r-- | bitbake/lib/bb/fetch/__init__.py | 12 | ||||
| -rw-r--r-- | bitbake/lib/bb/parse/parse_py/BBHandler.py | 51 | ||||
| -rw-r--r-- | bitbake/lib/bb/runqueue.py | 142 | ||||
| -rw-r--r-- | bitbake/lib/bb/shell.py | 23 | ||||
| -rw-r--r-- | bitbake/lib/bb/taskdata.py | 5 | ||||
| -rw-r--r-- | bitbake/lib/bb/utils.py | 8 |
12 files changed, 339 insertions, 470 deletions
diff --git a/bitbake/lib/bb/__init__.py b/bitbake/lib/bb/__init__.py index a126c17693..c452d529c1 100644 --- a/bitbake/lib/bb/__init__.py +++ b/bitbake/lib/bb/__init__.py @@ -46,7 +46,6 @@ __all__ = [ "pkgcmp", "dep_parenreduce", "dep_opconvert", - "digraph", # fetch "decodeurl", @@ -1128,184 +1127,6 @@ def dep_opconvert(mysplit, myuse): mypos += 1 return newsplit -class digraph: - """beautiful directed graph object""" - - def __init__(self): - self.dict={} - #okeys = keys, in order they were added (to optimize firstzero() ordering) - self.okeys=[] - self.__callback_cache=[] - - def __str__(self): - str = "" - for key in self.okeys: - str += "%s:\t%s\n" % (key, self.dict[key][1]) - return str - - def addnode(self,mykey,myparent): - if not mykey in self.dict: - self.okeys.append(mykey) - if myparent==None: - self.dict[mykey]=[0,[]] - else: - self.dict[mykey]=[0,[myparent]] - self.dict[myparent][0]=self.dict[myparent][0]+1 - return - if myparent and (not myparent in self.dict[mykey][1]): - self.dict[mykey][1].append(myparent) - self.dict[myparent][0]=self.dict[myparent][0]+1 - - def delnode(self,mykey, ref = 1): - """Delete a node - - If ref is 1, remove references to this node from other nodes. - If ref is 2, remove nodes that reference this node.""" - if not mykey in self.dict: - return - for x in self.dict[mykey][1]: - self.dict[x][0]=self.dict[x][0]-1 - del self.dict[mykey] - while 1: - try: - self.okeys.remove(mykey) - except ValueError: - break - if ref: - __kill = [] - for k in self.okeys: - if mykey in self.dict[k][1]: - if ref == 1 or ref == 2: - self.dict[k][1].remove(mykey) - if ref == 2: - __kill.append(k) - for l in __kill: - self.delnode(l, ref) - - def allnodes(self): - "returns all nodes in the dictionary" - keys = self.dict.keys() - ret = [] - for key in keys: - ret.append(key) - ret.sort() - return ret - - def firstzero(self): - "returns first node with zero references, or NULL if no such node exists" - for x in self.okeys: - if self.dict[x][0]==0: - return x - return None - - def firstnonzero(self): - "returns first node with nonzero references, or NULL if no such node exists" - for x in self.okeys: - if self.dict[x][0]!=0: - return x - return None - - - def allzeros(self): - "returns all nodes with zero references, or NULL if no such node exists" - zerolist = [] - for x in self.dict.keys(): - if self.dict[x][0]==0: - zerolist.append(x) - return zerolist - - def hasallzeros(self): - "returns 0/1, Are all nodes zeros? 1 : 0" - zerolist = [] - for x in self.dict.keys(): - if self.dict[x][0]!=0: - return 0 - return 1 - - def empty(self): - if len(self.dict)==0: - return 1 - return 0 - - def hasnode(self,mynode): - return mynode in self.dict - - def getparents(self, item): - if not self.hasnode(item): - return [] - parents = self.dict[item][1] - ret = [] - for parent in parents: - ret.append(parent) - ret.sort() - return ret - - def getchildren(self, item): - if not self.hasnode(item): - return [] - children = [i for i in self.okeys if item in self.getparents(i)] - return children - - def walkdown(self, item, callback, debug = None, usecache = False): - if not self.hasnode(item): - return 0 - - if usecache: - if self.__callback_cache.count(item): - if debug: - print "hit cache for item: %s" % item - return 1 - - parents = self.getparents(item) - children = self.getchildren(item) - for p in parents: - if p in children: -# print "%s is both parent and child of %s" % (p, item) - if usecache: - self.__callback_cache.append(p) - ret = callback(self, p) - if ret == 0: - return 0 - continue - if item == p: - print "eek, i'm my own parent!" - return 0 - if debug: - print "item: %s, p: %s" % (item, p) - ret = self.walkdown(p, callback, debug, usecache) - if ret == 0: - return 0 - if usecache: - self.__callback_cache.append(item) - return callback(self, item) - - def walkup(self, item, callback): - if not self.hasnode(item): - return 0 - - parents = self.getparents(item) - children = self.getchildren(item) - for c in children: - if c in parents: - ret = callback(self, item) - if ret == 0: - return 0 - continue - if item == c: - print "eek, i'm my own child!" - return 0 - ret = self.walkup(c, callback) - if ret == 0: - return 0 - return callback(self, item) - - def copy(self): - mygraph=digraph() - for x in self.dict.keys(): - mygraph.dict[x]=self.dict[x][:] - mygraph.okeys=self.okeys[:] - return mygraph - if __name__ == "__main__": import doctest, bb doctest.testmod(bb) diff --git a/bitbake/lib/bb/build.py b/bitbake/lib/bb/build.py index 1c015fe9a3..25c03a0a4e 100644 --- a/bitbake/lib/bb/build.py +++ b/bitbake/lib/bb/build.py @@ -74,12 +74,21 @@ def exec_func(func, d, dirs = None): if not body: return - cleandirs = (data.expand(data.getVarFlag(func, 'cleandirs', d), d) or "").split() + flags = data.getVarFlags(func, d) + for item in ['deps', 'check', 'interactive', 'python', 'cleandirs', 'dirs', 'lockfiles', 'fakeroot']: + if not item in flags: + flags[item] = None + + ispython = flags['python'] + + cleandirs = (data.expand(flags['cleandirs'], d) or "").split() for cdir in cleandirs: os.system("rm -rf %s" % cdir) - if not dirs: - dirs = (data.expand(data.getVarFlag(func, 'dirs', d), d) or "").split() + if dirs: + dirs = data.expand(dirs, d) + else: + dirs = (data.expand(flags['dirs'], d) or "").split() for adir in dirs: mkdirhier(adir) @@ -88,24 +97,22 @@ def exec_func(func, d, dirs = None): else: adir = data.getVar('B', d, 1) - adir = data.expand(adir, d) - try: prevdir = os.getcwd() except OSError: - prevdir = data.expand('${TOPDIR}', d) + prevdir = data.getVar('TOPDIR', d, True) if adir and os.access(adir, os.F_OK): os.chdir(adir) locks = [] - lockfiles = (data.expand(data.getVarFlag(func, 'lockfiles', d), d) or "").split() + lockfiles = (data.expand(flags['lockfiles'], d) or "").split() for lock in lockfiles: locks.append(bb.utils.lockfile(lock)) - if data.getVarFlag(func, "python", d): + if flags['python']: exec_func_python(func, d) else: - exec_func_shell(func, d) + exec_func_shell(func, d, flags) for lock in locks: bb.utils.unlockfile(lock) @@ -117,19 +124,20 @@ def exec_func_python(func, d): """Execute a python BB 'function'""" import re, os + bbfile = bb.data.getVar('FILE', d, 1) tmp = "def " + func + "():\n%s" % data.getVar(func, d) tmp += '\n' + func + '()' - comp = utils.better_compile(tmp, func, bb.data.getVar('FILE', d, 1) ) + comp = utils.better_compile(tmp, func, bbfile) prevdir = os.getcwd() g = {} # globals g['bb'] = bb g['os'] = os g['d'] = d - utils.better_exec(comp,g,tmp, bb.data.getVar('FILE',d,1)) + utils.better_exec(comp, g, tmp, bbfile) if os.path.exists(prevdir): os.chdir(prevdir) -def exec_func_shell(func, d): +def exec_func_shell(func, d, flags): """Execute a shell BB 'function' Returns true if execution was successful. For this, it creates a bash shell script in the tmp dectory, writes the local @@ -141,9 +149,9 @@ def exec_func_shell(func, d): """ import sys - deps = data.getVarFlag(func, 'deps', d) - check = data.getVarFlag(func, 'check', d) - interact = data.getVarFlag(func, 'interactive', d) + deps = flags['deps'] + check = flags['check'] + interact = flags['interactive'] if check in globals(): if globals()[check](func, deps): return @@ -195,7 +203,7 @@ def exec_func_shell(func, d): # execute function prevdir = os.getcwd() - if data.getVarFlag(func, "fakeroot", d): + if flags['fakeroot']: maybe_fakeroot = "PATH=\"%s\" fakeroot " % bb.data.getVar("PATH", d, 1) else: maybe_fakeroot = '' @@ -255,72 +263,29 @@ def exec_task(task, d): a function is that a task exists in the task digraph, and therefore has dependencies amongst other tasks.""" - # check if the task is in the graph.. - task_graph = data.getVar('_task_graph', d) - if not task_graph: - task_graph = bb.digraph() - data.setVar('_task_graph', task_graph, d) - task_cache = data.getVar('_task_cache', d) - if not task_cache: - task_cache = [] - data.setVar('_task_cache', task_cache, d) - if not task_graph.hasnode(task): - raise EventException("Missing node in task graph", InvalidTask(task, d)) - - # check whether this task needs executing.. - if stamp_is_current(task, d): - return 1 - - # follow digraph path up, then execute our way back down - def execute(graph, item): - if data.getVarFlag(item, 'task', d): - if item in task_cache: - return 1 - - if task != item: - # deeper than toplevel, exec w/ deps - exec_task(item, d) - return 1 - - try: - 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) - data.update_data(localdata) - event.fire(TaskStarted(item, localdata)) - exec_func(item, localdata) - event.fire(TaskSucceeded(item, localdata)) - task_cache.append(item) - data.setVar('_task_cache', task_cache, d) - except FuncFailed, 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) - - if data.getVarFlag(task, 'dontrundeps', d): - execute(None, task) - else: - task_graph.walkdown(task, execute) + # Check whther this is a valid task + if not data.getVarFlag(task, 'task', d): + raise EventException("No such task", InvalidTask(task, d)) + + try: + bb.msg.debug(1, bb.msg.domain.Build, "Executing task %s" % task) + old_overrides = data.getVar('OVERRIDES', d, 0) + localdata = data.createCopy(d) + data.setVar('OVERRIDES', 'task_%s:%s' % (task, old_overrides), localdata) + data.update_data(localdata) + event.fire(TaskStarted(task, localdata)) + exec_func(task, localdata) + event.fire(TaskSucceeded(task, localdata)) + except FuncFailed, reason: + bb.msg.note(1, bb.msg.domain.Build, "Task failed: %s" % reason ) + failedevent = TaskFailed(task, d) + event.fire(failedevent) + raise EventException("Function failed in task: %s" % reason, failedevent) # make stamp, or cause event and raise exception if not data.getVarFlag(task, 'nostamp', d) and not data.getVarFlag(task, 'selfstamp', d): make_stamp(task, d) -def extract_stamp_data(d, fn): - """ - Extracts stamp data from d which is either a data dictonary (fn unset) - or a dataCache entry (fn set). - """ - if fn: - return (d.task_queues[fn], d.stamp[fn], d.task_deps[fn]) - task_graph = data.getVar('_task_graph', d) - if not task_graph: - task_graph = bb.digraph() - data.setVar('_task_graph', task_graph, d) - return (task_graph, data.getVar('STAMP', d, 1), None) - def extract_stamp(d, fn): """ Extracts stamp format which is either a data dictonary (fn unset) @@ -330,49 +295,6 @@ def extract_stamp(d, fn): return d.stamp[fn] return data.getVar('STAMP', d, 1) -def stamp_is_current(task, d, file_name = None, checkdeps = 1): - """ - Check status of a given task's stamp. - Returns 0 if it is not current and needs updating. - (d can be a data dict or dataCache) - """ - - (task_graph, stampfn, taskdep) = extract_stamp_data(d, file_name) - - if not stampfn: - return 0 - - stampfile = "%s.%s" % (stampfn, 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 file_name: - if 'nostamp' in taskdep and task in taskdep['nostamp']: - return 1 - else: - if data.getVarFlag(task, 'nostamp', d): - return 1 - - if not stamp_is_current(task, d, file_name, 0 ): - return 0 - - depfile = "%s.%s" % (stampfn, task) - deptime = os.stat(depfile)[stat.ST_MTIME] - if deptime > tasktime: - return 0 - return 1 - - return task_graph.walkdown(task, checkStamp) - def stamp_internal(task, d, file_name): """ Internal stamp helper function @@ -409,40 +331,39 @@ def del_stamp(task, d, file_name = None): stamp_internal(task, d, file_name) def add_tasks(tasklist, d): - task_graph = data.getVar('_task_graph', d) task_deps = data.getVar('_task_deps', d) - if not task_graph: - task_graph = bb.digraph() if not task_deps: task_deps = {} + if not 'tasks' in task_deps: + task_deps['tasks'] = [] + if not 'parents' in task_deps: + task_deps['parents'] = {} for task in tasklist: - deps = tasklist[task] task = data.expand(task, d) - data.setVarFlag(task, 'task', 1, d) - task_graph.addnode(task, None) - for dep in deps: - dep = data.expand(dep, d) - if not task_graph.hasnode(dep): - task_graph.addnode(dep, None) - task_graph.addnode(task, dep) + + if not task in task_deps['tasks']: + task_deps['tasks'].append(task) flags = data.getVarFlags(task, d) def getTask(name): + if not name in task_deps: + task_deps[name] = {} if name in flags: deptask = data.expand(flags[name], d) - if not name in task_deps: - task_deps[name] = {} task_deps[name][task] = deptask getTask('depends') getTask('deptask') getTask('rdeptask') getTask('recrdeptask') getTask('nostamp') + task_deps['parents'][task] = [] + for dep in flags['deps']: + dep = data.expand(dep, d) + task_deps['parents'][task].append(dep) # don't assume holding a reference - data.setVar('_task_graph', task_graph, d) data.setVar('_task_deps', task_deps, d) def remove_task(task, kill, d): @@ -450,22 +371,5 @@ def remove_task(task, kill, d): If kill is 1, also remove tasks that depend on this task.""" - task_graph = data.getVar('_task_graph', d) - if not task_graph: - task_graph = bb.digraph() - if not task_graph.hasnode(task): - return - data.delVarFlag(task, 'task', d) - ref = 1 - if kill == 1: - ref = 2 - task_graph.delnode(task, ref) - data.setVar('_task_graph', task_graph, d) - -def task_exists(task, d): - task_graph = data.getVar('_task_graph', d) - if not task_graph: - task_graph = bb.digraph() - data.setVar('_task_graph', task_graph, d) - return task_graph.hasnode(task) + diff --git a/bitbake/lib/bb/cache.py b/bitbake/lib/bb/cache.py index 7d7e66ebd2..dad82a9b36 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__ = "127" +__cache_version__ = "128" class Cache: """ @@ -50,9 +50,11 @@ class Cache: self.cachedir = bb.data.getVar("CACHE", cooker.configuration.data, True) self.clean = {} + self.checked = {} self.depends_cache = {} self.data = None self.data_fn = None + self.cacheclean = True if self.cachedir in [None, '']: self.has_cache = False @@ -67,9 +69,20 @@ class Cache: except OSError: bb.mkdirhier( self.cachedir ) - if self.has_cache and (self.mtime(self.cachefile)): + if not self.has_cache: + return + + # 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 + + if self.mtime(self.cachefile) >= newest_mtime: try: - p = pickle.Unpickler( file(self.cachefile,"rb")) + 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' @@ -81,11 +94,8 @@ class Cache: except (ValueError, KeyError): bb.msg.note(1, bb.msg.domain.Cache, "Invalid cache found, rebuilding...") self.depends_cache = {} - - if self.depends_cache: - for fn in self.depends_cache.keys(): - self.clean[fn] = "" - self.cacheValidUpdate(fn) + else: + bb.msg.note(1, bb.msg.domain.Cache, "Out of date cache found, rebuilding...") def getVar(self, var, fn, exp = 0): """ @@ -97,7 +107,6 @@ class Cache: 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] @@ -109,6 +118,7 @@ class Cache: # yet setData hasn't been called to setup the right access. Very bad. bb.msg.error(bb.msg.domain.Cache, "Parsing error data_fn %s and fn %s don't match" % (self.data_fn, fn)) + self.cacheclean = False result = bb.data.getVar(var, self.data, exp) self.depends_cache[fn][var] = result return result @@ -131,6 +141,8 @@ class Cache: Return a complete set of data for fn. To do this, we need to parse the file. """ + bb.msg.debug(1, bb.msg.domain.Cache, "Parsing %s (full)" % fn) + bb_data, skipped = self.load_bbfile(fn, cfgData) return bb_data @@ -142,11 +154,15 @@ class Cache: to record the variables accessed. Return the cache status and whether the file was skipped when parsed """ + if fn not in self.checked: + self.cacheValidUpdate(fn) if self.cacheValid(fn): if "SKIPPED" in self.depends_cache[fn]: return True, True return True, False + bb.msg.debug(1, bb.msg.domain.Cache, "Parsing %s" % fn) + bb_data, skipped = self.load_bbfile(fn, cfgData) self.setData(fn, bb_data) return False, skipped @@ -172,11 +188,10 @@ class Cache: if not self.has_cache: return False - # Check file still exists - if self.mtime(fn) == 0: - bb.msg.debug(2, bb.msg.domain.Cache, "Cache: %s not longer exists" % fn) - self.remove(fn) - return False + self.checked[fn] = "" + + # Pretend we're clean so getVar works + self.clean[fn] = "" # File isn't in depends_cache if not fn in self.depends_cache: @@ -184,6 +199,12 @@ class Cache: self.remove(fn) return False + # Check file still exists + if self.mtime(fn) == 0: + bb.msg.debug(2, bb.msg.domain.Cache, "Cache: %s not longer exists" % fn) + self.remove(fn) + return False + # Check the file's timestamp if bb.parse.cached_mtime(fn) > self.getVar("CACHETIMESTAMP", fn, True): bb.msg.debug(2, bb.msg.domain.Cache, "Cache: %s changed" % fn) @@ -195,6 +216,7 @@ class Cache: for f,old_mtime in depends: # Check if file still exists if self.mtime(f) == 0: + self.remove(fn) return False new_mtime = bb.parse.cached_mtime(f) @@ -203,7 +225,7 @@ class Cache: self.remove(fn) return False - bb.msg.debug(2, bb.msg.domain.Cache, "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] = "" @@ -238,6 +260,10 @@ class Cache: if not self.has_cache: return + if self.cacheclean: + bb.msg.note(1, bb.msg.domain.Cache, "Cache is clean, not saving.") + return + version_data = {} version_data['CACHE_VER'] = __cache_version__ version_data['BITBAKE_VER'] = bb.__version__ @@ -264,7 +290,6 @@ class Cache: 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 @@ -328,14 +353,16 @@ class Cache: if not file_name in cacheData.runrecs: cacheData.runrecs[file_name] = {} + rdepends = bb.utils.explode_deps(self.getVar('RDEPENDS', file_name, True) or "") + rrecommends = bb.utils.explode_deps(self.getVar('RRECOMMENDS', file_name, True) or "") for package in packages + [pn]: if not package in cacheData.rundeps[file_name]: cacheData.rundeps[file_name][package] = {} if not package in cacheData.runrecs[file_name]: cacheData.runrecs[file_name][package] = {} - add_dep(cacheData.rundeps[file_name][package], bb.utils.explode_deps(self.getVar('RDEPENDS', file_name, True) or "")) - add_dep(cacheData.runrecs[file_name][package], bb.utils.explode_deps(self.getVar('RRECOMMENDS', file_name, True) or "")) + add_dep(cacheData.rundeps[file_name][package], rdepends) + add_dep(cacheData.runrecs[file_name][package], rrecommends) add_dep(cacheData.rundeps[file_name][package], bb.utils.explode_deps(self.getVar("RDEPENDS_%s" % package, file_name, True) or "")) add_dep(cacheData.runrecs[file_name][package], bb.utils.explode_deps(self.getVar("RRECOMMENDS_%s" % package, file_name, True) or "")) diff --git a/bitbake/lib/bb/cooker.py b/bitbake/lib/bb/cooker.py index 2c091b6522..38a8209760 100644 --- a/bitbake/lib/bb/cooker.py +++ b/bitbake/lib/bb/cooker.py @@ -97,14 +97,12 @@ class BBCooker: bb.msg.note(2, bb.msg.domain.Build, "Renice to %s " % os.nice(nice)) - def tryBuildPackage(self, fn, item, task, the_data, build_depends): + def tryBuildPackage(self, fn, item, task, the_data): """ Build one task of a package, optionally build following task depends """ bb.event.fire(bb.event.PkgStarted(item, the_data)) try: - 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)) @@ -119,21 +117,20 @@ class BBCooker: bb.event.fire(bb.event.PkgFailed(item, the_data)) raise - def tryBuild( self, fn, build_depends): + def tryBuild(self, fn): """ Build a provider and its dependencies. build_depends is a list of previous build dependencies (not runtime) If build_depends is empty, we're dealing with a runtime depends """ - the_data = self.bb_cache.loadDataFull(fn, self.configuration.data) item = self.status.pkg_fn[fn] - if bb.build.stamp_is_current('do_%s' % self.configuration.cmd, the_data): - return True + #if bb.build.stamp_is_current('do_%s' % self.configuration.cmd, the_data): + # return True - return self.tryBuildPackage(fn, item, self.configuration.cmd, the_data, build_depends) + return self.tryBuildPackage(fn, item, self.configuration.cmd, the_data) def showVersions(self): pkg_pn = self.status.pkg_pn @@ -184,6 +181,8 @@ class BBCooker: self.cb = None self.bb_cache = bb.cache.init(self) fn = self.matchFile(buildfile) + if not fn: + sys.exit(1) elif len(pkgs_to_build) == 1: self.updateCache() @@ -220,7 +219,7 @@ class BBCooker: except Exception, e: bb.msg.fatal(bb.msg.domain.Parsing, "%s" % e) # emit the metadata which isnt valid shell - data.expandKeys( envdata ) + data.expandKeys( envdata ) for e in envdata.keys(): if data.getVarFlag( e, 'python', envdata ): sys.__stdout__.write("\npython %s () {\n%s}\n" % (e, data.getVar(e, envdata, 1))) @@ -273,7 +272,7 @@ class BBCooker: if fnid not in seen_fnids: seen_fnids.append(fnid) packages = [] - print >> depends_file, '"%s" [label="%s %s\\n%s"]' % (pn, pn, version, fn) + print >> depends_file, '"%s" [label="%s %s\\n%s"]' % (pn, pn, version, fn) for depend in self.status.deps[fn]: print >> depends_file, '"%s" -> "%s"' % (pn, depend) rdepends = self.status.rundeps[fn] @@ -387,19 +386,15 @@ class BBCooker: try: self.configuration.data = bb.parse.handle( afile, self.configuration.data ) - # Add the handlers we inherited by INHERIT - # we need to do this manually as it is not guranteed - # we will pick up these classes... as we only INHERIT - # on .inc and .bb files but not on .conf - data = bb.data.createCopy( self.configuration.data ) - inherits = ["base"] + (bb.data.getVar('INHERIT', data, True ) or "").split() + # Handle any INHERITs and inherit the base class + inherits = ["base"] + (bb.data.getVar('INHERIT', self.configuration.data, True ) or "").split() for inherit in inherits: - data = bb.parse.handle( os.path.join('classes', '%s.bbclass' % inherit ), data, True ) + self.configuration.data = bb.parse.handle(os.path.join('classes', '%s.bbclass' % inherit), self.configuration.data, True ) - # FIXME: This assumes that we included at least one .inc file - for var in bb.data.keys(data): - if bb.data.getVarFlag(var, 'handler', data): - bb.event.register(var,bb.data.getVar(var, data)) + # Nomally we only register event handlers at the end of parsing .bb files + # We register any handlers we've found so far here... + for var in data.getVar('__BBHANDLERS', self.configuration.data) or []: + bb.event.register(var,bb.data.getVar(var, self.configuration.data)) bb.fetch.fetcher_init(self.configuration.data) @@ -463,30 +458,62 @@ class BBCooker: 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) - return matches[0] + return False + return matches[0] def buildFile(self, buildfile): """ Build the file matching regexp buildfile """ - bf = self.matchFile(buildfile) + # Make sure our target is a fully qualified filename + fn = self.matchFile(buildfile) + if not fn: + return False - bbfile_data = bb.parse.handle(bf, self.configuration.data) + # Load data into the cache for fn + self.bb_cache = bb.cache.init(self) + self.bb_cache.loadData(fn, self.configuration.data) + + # Parse the loaded cache data + self.status = bb.cache.CacheData() + self.bb_cache.handle_data(fn, self.status) + + # Tweak some variables + item = self.bb_cache.getVar('PN', fn, True) + self.status.ignored_dependencies = Set() + self.status.bbfile_priority[fn] = 1 + + # Remove external dependencies + self.status.task_deps[fn]['depends'] = {} + self.status.deps[fn] = [] + self.status.rundeps[fn] = [] + self.status.runrecs[fn] = [] # 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.msg.note(2, bb.msg.domain.RunQueue, "Remove stamp %s, %s" % (self.configuration.cmd, fn)) 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 ) + # Setup taskdata structure + taskdata = bb.taskdata.TaskData(self.configuration.abort) + taskdata.add_provider(self.configuration.data, self.status, item) - sys.exit(0) + buildname = bb.data.getVar("BUILDNAME", self.configuration.data) + bb.event.fire(bb.event.BuildStarted(buildname, [item], self.configuration.event_data)) + + # Execute the runqueue + runlist = [[item, "do_%s" % self.configuration.cmd]] + 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]) + return False + bb.event.fire(bb.event.BuildCompleted(buildname, [item], self.configuration.event_data, failures)) + return True def buildTargets(self, targets): """ @@ -568,7 +595,9 @@ class BBCooker: self.interactiveMode() if self.configuration.buildfile is not None: - return self.buildFile(self.configuration.buildfile) < |
