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
This commit is contained in:
parent
e88b475378
commit
ab191d21e2
|
@ -1,6 +1,26 @@
|
||||||
Changes in BitBake 1.8.x:
|
Changes in BitBake 1.8.x:
|
||||||
- Fix exit code for build failures in --continue mode
|
- Fix exit code for build failures in --continue mode
|
||||||
- Fix git branch tags fetching
|
- Fix git branch tags fetching
|
||||||
|
- Change parseConfigurationFile so it works on real data, not a copy
|
||||||
|
- Handle 'base' inherit and all other INHERITs from parseConfigurationFile
|
||||||
|
instead of BBHandler
|
||||||
|
- Fix getVarFlags bug in data_smart
|
||||||
|
- Optmise cache handling by more quickly detecting an invalid cache, only
|
||||||
|
saving the cache when its changed, moving the cache validity check into
|
||||||
|
the parsing loop and factoring some getVar calls outside a for loop
|
||||||
|
- Cooker: Remove a debug message from the parsing loop to lower overhead
|
||||||
|
- Convert build.py exec_task to use getVarFlags
|
||||||
|
- Update shell to use cooker.buildFile
|
||||||
|
- Add StampUpdate event
|
||||||
|
- Convert -b option to use taskdata/runqueue
|
||||||
|
- Remove digraph and switch to new stamp checking code. exec_task no longer
|
||||||
|
honours dependencies
|
||||||
|
- Make fetcher timestamp updating non-fatal when permissions don't allow
|
||||||
|
updates
|
||||||
|
- Add BB_SCHEDULER variable/option ("completion" or "speed") controlling
|
||||||
|
the way bitbake schedules tasks
|
||||||
|
- Add BB_STAMP_POLICY variable/option ("perfile" or "full") controlling
|
||||||
|
how extensively stamps are looked at for validity
|
||||||
|
|
||||||
Changes in BitBake 1.8.10:
|
Changes in BitBake 1.8.10:
|
||||||
- Psyco is available only for x86 - do not use it on other architectures.
|
- Psyco is available only for x86 - do not use it on other architectures.
|
||||||
|
|
|
@ -46,7 +46,6 @@ __all__ = [
|
||||||
"pkgcmp",
|
"pkgcmp",
|
||||||
"dep_parenreduce",
|
"dep_parenreduce",
|
||||||
"dep_opconvert",
|
"dep_opconvert",
|
||||||
"digraph",
|
|
||||||
|
|
||||||
# fetch
|
# fetch
|
||||||
"decodeurl",
|
"decodeurl",
|
||||||
|
@ -1128,184 +1127,6 @@ def dep_opconvert(mysplit, myuse):
|
||||||
mypos += 1
|
mypos += 1
|
||||||
return newsplit
|
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__":
|
if __name__ == "__main__":
|
||||||
import doctest, bb
|
import doctest, bb
|
||||||
doctest.testmod(bb)
|
doctest.testmod(bb)
|
||||||
|
|
|
@ -74,12 +74,21 @@ def exec_func(func, d, dirs = None):
|
||||||
if not body:
|
if not body:
|
||||||
return
|
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:
|
for cdir in cleandirs:
|
||||||
os.system("rm -rf %s" % cdir)
|
os.system("rm -rf %s" % cdir)
|
||||||
|
|
||||||
if not dirs:
|
if dirs:
|
||||||
dirs = (data.expand(data.getVarFlag(func, 'dirs', d), d) or "").split()
|
dirs = data.expand(dirs, d)
|
||||||
|
else:
|
||||||
|
dirs = (data.expand(flags['dirs'], d) or "").split()
|
||||||
for adir in dirs:
|
for adir in dirs:
|
||||||
mkdirhier(adir)
|
mkdirhier(adir)
|
||||||
|
|
||||||
|
@ -88,24 +97,22 @@ def exec_func(func, d, dirs = None):
|
||||||
else:
|
else:
|
||||||
adir = data.getVar('B', d, 1)
|
adir = data.getVar('B', d, 1)
|
||||||
|
|
||||||
adir = data.expand(adir, d)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
prevdir = os.getcwd()
|
prevdir = os.getcwd()
|
||||||
except OSError:
|
except OSError:
|
||||||
prevdir = data.expand('${TOPDIR}', d)
|
prevdir = data.getVar('TOPDIR', d, True)
|
||||||
if adir and os.access(adir, os.F_OK):
|
if adir and os.access(adir, os.F_OK):
|
||||||
os.chdir(adir)
|
os.chdir(adir)
|
||||||
|
|
||||||
locks = []
|
locks = []
|
||||||
lockfiles = (data.expand(data.getVarFlag(func, 'lockfiles', d), d) or "").split()
|
lockfiles = (data.expand(flags['lockfiles'], d) or "").split()
|
||||||
for lock in lockfiles:
|
for lock in lockfiles:
|
||||||
locks.append(bb.utils.lockfile(lock))
|
locks.append(bb.utils.lockfile(lock))
|
||||||
|
|
||||||
if data.getVarFlag(func, "python", d):
|
if flags['python']:
|
||||||
exec_func_python(func, d)
|
exec_func_python(func, d)
|
||||||
else:
|
else:
|
||||||
exec_func_shell(func, d)
|
exec_func_shell(func, d, flags)
|
||||||
|
|
||||||
for lock in locks:
|
for lock in locks:
|
||||||
bb.utils.unlockfile(lock)
|
bb.utils.unlockfile(lock)
|
||||||
|
@ -117,19 +124,20 @@ def exec_func_python(func, d):
|
||||||
"""Execute a python BB 'function'"""
|
"""Execute a python BB 'function'"""
|
||||||
import re, os
|
import re, os
|
||||||
|
|
||||||
|
bbfile = bb.data.getVar('FILE', d, 1)
|
||||||
tmp = "def " + func + "():\n%s" % data.getVar(func, d)
|
tmp = "def " + func + "():\n%s" % data.getVar(func, d)
|
||||||
tmp += '\n' + func + '()'
|
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()
|
prevdir = os.getcwd()
|
||||||
g = {} # globals
|
g = {} # globals
|
||||||
g['bb'] = bb
|
g['bb'] = bb
|
||||||
g['os'] = os
|
g['os'] = os
|
||||||
g['d'] = d
|
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):
|
if os.path.exists(prevdir):
|
||||||
os.chdir(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.
|
"""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
|
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
|
import sys
|
||||||
|
|
||||||
deps = data.getVarFlag(func, 'deps', d)
|
deps = flags['deps']
|
||||||
check = data.getVarFlag(func, 'check', d)
|
check = flags['check']
|
||||||
interact = data.getVarFlag(func, 'interactive', d)
|
interact = flags['interactive']
|
||||||
if check in globals():
|
if check in globals():
|
||||||
if globals()[check](func, deps):
|
if globals()[check](func, deps):
|
||||||
return
|
return
|
||||||
|
@ -195,7 +203,7 @@ def exec_func_shell(func, d):
|
||||||
|
|
||||||
# execute function
|
# execute function
|
||||||
prevdir = os.getcwd()
|
prevdir = os.getcwd()
|
||||||
if data.getVarFlag(func, "fakeroot", d):
|
if flags['fakeroot']:
|
||||||
maybe_fakeroot = "PATH=\"%s\" fakeroot " % bb.data.getVar("PATH", d, 1)
|
maybe_fakeroot = "PATH=\"%s\" fakeroot " % bb.data.getVar("PATH", d, 1)
|
||||||
else:
|
else:
|
||||||
maybe_fakeroot = ''
|
maybe_fakeroot = ''
|
||||||
|
@ -255,72 +263,29 @@ def exec_task(task, d):
|
||||||
a function is that a task exists in the task digraph, and therefore
|
a function is that a task exists in the task digraph, and therefore
|
||||||
has dependencies amongst other tasks."""
|
has dependencies amongst other tasks."""
|
||||||
|
|
||||||
# check if the task is in the graph..
|
# Check whther this is a valid task
|
||||||
task_graph = data.getVar('_task_graph', d)
|
if not data.getVarFlag(task, 'task', d):
|
||||||
if not task_graph:
|
raise EventException("No such task", InvalidTask(task, d))
|
||||||
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..
|
try:
|
||||||
if stamp_is_current(task, d):
|
bb.msg.debug(1, bb.msg.domain.Build, "Executing task %s" % task)
|
||||||
return 1
|
old_overrides = data.getVar('OVERRIDES', d, 0)
|
||||||
|
localdata = data.createCopy(d)
|
||||||
# follow digraph path up, then execute our way back down
|
data.setVar('OVERRIDES', 'task_%s:%s' % (task, old_overrides), localdata)
|
||||||
def execute(graph, item):
|
data.update_data(localdata)
|
||||||
if data.getVarFlag(item, 'task', d):
|
event.fire(TaskStarted(task, localdata))
|
||||||
if item in task_cache:
|
exec_func(task, localdata)
|
||||||
return 1
|
event.fire(TaskSucceeded(task, localdata))
|
||||||
|
except FuncFailed, reason:
|
||||||
if task != item:
|
bb.msg.note(1, bb.msg.domain.Build, "Task failed: %s" % reason )
|
||||||
# deeper than toplevel, exec w/ deps
|
failedevent = TaskFailed(task, d)
|
||||||
exec_task(item, d)
|
event.fire(failedevent)
|
||||||
return 1
|
raise EventException("Function failed in task: %s" % reason, failedevent)
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
# make stamp, or cause event and raise exception
|
# make stamp, or cause event and raise exception
|
||||||
if not data.getVarFlag(task, 'nostamp', d) and not data.getVarFlag(task, 'selfstamp', d):
|
if not data.getVarFlag(task, 'nostamp', d) and not data.getVarFlag(task, 'selfstamp', d):
|
||||||
make_stamp(task, 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):
|
def extract_stamp(d, fn):
|
||||||
"""
|
"""
|
||||||
Extracts stamp format which is either a data dictonary (fn unset)
|
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 d.stamp[fn]
|
||||||
return data.getVar('STAMP', d, 1)
|
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):
|
def stamp_internal(task, d, file_name):
|
||||||
"""
|
"""
|
||||||
Internal stamp helper function
|
Internal stamp helper function
|
||||||
|
@ -409,40 +331,39 @@ def del_stamp(task, d, file_name = None):
|
||||||
stamp_internal(task, d, file_name)
|
stamp_internal(task, d, file_name)
|
||||||
|
|
||||||
def add_tasks(tasklist, d):
|
def add_tasks(tasklist, d):
|
||||||
task_graph = data.getVar('_task_graph', d)
|
|
||||||
task_deps = data.getVar('_task_deps', d)
|
task_deps = data.getVar('_task_deps', d)
|
||||||
if not task_graph:
|
|
||||||
task_graph = bb.digraph()
|
|
||||||
if not task_deps:
|
if not task_deps:
|
||||||
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:
|
for task in tasklist:
|
||||||
deps = tasklist[task]
|
|
||||||
task = data.expand(task, d)
|
task = data.expand(task, d)
|
||||||
|
|
||||||
data.setVarFlag(task, 'task', 1, d)
|
data.setVarFlag(task, 'task', 1, d)
|
||||||
task_graph.addnode(task, None)
|
|
||||||
for dep in deps:
|
if not task in task_deps['tasks']:
|
||||||
dep = data.expand(dep, d)
|
task_deps['tasks'].append(task)
|
||||||
if not task_graph.hasnode(dep):
|
|
||||||
task_graph.addnode(dep, None)
|
|
||||||
task_graph.addnode(task, dep)
|
|
||||||
|
|
||||||
flags = data.getVarFlags(task, d)
|
flags = data.getVarFlags(task, d)
|
||||||
def getTask(name):
|
def getTask(name):
|
||||||
|
if not name in task_deps:
|
||||||
|
task_deps[name] = {}
|
||||||
if name in flags:
|
if name in flags:
|
||||||
deptask = data.expand(flags[name], d)
|
deptask = data.expand(flags[name], d)
|
||||||
if not name in task_deps:
|
|
||||||
task_deps[name] = {}
|
|
||||||
task_deps[name][task] = deptask
|
task_deps[name][task] = deptask
|
||||||
getTask('depends')
|
getTask('depends')
|
||||||
getTask('deptask')
|
getTask('deptask')
|
||||||
getTask('rdeptask')
|
getTask('rdeptask')
|
||||||
getTask('recrdeptask')
|
getTask('recrdeptask')
|
||||||
getTask('nostamp')
|
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
|
# don't assume holding a reference
|
||||||
data.setVar('_task_graph', task_graph, d)
|
|
||||||
data.setVar('_task_deps', task_deps, d)
|
data.setVar('_task_deps', task_deps, d)
|
||||||
|
|
||||||
def remove_task(task, kill, 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."""
|
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)
|
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)
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ except ImportError:
|
||||||
import pickle
|
import pickle
|
||||||
bb.msg.note(1, bb.msg.domain.Cache, "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__ = "127"
|
__cache_version__ = "128"
|
||||||
|
|
||||||
class Cache:
|
class Cache:
|
||||||
"""
|
"""
|
||||||
|
@ -50,9 +50,11 @@ class Cache:
|
||||||
|
|
||||||
self.cachedir = bb.data.getVar("CACHE", cooker.configuration.data, True)
|
self.cachedir = bb.data.getVar("CACHE", cooker.configuration.data, True)
|
||||||
self.clean = {}
|
self.clean = {}
|
||||||
|
self.checked = {}
|
||||||
self.depends_cache = {}
|
self.depends_cache = {}
|
||||||
self.data = None
|
self.data = None
|
||||||
self.data_fn = None
|
self.data_fn = None
|
||||||
|
self.cacheclean = True
|
||||||
|
|
||||||
if self.cachedir in [None, '']:
|
if self.cachedir in [None, '']:
|
||||||
self.has_cache = False
|
self.has_cache = False
|
||||||
|
@ -67,9 +69,20 @@ class Cache:
|
||||||
except OSError:
|
except OSError:
|
||||||
bb.mkdirhier( self.cachedir )
|
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:
|
try:
|
||||||
p = pickle.Unpickler( file(self.cachefile,"rb"))
|
p = pickle.Unpickler(file(self.cachefile, "rb"))
|
||||||
self.depends_cache, version_data = p.load()
|
self.depends_cache, version_data = p.load()
|
||||||
if version_data['CACHE_VER'] != __cache_version__:
|
if version_data['CACHE_VER'] != __cache_version__:
|
||||||
raise ValueError, 'Cache Version Mismatch'
|
raise ValueError, 'Cache Version Mismatch'
|
||||||
|
@ -81,11 +94,8 @@ class Cache:
|
||||||
except (ValueError, KeyError):
|
except (ValueError, KeyError):
|
||||||
bb.msg.note(1, bb.msg.domain.Cache, "Invalid cache found, rebuilding...")
|
bb.msg.note(1, bb.msg.domain.Cache, "Invalid cache found, rebuilding...")
|
||||||
self.depends_cache = {}
|
self.depends_cache = {}
|
||||||
|
else:
|
||||||
if self.depends_cache:
|
bb.msg.note(1, bb.msg.domain.Cache, "Out of date cache found, rebuilding...")
|
||||||
for fn in self.depends_cache.keys():
|
|
||||||
self.clean[fn] = ""
|
|
||||||
self.cacheValidUpdate(fn)
|
|
||||||
|
|
||||||
def getVar(self, var, fn, exp = 0):
|
def getVar(self, var, fn, exp = 0):
|
||||||
"""
|
"""
|
||||||
|
@ -97,7 +107,6 @@ class Cache:
|
||||||
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.
|
backend but add a copy of the data to the cache.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if fn in self.clean:
|
if fn in self.clean:
|
||||||
return self.depends_cache[fn][var]
|
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.
|
# 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))
|
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)
|
result = bb.data.getVar(var, self.data, exp)
|
||||||
self.depends_cache[fn][var] = result
|
self.depends_cache[fn][var] = result
|
||||||
return result
|
return result
|
||||||
|
@ -131,6 +141,8 @@ class Cache:
|
||||||
Return a complete set of data for fn.
|
Return a complete set of data for fn.
|
||||||
To do this, we need to parse the file.
|
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)
|
bb_data, skipped = self.load_bbfile(fn, cfgData)
|
||||||
return bb_data
|
return bb_data
|
||||||
|
|
||||||
|
@ -142,11 +154,15 @@ class Cache:
|
||||||
to record the variables accessed.
|
to record the variables accessed.
|
||||||
Return the cache status and whether the file was skipped when parsed
|
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 self.cacheValid(fn):
|
||||||
if "SKIPPED" in self.depends_cache[fn]:
|
if "SKIPPED" in self.depends_cache[fn]:
|
||||||
return True, True
|
return True, True
|
||||||
return True, False
|
return True, False
|
||||||
|
|
||||||
|
bb.msg.debug(1, bb.msg.domain.Cache, "Parsing %s" % fn)
|
||||||
|
|
||||||
bb_data, skipped = self.load_bbfile(fn, cfgData)
|
bb_data, skipped = self.load_bbfile(fn, cfgData)
|
||||||
self.setData(fn, bb_data)
|
self.setData(fn, bb_data)
|
||||||
return False, skipped
|
return False, skipped
|
||||||
|
@ -172,11 +188,10 @@ class Cache:
|
||||||
if not self.has_cache:
|
if not self.has_cache:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Check file still exists
|
self.checked[fn] = ""
|
||||||
if self.mtime(fn) == 0:
|
|
||||||
bb.msg.debug(2, bb.msg.domain.Cache, "Cache: %s not longer exists" % fn)
|
# Pretend we're clean so getVar works
|
||||||
self.remove(fn)
|
self.clean[fn] = ""
|
||||||
return False
|
|
||||||
|
|
||||||
# File isn't in depends_cache
|
# File isn't in depends_cache
|
||||||
if not fn in self.depends_cache:
|
if not fn in self.depends_cache:
|
||||||
|
@ -184,6 +199,12 @@ class Cache:
|
||||||
self.remove(fn)
|
self.remove(fn)
|
||||||
return False
|
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
|
# Check the file's timestamp
|
||||||
if bb.parse.cached_mtime(fn) > self.getVar("CACHETIMESTAMP", fn, True):
|
if bb.parse.cached_mtime(fn) > self.getVar("CACHETIMESTAMP", fn, True):
|
||||||
bb.msg.debug(2, bb.msg.domain.Cache, "Cache: %s changed" % fn)
|
bb.msg.debug(2, bb.msg.domain.Cache, "Cache: %s changed" % fn)
|
||||||
|
@ -195,6 +216,7 @@ class Cache:
|
||||||
for f,old_mtime in depends:
|
for f,old_mtime in depends:
|
||||||
# Check if file still exists
|
# Check if file still exists
|
||||||
if self.mtime(f) == 0:
|
if self.mtime(f) == 0:
|
||||||
|
self.remove(fn)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
new_mtime = bb.parse.cached_mtime(f)
|
new_mtime = bb.parse.cached_mtime(f)
|
||||||
|
@ -203,7 +225,7 @@ class Cache:
|
||||||
self.remove(fn)
|
self.remove(fn)
|
||||||
return False
|
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:
|
if not fn in self.clean:
|
||||||
self.clean[fn] = ""
|
self.clean[fn] = ""
|
||||||
|
|
||||||
|
@ -238,6 +260,10 @@ class Cache:
|
||||||
if not self.has_cache:
|
if not self.has_cache:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if self.cacheclean:
|
||||||
|
bb.msg.note(1, bb.msg.domain.Cache, "Cache is clean, not saving.")
|
||||||
|
return
|
||||||
|
|
||||||
version_data = {}
|
version_data = {}
|
||||||
version_data['CACHE_VER'] = __cache_version__
|
version_data['CACHE_VER'] = __cache_version__
|
||||||
version_data['BITBAKE_VER'] = bb.__version__
|
version_data['BITBAKE_VER'] = bb.__version__
|
||||||
|
@ -264,7 +290,6 @@ class Cache:
|
||||||
packages_dynamic = (self.getVar('PACKAGES_DYNAMIC', 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()
|
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)
|
cacheData.task_deps[file_name] = self.getVar("_task_deps", file_name, True)
|
||||||
|
|
||||||
# build PackageName to FileName lookup table
|
# build PackageName to FileName lookup table
|
||||||
|
@ -328,14 +353,16 @@ class Cache:
|
||||||
if not file_name in cacheData.runrecs:
|
if not file_name in cacheData.runrecs:
|
||||||
cacheData.runrecs[file_name] = {}
|
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]:
|
for package in packages + [pn]:
|
||||||
if not package in cacheData.rundeps[file_name]:
|
if not package in cacheData.rundeps[file_name]:
|
||||||
cacheData.rundeps[file_name][package] = {}
|
cacheData.rundeps[file_name][package] = {}
|
||||||
if not package in cacheData.runrecs[file_name]:
|
if not package in cacheData.runrecs[file_name]:
|
||||||
cacheData.runrecs[file_name][package] = {}
|
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.rundeps[file_name][package], rdepends)
|
||||||
add_dep(cacheData.runrecs[file_name][package], bb.utils.explode_deps(self.getVar('RRECOMMENDS', file_name, True) or ""))
|
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.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 ""))
|
add_dep(cacheData.runrecs[file_name][package], bb.utils.explode_deps(self.getVar("RRECOMMENDS_%s" % package, file_name, True) or ""))
|
||||||
|
|
||||||
|
|
|
@ -97,14 +97,12 @@ class BBCooker:
|
||||||
bb.msg.note(2, bb.msg.domain.Build, "Renice to %s " % os.nice(nice))
|
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
|
Build one task of a package, optionally build following task depends
|
||||||
"""
|
"""
|
||||||
bb.event.fire(bb.event.PkgStarted(item, the_data))
|
bb.event.fire(bb.event.PkgStarted(item, the_data))
|
||||||
try:
|
try:
|
||||||
if not build_depends:
|
|
||||||
bb.data.setVarFlag('do_%s' % task, 'dontrundeps', 1, the_data)
|
|
||||||
if not self.configuration.dry_run:
|
if not self.configuration.dry_run:
|
||||||
bb.build.exec_task('do_%s' % task, the_data)
|
bb.build.exec_task('do_%s' % task, the_data)
|
||||||
bb.event.fire(bb.event.PkgSucceeded(item, 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))
|
bb.event.fire(bb.event.PkgFailed(item, the_data))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def tryBuild( self, fn, build_depends):
|
def tryBuild(self, fn):
|
||||||
"""
|
"""
|
||||||
Build a provider and its dependencies.
|
Build a provider and its dependencies.
|
||||||
build_depends is a list of previous build dependencies (not runtime)
|
build_depends is a list of previous build dependencies (not runtime)
|
||||||
If build_depends is empty, we're dealing with a runtime depends
|
If build_depends is empty, we're dealing with a runtime depends
|
||||||
"""
|
"""
|
||||||
|
|
||||||
the_data = self.bb_cache.loadDataFull(fn, self.configuration.data)
|
the_data = self.bb_cache.loadDataFull(fn, self.configuration.data)
|
||||||
|
|
||||||
item = self.status.pkg_fn[fn]
|
item = self.status.pkg_fn[fn]
|
||||||
|
|
||||||
if bb.build.stamp_is_current('do_%s' % self.configuration.cmd, the_data):
|
#if bb.build.stamp_is_current('do_%s' % self.configuration.cmd, the_data):
|
||||||
return True
|
# 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):
|
def showVersions(self):
|
||||||
pkg_pn = self.status.pkg_pn
|
pkg_pn = self.status.pkg_pn
|
||||||
|
@ -184,6 +181,8 @@ class BBCooker:
|
||||||
self.cb = None
|
self.cb = None
|
||||||
self.bb_cache = bb.cache.init(self)
|
self.bb_cache = bb.cache.init(self)
|
||||||
fn = self.matchFile(buildfile)
|
fn = self.matchFile(buildfile)
|
||||||
|
if not fn:
|
||||||
|
sys.exit(1)
|
||||||
elif len(pkgs_to_build) == 1:
|
elif len(pkgs_to_build) == 1:
|
||||||
self.updateCache()
|
self.updateCache()
|
||||||
|
|
||||||
|
@ -220,7 +219,7 @@ class BBCooker:
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
bb.msg.fatal(bb.msg.domain.Parsing, "%s" % e)
|
bb.msg.fatal(bb.msg.domain.Parsing, "%s" % e)
|
||||||
# emit the metadata which isnt valid shell
|
# emit the metadata which isnt valid shell
|
||||||
data.expandKeys( envdata )
|
data.expandKeys( envdata )
|
||||||
for e in envdata.keys():
|
for e in envdata.keys():
|
||||||
if data.getVarFlag( e, 'python', envdata ):
|
if data.getVarFlag( e, 'python', envdata ):
|
||||||
sys.__stdout__.write("\npython %s () {\n%s}\n" % (e, data.getVar(e, envdata, 1)))
|
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:
|
if fnid not in seen_fnids:
|
||||||
seen_fnids.append(fnid)
|
seen_fnids.append(fnid)
|
||||||
packages = []
|
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]:
|
for depend in self.status.deps[fn]:
|
||||||
print >> depends_file, '"%s" -> "%s"' % (pn, depend)
|
print >> depends_file, '"%s" -> "%s"' % (pn, depend)
|
||||||
rdepends = self.status.rundeps[fn]
|
rdepends = self.status.rundeps[fn]
|
||||||
|
@ -387,19 +386,15 @@ class BBCooker:
|
||||||
try:
|
try:
|
||||||
self.configuration.data = bb.parse.handle( afile, self.configuration.data )
|
self.configuration.data = bb.parse.handle( afile, self.configuration.data )
|
||||||
|
|
||||||
# Add the handlers we inherited by INHERIT
|
# Handle any INHERITs and inherit the base class
|
||||||
# we need to do this manually as it is not guranteed
|
inherits = ["base"] + (bb.data.getVar('INHERIT', self.configuration.data, True ) or "").split()
|
||||||
# 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()
|
|
||||||
for inherit in inherits:
|
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
|
# Nomally we only register event handlers at the end of parsing .bb files
|
||||||
for var in bb.data.keys(data):
|
# We register any handlers we've found so far here...
|
||||||
if bb.data.getVarFlag(var, 'handler', data):
|
for var in data.getVar('__BBHANDLERS', self.configuration.data) or []:
|
||||||
bb.event.register(var,bb.data.getVar(var, data))
|
bb.event.register(var,bb.data.getVar(var, self.configuration.data))
|
||||||
|
|
||||||
bb.fetch.fetcher_init(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)))
|
bb.msg.error(bb.msg.domain.Parsing, "Unable to match %s (%s matches found):" % (buildfile, len(matches)))
|
||||||
for f in matches:
|
for f in matches:
|
||||||
bb.msg.error(bb.msg.domain.Parsing, " %s" % f)
|
bb.msg.error(bb.msg.domain.Parsing, " %s" % f)
|
||||||
sys.exit(1)
|
return False
|
||||||
return matches[0]
|
return matches[0]
|
||||||
|
|
||||||
def buildFile(self, buildfile):
|
def buildFile(self, buildfile):
|
||||||
"""
|
"""
|
||||||
Build the file matching regexp 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
|
# Remove stamp for target if force mode active
|
||||||
if self.configuration.force:
|
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)
|
bb.build.del_stamp('do_%s' % self.configuration.cmd, bbfile_data)
|
||||||
|
|
||||||
item = bb.data.getVar('PN', bbfile_data, 1)
|
# Setup taskdata structure
|
||||||
try:
|
taskdata = bb.taskdata.TaskData(self.configuration.abort)
|
||||||
self.tryBuildPackage(bf, item, self.configuration.cmd, bbfile_data, True)
|
taskdata.add_provider(self.configuration.data, self.status, item)
|
||||||
except bb.build.EventException:
|
|
||||||
bb.msg.error(bb.msg.domain.Build, "Build of '%s' failed" % 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):
|
def buildTargets(self, targets):
|
||||||
"""
|
"""
|
||||||
|
@ -568,7 +595,9 @@ class BBCooker:
|
||||||
self.interactiveMode()
|
self.interactiveMode()
|
||||||
|
|
||||||
if self.configuration.buildfile is not None:
|
if self.configuration.buildfile is not None:
|
||||||
return self.buildFile(self.configuration.buildfile)
|
if not self.buildFile(self.configuration.buildfile):
|
||||||
|
sys.exit(1)
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
# initialise the parsing status now we know we will need deps
|
# initialise the parsing status now we know we will need deps
|
||||||
self.updateCache()
|
self.updateCache()
|
||||||
|
@ -676,7 +705,7 @@ class BBCooker:
|
||||||
for i in xrange( len( filelist ) ):
|
for i in xrange( len( filelist ) ):
|
||||||
f = filelist[i]
|
f = filelist[i]
|
||||||
|
|
||||||
bb.msg.debug(1, bb.msg.domain.Collection, "parsing %s" % f)
|
#bb.msg.debug(1, bb.msg.domain.Collection, "parsing %s" % f)
|
||||||
|
|
||||||
# read a file's metadata
|
# read a file's metadata
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -232,10 +232,10 @@ class DataSmart:
|
||||||
flags = {}
|
flags = {}
|
||||||
|
|
||||||
if local_var:
|
if local_var:
|
||||||
for i in self.dict[var].keys():
|
for i in local_var.keys():
|
||||||
if i == "content":
|
if i == "content":
|
||||||
continue
|
continue
|
||||||
flags[i] = self.dict[var][i]
|
flags[i] = local_var[i]
|
||||||
|
|
||||||
if len(flags) == 0:
|
if len(flags) == 0:
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -127,6 +127,23 @@ def getName(e):
|
||||||
class ConfigParsed(Event):
|
class ConfigParsed(Event):
|
||||||
"""Configuration Parsing Complete"""
|
"""Configuration Parsing Complete"""
|
||||||
|
|
||||||
|
class StampUpdate(Event):
|
||||||
|
"""Trigger for any adjustment of the stamp files to happen"""
|
||||||
|
|
||||||
|
def __init__(self, targets, stampfns, d):
|
||||||
|
self._targets = targets
|
||||||
|
self._stampfns = stampfns
|
||||||
|
Event.__init__(self, d)
|
||||||
|
|
||||||
|
def getStampPrefix(self):
|
||||||
|
return self._stampfns
|
||||||
|
|
||||||
|
def getTargets(self):
|
||||||
|
return self._targets
|
||||||
|
|
||||||
|
stampPrefix = property(getStampPrefix)
|
||||||
|
targets = property(getTargets)
|
||||||
|
|
||||||
class PkgBase(Event):
|
class PkgBase(Event):
|
||||||
"""Base class for package events"""
|
"""Base class for package events"""
|
||||||
|
|
||||||
|
|
|
@ -139,13 +139,21 @@ def go(d):
|
||||||
if not m.forcefetch(u, ud, d) and os.path.exists(ud.md5):
|
if not m.forcefetch(u, ud, d) and os.path.exists(ud.md5):
|
||||||
# File already present along with md5 stamp file
|
# File already present along with md5 stamp file
|
||||||
# Touch md5 file to show activity
|
# Touch md5 file to show activity
|
||||||
os.utime(ud.md5, None)
|
try:
|
||||||
|
os.utime(ud.md5, None)
|
||||||
|
except:
|
||||||
|
# Errors aren't fatal here
|
||||||
|
pass
|
||||||
continue
|
continue
|
||||||
lf = bb.utils.lockfile(ud.lockfile)
|
lf = bb.utils.lockfile(ud.lockfile)
|
||||||
if not m.forcefetch(u, ud, d) and os.path.exists(ud.md5):
|
if not m.forcefetch(u, ud, d) and os.path.exists(ud.md5):
|
||||||
# If someone else fetched this before we got the lock,
|
# If someone else fetched this before we got the lock,
|
||||||
# notice and don't try again
|
# notice and don't try again
|
||||||
os.utime(ud.md5, None)
|
try:
|
||||||
|
os.utime(ud.md5, None)
|
||||||
|
except:
|
||||||
|
# Errors aren't fatal here
|
||||||
|
pass
|
||||||
bb.utils.unlockfile(lf)
|
bb.utils.unlockfile(lf)
|
||||||
continue
|
continue
|
||||||
m.go(u, ud, d)
|
m.go(u, ud, d)
|
||||||
|
|
|
@ -95,6 +95,10 @@ def handle(fn, d, include = 0):
|
||||||
if ext == ".bbclass":
|
if ext == ".bbclass":
|
||||||
__classname__ = root
|
__classname__ = root
|
||||||
classes.append(__classname__)
|
classes.append(__classname__)
|
||||||
|
__inherit_cache = data.getVar('__inherit_cache', d) or []
|
||||||
|
if not fn in __inherit_cache:
|
||||||
|
__inherit_cache.append(fn)
|
||||||
|
data.setVar('__inherit_cache', __inherit_cache, d)
|
||||||
|
|
||||||
if include != 0:
|
if include != 0:
|
||||||
oldfile = data.getVar('FILE', d)
|
oldfile = data.getVar('FILE', d)
|
||||||
|
@ -126,10 +130,6 @@ def handle(fn, d, include = 0):
|
||||||
|
|
||||||
if ext != ".bbclass":
|
if ext != ".bbclass":
|
||||||
data.setVar('FILE', fn, d)
|
data.setVar('FILE', fn, d)
|
||||||
i = (data.getVar("INHERIT", d, 1) or "").split()
|
|
||||||
if not "base" in i and __classname__ != "base":
|
|
||||||
i[0:0] = ["base"]
|
|
||||||
inherit(i, d)
|
|
||||||
|
|
||||||
lineno = 0
|
lineno = 0
|
||||||
while 1:
|
while 1:
|
||||||
|
@ -171,33 +171,12 @@ def handle(fn, d, include = 0):
|
||||||
all_handlers = {}
|
all_handlers = {}
|
||||||
for var in data.getVar('__BBHANDLERS', d) or []:
|
for var in data.getVar('__BBHANDLERS', d) or []:
|
||||||
# try to add the handler
|
# try to add the handler
|
||||||
# if we added it remember the choiche
|
|
||||||
handler = data.getVar(var,d)
|
handler = data.getVar(var,d)
|
||||||
if bb.event.register(var,handler) == bb.event.Registered:
|
bb.event.register(var, handler)
|
||||||
all_handlers[var] = handler
|
|
||||||
|
|
||||||
tasklist = {}
|
|
||||||
for var in data.getVar('__BBTASKS', d) or []:
|
|
||||||
if var not in tasklist:
|
|
||||||
tasklist[var] = []
|
|
||||||
deps = data.getVarFlag(var, 'deps', d) or []
|
|
||||||
for p in deps:
|
|
||||||
if p not in tasklist[var]:
|
|
||||||
tasklist[var].append(p)
|
|
||||||
|
|
||||||
postdeps = data.getVarFlag(var, 'postdeps', d) or []
|
|
||||||
for p in postdeps:
|
|
||||||
if p not in tasklist:
|
|
||||||
tasklist[p] = []
|
|
||||||
if var not in tasklist[p]:
|
|
||||||
tasklist[p].append(var)
|
|
||||||
|
|
||||||
|
tasklist = data.getVar('__BBTASKS', d) or []
|
||||||
bb.build.add_tasks(tasklist, d)
|
bb.build.add_tasks(tasklist, d)
|
||||||
|
|
||||||
# now add the handlers
|
|
||||||
if not len(all_handlers) == 0:
|
|
||||||
data.setVar('__all_handlers__', all_handlers, d)
|
|
||||||
|
|
||||||
bbpath.pop(0)
|
bbpath.pop(0)
|
||||||
if oldfile:
|
if oldfile:
|
||||||
bb.data.setVar("FILE", oldfile, d)
|
bb.data.setVar("FILE", oldfile, d)
|
||||||
|
@ -342,15 +321,23 @@ def feeder(lineno, s, fn, root, d):
|
||||||
data.setVarFlag(var, "task", 1, d)
|
data.setVarFlag(var, "task", 1, d)
|
||||||
|
|
||||||
bbtasks = data.getVar('__BBTASKS', d) or []
|
bbtasks = data.getVar('__BBTASKS', d) or []
|
||||||
bbtasks.append(var)
|
if not var in bbtasks:
|
||||||
|
bbtasks.append(var)
|
||||||
data.setVar('__BBTASKS', bbtasks, d)
|
data.setVar('__BBTASKS', bbtasks, d)
|
||||||
|
|
||||||
|
existing = data.getVarFlag(var, "deps", d) or []
|
||||||
if after is not None:
|
if after is not None:
|
||||||
# set up deps for function
|
# set up deps for function
|
||||||
data.setVarFlag(var, "deps", after.split(), d)
|
for entry in after.split():
|
||||||
|
if entry not in existing:
|
||||||
|
existing.append(entry)
|
||||||
|
data.setVarFlag(var, "deps", existing, d)
|
||||||
if before is not None:
|
if before is not None:
|
||||||
# set up things that depend on this func
|
# set up things that depend on this func
|
||||||
data.setVarFlag(var, "postdeps", before.split(), d)
|
for entry in before.split():
|
||||||
|
existing = data.getVarFlag(entry, "deps", d) or []
|
||||||
|
if var not in existing:
|
||||||
|
data.setVarFlag(entry, "deps", [var] + existing, d)
|
||||||
return
|
return
|
||||||
|
|
||||||
m = __addhandler_regexp__.match(s)
|
m = __addhandler_regexp__.match(s)
|
||||||
|
|
|
@ -26,6 +26,7 @@ from bb import msg, data, event, mkdirhier, utils
|
||||||
from sets import Set
|
from sets import Set
|
||||||
import bb, os, sys
|
import bb, os, sys
|
||||||
import signal
|
import signal
|
||||||
|
import stat
|
||||||
|
|
||||||
class TaskFailure(Exception):
|
class TaskFailure(Exception):
|
||||||
"""Exception raised when a task in a runqueue fails"""
|
"""Exception raised when a task in a runqueue fails"""
|
||||||
|
@ -45,11 +46,11 @@ class RunQueueStats:
|
||||||
def taskFailed(self):
|
def taskFailed(self):
|
||||||
self.failed = self.failed + 1
|
self.failed = self.failed + 1
|
||||||
|
|
||||||
def taskCompleted(self):
|
def taskCompleted(self, number = 1):
|
||||||
self.completed = self.completed + 1
|
self.completed = self.completed + number
|
||||||
|
|
||||||
def taskSkipped(self):
|
def taskSkipped(self, number = 1):
|
||||||
self.skipped = self.skipped + 1
|
self.skipped = self.skipped + number
|
||||||
|
|
||||||
class RunQueueScheduler:
|
class RunQueueScheduler:
|
||||||
"""
|
"""
|
||||||
|
@ -144,8 +145,11 @@ class RunQueue:
|
||||||
self.taskData = taskData
|
self.taskData = taskData
|
||||||
self.targets = targets
|
self.targets = targets
|
||||||
|
|
||||||
self.number_tasks = int(bb.data.getVar("BB_NUMBER_THREADS", cfgData) or 1)
|
self.cfgdata = cfgData
|
||||||
self.multi_provider_whitelist = (bb.data.getVar("MULTI_PROVIDER_WHITELIST", cfgData) or "").split()
|
self.number_tasks = int(bb.data.getVar("BB_NUMBER_THREADS", cfgData, 1) or 1)
|
||||||
|
self.multi_provider_whitelist = (bb.data.getVar("MULTI_PROVIDER_WHITELIST", cfgData, 1) or "").split()
|
||||||
|
self.scheduler = bb.data.getVar("BB_SCHEDULER", cfgData, 1) or "speed"
|
||||||
|
self.stamppolicy = bb.data.getVar("BB_STAMP_POLICY", cfgData, 1) or "perfile"
|
||||||
|
|
||||||
def reset_runqueue(self):
|
def reset_runqueue(self):
|
||||||
|
|
||||||
|
@ -512,6 +516,7 @@ class RunQueue:
|
||||||
for depend in depends:
|
for depend in depends:
|
||||||
mark_active(depend, depth+1)
|
mark_active(depend, depth+1)
|
||||||
|
|
||||||
|
self.target_pairs = []
|
||||||
for target in self.targets:
|
for target in self.targets:
|
||||||
targetid = taskData.getbuild_id(target[0])
|
targetid = taskData.getbuild_id(target[0])
|
||||||
|
|
||||||
|
@ -522,10 +527,11 @@ class RunQueue:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
fnid = taskData.build_targets[targetid][0]
|
fnid = taskData.build_targets[targetid][0]
|
||||||
|
fn = taskData.fn_index[fnid]
|
||||||
|
self.target_pairs.append((fn, target[1]))
|
||||||
|
|
||||||
# Remove stamps for targets if force mode active
|
# Remove stamps for targets if force mode active
|
||||||
if self.cooker.configuration.force:
|
if self.cooker.configuration.force:
|
||||||
fn = taskData.fn_index[fnid]
|
|
||||||
bb.msg.note(2, bb.msg.domain.RunQueue, "Remove stamp %s, %s" % (target[1], fn))
|
bb.msg.note(2, bb.msg.domain.RunQueue, "Remove stamp %s, %s" % (target[1], fn))
|
||||||
bb.build.del_stamp(target[1], self.dataCache, fn)
|
bb.build.del_stamp(target[1], self.dataCache, fn)
|
||||||
|
|
||||||
|
@ -608,10 +614,11 @@ class RunQueue:
|
||||||
self.runq_weight = self.calculate_task_weights(endpoints)
|
self.runq_weight = self.calculate_task_weights(endpoints)
|
||||||
|
|
||||||
# Decide what order to execute the tasks in, pick a scheduler
|
# Decide what order to execute the tasks in, pick a scheduler
|
||||||
# FIXME - Allow user selection
|
|
||||||
#self.sched = RunQueueScheduler(self)
|
#self.sched = RunQueueScheduler(self)
|
||||||
self.sched = RunQueueSchedulerSpeed(self)
|
if self.scheduler == "completion":
|
||||||
#self.sched = RunQueueSchedulerCompletion(self)
|
self.sched = RunQueueSchedulerCompletion(self)
|
||||||
|
else:
|
||||||
|
self.sched = RunQueueSchedulerSpeed(self)
|
||||||
|
|
||||||
# Sanity Check - Check for multiple tasks building the same provider
|
# Sanity Check - Check for multiple tasks building the same provider
|
||||||
prov_list = {}
|
prov_list = {}
|
||||||
|
@ -636,6 +643,93 @@ class RunQueue:
|
||||||
|
|
||||||
#self.dump_data(taskData)
|
#self.dump_data(taskData)
|
||||||
|
|
||||||
|
def check_stamps(self):
|
||||||
|
unchecked = {}
|
||||||
|
current = []
|
||||||
|
notcurrent = []
|
||||||
|
buildable = []
|
||||||
|
|
||||||
|
if self.stamppolicy == "perfile":
|
||||||
|
fulldeptree = False
|
||||||
|
else:
|
||||||
|
fulldeptree = True
|
||||||
|
|
||||||
|
for task in range(len(self.runq_fnid)):
|
||||||
|
unchecked[task] = ""
|
||||||
|
if len(self.runq_depends[task]) == 0:
|
||||||
|
buildable.append(task)
|
||||||
|
|
||||||
|
for task in range(len(self.runq_fnid)):
|
||||||
|
if task not in unchecked:
|
||||||
|
continue
|
||||||
|
fn = self.taskData.fn_index[self.runq_fnid[task]]
|
||||||
|
taskname = self.runq_task[task]
|
||||||
|
stampfile = "%s.%s" % (self.dataCache.stamp[fn], taskname)
|
||||||
|
# If the stamp is missing its not current
|
||||||
|
if not os.access(stampfile, os.F_OK):
|
||||||
|
del unchecked[task]
|
||||||
|
notcurrent.append(task)
|
||||||
|
continue
|
||||||
|
# If its a 'nostamp' task, it's not current
|
||||||
|
taskdep = self.dataCache.task_deps[fn]
|
||||||
|
if 'nostamp' in taskdep and task in taskdep['nostamp']:
|
||||||
|
del unchecked[task]
|
||||||
|
notcurrent.append(task)
|
||||||
|
continue
|
||||||
|
|
||||||
|
while (len(buildable) > 0):
|
||||||
|
nextbuildable = []
|
||||||
|
for task in buildable:
|
||||||
|
if task in unchecked:
|
||||||
|
fn = self.taskData.fn_index[self.runq_fnid[task]]
|
||||||
|
taskname = self.runq_task[task]
|
||||||
|
stampfile = "%s.%s" % (self.dataCache.stamp[fn], taskname)
|
||||||
|
iscurrent = True
|
||||||
|
|
||||||
|
t1 = os.stat(stampfile)[stat.ST_MTIME]
|
||||||
|
for dep in self.runq_depends[task]:
|
||||||
|
if iscurrent:
|
||||||
|
fn2 = self.taskData.fn_index[self.runq_fnid[dep]]
|
||||||
|
taskname2 = self.runq_task[dep]
|
||||||
|
stampfile2 = "%s.%s" % (self.dataCache.stamp[fn2], taskname2)
|
||||||
|
if fulldeptree or fn == fn2:
|
||||||
|
if dep in notcurrent:
|
||||||
|
iscurrent = False
|
||||||
|
else:
|
||||||
|
t2 = os.stat(stampfile2)[stat.ST_MTIME]
|
||||||
|
if t1 < t2:
|
||||||
|
iscurrent = False
|
||||||
|
del unchecked[task]
|
||||||
|
if iscurrent:
|
||||||
|
current.append(task)
|
||||||
|
else:
|
||||||
|
notcurrent.append(task)
|
||||||
|
|
||||||
|
for revdep in self.runq_revdeps[task]:
|
||||||
|
alldeps = 1
|
||||||
|
for dep in self.runq_depends[revdep]:
|
||||||
|
if dep in unchecked:
|
||||||
|
alldeps = 0
|
||||||
|
if alldeps == 1:
|
||||||
|
if revdep in unchecked:
|
||||||
|
nextbuildable.append(revdep)
|
||||||
|
|
||||||
|
buildable = nextbuildable
|
||||||
|
|
||||||
|
#for task in range(len(self.runq_fnid)):
|
||||||
|
# fn = self.taskData.fn_index[self.runq_fnid[task]]
|
||||||
|
# taskname = self.runq_task[task]
|
||||||
|
# print "%s %s.%s" % (task, taskname, fn)
|
||||||
|
|
||||||
|
#print "Unchecked: %s" % unchecked
|
||||||
|
#print "Current: %s" % current
|
||||||
|
#print "Not current: %s" % notcurrent
|
||||||
|
|
||||||
|
if len(unchecked) > 0:
|
||||||
|
bb.fatal("check_stamps fatal internal error")
|
||||||
|
return current
|
||||||
|
|
||||||
|
|
||||||
def execute_runqueue(self):
|
def execute_runqueue(self):
|
||||||
"""
|
"""
|
||||||
Run the tasks in a queue prepared by prepare_runqueue
|
Run the tasks in a queue prepared by prepare_runqueue
|
||||||
|
@ -721,18 +815,13 @@ class RunQueue:
|
||||||
def sigint_handler(signum, frame):
|
def sigint_handler(signum, frame):
|
||||||
raise KeyboardInterrupt
|
raise KeyboardInterrupt
|
||||||
|
|
||||||
# RP - this code allows tasks to run out of the correct order - disabled, FIXME
|
event.fire(bb.event.StampUpdate(self.target_pairs, self.dataCache.stamp, self.cfgdata))
|
||||||
# Find any tasks with current stamps and remove them from the queue
|
|
||||||
#for task1 in range(len(self.runq_fnid)):
|
# Find out which tasks have current stamps which we can skip when the
|
||||||
# task = self.prio_map[task1]
|
# time comes
|
||||||
# fn = self.taskData.fn_index[self.runq_fnid[task]]
|
currentstamps = self.check_stamps()
|
||||||
# taskname = self.runq_task[task]
|
self.stats.taskSkipped(len(currentstamps))
|
||||||
# if bb.build.stamp_is_current(taskname, self.dataCache, fn):
|
self.stats.taskCompleted(len(currentstamps))
|
||||||
# bb.msg.debug(2, bb.msg.domain.RunQueue, "Stamp current task %s (%s)" % (task, self.get_user_idstring(task)))
|
|
||||||
# self.runq_running[task] = 1
|
|
||||||
# self.task_complete(task)
|
|
||||||
# self.stats.taskCompleted()
|
|
||||||
# self.stats.taskSkipped()
|
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
task = self.sched.next()
|
task = self.sched.next()
|
||||||
|
@ -740,12 +829,13 @@ class RunQueue:
|
||||||
fn = self.taskData.fn_index[self.runq_fnid[task]]
|
fn = self.taskData.fn_index[self.runq_fnid[task]]
|
||||||
|
|
||||||
taskname = self.runq_task[task]
|
taskname = self.runq_task[task]
|
||||||
if bb.build.stamp_is_current(taskname, self.dataCache, fn):
|
if task in currentstamps:
|
||||||
|
#if bb.build.stamp_is_current(taskname, self.dataCache, fn):
|
||||||
bb.msg.debug(2, bb.msg.domain.RunQueue, "Stamp current task %s (%s)" % (task, self.get_user_idstring(task)))
|
bb.msg.debug(2, bb.msg.domain.RunQueue, "Stamp current task %s (%s)" % (task, self.get_user_idstring(task)))
|
||||||
self.runq_running[task] = 1
|
self.runq_running[task] = 1
|
||||||
self.task_complete(task)
|
self.task_complete(task)
|
||||||
self.stats.taskCompleted()
|
#self.stats.taskCompleted()
|
||||||
self.stats.taskSkipped()
|
#self.stats.taskSkipped()
|
||||||
continue
|
continue
|
||||||
|
|
||||||
bb.msg.note(1, bb.msg.domain.RunQueue, "Running task %d of %d (ID: %s, %s)" % (self.stats.completed + self.active_builds + 1, len(self.runq_fnid), task, self.get_user_idstring(task)))
|
bb.msg.note(1, bb.msg.domain.RunQueue, "Running task %d of %d (ID: %s, %s)" % (self.stats.completed + self.active_builds + 1, len(self.runq_fnid), task, self.get_user_idstring(task)))
|
||||||
|
@ -764,7 +854,7 @@ class RunQueue:
|
||||||
os.dup2(newsi, sys.stdin.fileno())
|
os.dup2(newsi, sys.stdin.fileno())
|
||||||
self.cooker.configuration.cmd = taskname[3:]
|
self.cooker.configuration.cmd = taskname[3:]
|
||||||
try:
|
try:
|
||||||
self.cooker.tryBuild(fn, False)
|
self.cooker.tryBuild(fn)
|
||||||
except bb.build.EventException:
|
except bb.build.EventException:
|
||||||
bb.msg.error(bb.msg.domain.Build, "Build of " + fn + " " + taskname + " failed")
|
bb.msg.error(bb.msg.domain.Build, "Build of " + fn + " " + taskname + " failed")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
|
@ -243,27 +243,13 @@ class BitBakeShellCommands:
|
||||||
oldcmd = cooker.configuration.cmd
|
oldcmd = cooker.configuration.cmd
|
||||||
cooker.configuration.cmd = cmd
|
cooker.configuration.cmd = cmd
|
||||||
|
|
||||||
thisdata = data.createCopy(cooker.configuration.data)
|
|
||||||
data.update_data(thisdata)
|
|
||||||
data.expandKeys(thisdata)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
bbfile_data = parse.handle( bf, thisdata )
|
cooker.buildFile(bf)
|
||||||
except parse.ParseError:
|
except parse.ParseError:
|
||||||
print "ERROR: Unable to open or parse '%s'" % bf
|
print "ERROR: Unable to open or parse '%s'" % bf
|
||||||
else:
|
except build.EventException, e:
|
||||||
# Remove stamp for target if force mode active
|
print "ERROR: Couldn't build '%s'" % name
|
||||||
if cooker.configuration.force:
|
last_exception = e
|
||||||
bb.msg.note(2, bb.msg.domain.RunQueue, "Remove stamp %s, %s" % (cmd, bf))
|
|
||||||
bb.build.del_stamp('do_%s' % cmd, bbfile_data)
|
|
||||||
|
|
||||||
item = data.getVar('PN', bbfile_data, 1)
|
|
||||||
data.setVar( "_task_cache", [], bbfile_data ) # force
|
|
||||||
try:
|
|
||||||
cooker.tryBuildPackage( os.path.abspath( bf ), item, cmd, bbfile_data, True )
|
|
||||||
except build.EventException, e:
|
|
||||||
print "ERROR: Couldn't build '%s'" % name
|
|
||||||
last_exception = e
|
|
||||||
|
|
||||||
cooker.configuration.cmd = oldcmd
|
cooker.configuration.cmd = oldcmd
|
||||||
fileBuild.usage = "<bbfile>"
|
fileBuild.usage = "<bbfile>"
|
||||||
|
@ -586,6 +572,7 @@ SRC_URI = ""
|
||||||
|
|
||||||
def completeFilePath( bbfile ):
|
def completeFilePath( bbfile ):
|
||||||
"""Get the complete bbfile path"""
|
"""Get the complete bbfile path"""
|
||||||
|
if not cooker.status: return bbfile
|
||||||
if not cooker.status.pkg_fn: return bbfile
|
if not cooker.status.pkg_fn: return bbfile
|
||||||
for key in cooker.status.pkg_fn.keys():
|
for key in cooker.status.pkg_fn.keys():
|
||||||
if key.endswith( bbfile ):
|
if key.endswith( bbfile ):
|
||||||
|
|
|
@ -124,7 +124,6 @@ class TaskData:
|
||||||
Add tasks for a given fn to the database
|
Add tasks for a given fn to the database
|
||||||
"""
|
"""
|
||||||
|
|
||||||
task_graph = dataCache.task_queues[fn]
|
|
||||||
task_deps = dataCache.task_deps[fn]
|
task_deps = dataCache.task_deps[fn]
|
||||||
|
|
||||||
fnid = self.getfn_id(fn)
|
fnid = self.getfn_id(fn)
|
||||||
|
@ -136,11 +135,11 @@ class TaskData:
|
||||||
if fnid in self.tasks_fnid:
|
if fnid in self.tasks_fnid:
|
||||||
return
|
return
|
||||||
|
|
||||||
for task in task_graph.allnodes():
|
for task in task_deps['tasks']:
|
||||||
|
|
||||||
# Work out task dependencies
|
# Work out task dependencies
|
||||||
parentids = []
|
parentids = []
|
||||||
for dep in task_graph.getparents(task):
|
for dep in task_deps['parents'][task]:
|
||||||
parentid = self.gettask_id(fn, dep)
|
parentid = self.gettask_id(fn, dep)
|
||||||
parentids.append(parentid)
|
parentids.append(parentid)
|
||||||
taskid = self.gettask_id(fn, task)
|
taskid = self.gettask_id(fn, task)
|
||||||
|
|
|
@ -85,11 +85,11 @@ def explode_deps(s):
|
||||||
for i in l:
|
for i in l:
|
||||||
if i[0] == '(':
|
if i[0] == '(':
|
||||||
flag = True
|
flag = True
|
||||||
j = []
|
#j = []
|
||||||
if flag:
|
if not flag:
|
||||||
j.append(i)
|
|
||||||
else:
|
|
||||||
r.append(i)
|
r.append(i)
|
||||||
|
#else:
|
||||||
|
# j.append(i)
|
||||||
if flag and i.endswith(')'):
|
if flag and i.endswith(')'):
|
||||||
flag = False
|
flag = False
|
||||||
# Ignore version
|
# Ignore version
|
||||||
|
|
Loading…
Reference in New Issue