M7350/oe-core/bitbake/lib/bb/build.py

712 lines
22 KiB
Python
Raw Normal View History

2024-09-09 08:52:07 +00:00
# ex:ts=4:sw=4:sts=4:et
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
#
# BitBake 'Build' implementation
#
# Core code for function execution and task handling in the
# BitBake build tools.
#
# Copyright (C) 2003, 2004 Chris Larson
#
# Based on Gentoo's portage.py.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
2024-09-09 08:57:42 +00:00
# Based on functions from the base bb module, Copyright 2003 Holger Schurig
2024-09-09 08:52:07 +00:00
import os
import sys
import logging
import shlex
2024-09-09 08:57:42 +00:00
import glob
import time
2024-09-09 08:52:07 +00:00
import bb
import bb.msg
import bb.process
from contextlib import nested
2024-09-09 08:57:42 +00:00
from bb import event, utils
2024-09-09 08:52:07 +00:00
bblogger = logging.getLogger('BitBake')
logger = logging.getLogger('BitBake.Build')
NULL = open(os.devnull, 'r+')
2024-09-09 08:57:42 +00:00
# When we execute a Python function, we'd like certain things
# in all namespaces, hence we add them to __builtins__.
2024-09-09 08:52:07 +00:00
# If we do not do this and use the exec globals, they will
# not be available to subfunctions.
__builtins__['bb'] = bb
__builtins__['os'] = os
class FuncFailed(Exception):
def __init__(self, name = None, logfile = None):
self.logfile = logfile
self.name = name
if name:
self.msg = 'Function failed: %s' % name
else:
self.msg = "Function failed"
def __str__(self):
if self.logfile and os.path.exists(self.logfile):
2024-09-09 08:57:42 +00:00
msg = ("%s (log file is located at %s)" %
2024-09-09 08:52:07 +00:00
(self.msg, self.logfile))
else:
msg = self.msg
return msg
class TaskBase(event.Event):
"""Base class for task events"""
2024-09-09 08:57:42 +00:00
def __init__(self, t, logfile, d):
2024-09-09 08:52:07 +00:00
self._task = t
2024-09-09 08:57:42 +00:00
self._package = d.getVar("PF", True)
self.taskfile = d.getVar("FILE", True)
self.taskname = self._task
self.logfile = logfile
self.time = time.time()
2024-09-09 08:52:07 +00:00
event.Event.__init__(self)
2024-09-09 08:57:42 +00:00
self._message = "recipe %s: task %s: %s" % (d.getVar("PF", True), t, self.getDisplayName())
2024-09-09 08:52:07 +00:00
def getTask(self):
return self._task
def setTask(self, task):
self._task = task
2024-09-09 08:57:42 +00:00
def getDisplayName(self):
return bb.event.getName(self)[4:]
2024-09-09 08:52:07 +00:00
task = property(getTask, setTask, None, "task property")
class TaskStarted(TaskBase):
"""Task execution started"""
2024-09-09 08:57:42 +00:00
def __init__(self, t, logfile, taskflags, d):
super(TaskStarted, self).__init__(t, logfile, d)
self.taskflags = taskflags
2024-09-09 08:52:07 +00:00
class TaskSucceeded(TaskBase):
"""Task execution completed"""
class TaskFailed(TaskBase):
"""Task execution failed"""
def __init__(self, task, logfile, metadata, errprinted = False):
self.errprinted = errprinted
2024-09-09 08:57:42 +00:00
super(TaskFailed, self).__init__(task, logfile, metadata)
class TaskFailedSilent(TaskBase):
"""Task execution failed (silently)"""
def getDisplayName(self):
# Don't need to tell the user it was silent
return "Failed"
2024-09-09 08:52:07 +00:00
class TaskInvalid(TaskBase):
def __init__(self, task, metadata):
2024-09-09 08:57:42 +00:00
super(TaskInvalid, self).__init__(task, None, metadata)
2024-09-09 08:52:07 +00:00
self._message = "No such task '%s'" % task
class LogTee(object):
def __init__(self, logger, outfile):
self.outfile = outfile
self.logger = logger
self.name = self.outfile.name
def write(self, string):
self.logger.plain(string)
self.outfile.write(string)
def __enter__(self):
self.outfile.__enter__()
return self
def __exit__(self, *excinfo):
self.outfile.__exit__(*excinfo)
def __repr__(self):
return '<LogTee {0}>'.format(self.name)
2024-09-09 08:57:42 +00:00
def flush(self):
self.outfile.flush()
2024-09-09 08:52:07 +00:00
def exec_func(func, d, dirs = None):
2024-09-09 08:57:42 +00:00
"""Execute a BB 'function'"""
2024-09-09 08:52:07 +00:00
2024-09-09 08:57:42 +00:00
body = d.getVar(func)
2024-09-09 08:52:07 +00:00
if not body:
if body is None:
logger.warn("Function %s doesn't exist", func)
return
2024-09-09 08:57:42 +00:00
flags = d.getVarFlags(func)
2024-09-09 08:52:07 +00:00
cleandirs = flags.get('cleandirs')
if cleandirs:
2024-09-09 08:57:42 +00:00
for cdir in d.expand(cleandirs).split():
2024-09-09 08:52:07 +00:00
bb.utils.remove(cdir, True)
2024-09-09 08:57:42 +00:00
bb.utils.mkdirhier(cdir)
2024-09-09 08:52:07 +00:00
if dirs is None:
dirs = flags.get('dirs')
if dirs:
2024-09-09 08:57:42 +00:00
dirs = d.expand(dirs).split()
2024-09-09 08:52:07 +00:00
if dirs:
for adir in dirs:
bb.utils.mkdirhier(adir)
adir = dirs[-1]
else:
2024-09-09 08:57:42 +00:00
adir = d.getVar('B', True)
2024-09-09 08:52:07 +00:00
bb.utils.mkdirhier(adir)
ispython = flags.get('python')
lockflag = flags.get('lockfiles')
if lockflag:
2024-09-09 08:57:42 +00:00
lockfiles = [f for f in d.expand(lockflag).split()]
2024-09-09 08:52:07 +00:00
else:
lockfiles = None
2024-09-09 08:57:42 +00:00
tempdir = d.getVar('T', True)
# or func allows items to be executed outside of the normal
# task set, such as buildhistory
task = d.getVar('BB_RUNTASK', True) or func
if task == func:
taskfunc = task
else:
taskfunc = "%s.%s" % (task, func)
runfmt = d.getVar('BB_RUNFMT', True) or "run.{func}.{pid}"
runfn = runfmt.format(taskfunc=taskfunc, task=task, func=func, pid=os.getpid())
runfile = os.path.join(tempdir, runfn)
bb.utils.mkdirhier(os.path.dirname(runfile))
# Setup the courtesy link to the runfn, only for tasks
# we create the link 'just' before the run script is created
# if we create it after, and if the run script fails, then the
# link won't be created as an exception would be fired.
if task == func:
runlink = os.path.join(tempdir, 'run.{0}'.format(task))
if runlink:
bb.utils.remove(runlink)
try:
os.symlink(runfn, runlink)
except OSError:
pass
2024-09-09 08:52:07 +00:00
with bb.utils.fileslocked(lockfiles):
if ispython:
exec_func_python(func, d, runfile, cwd=adir)
else:
exec_func_shell(func, d, runfile, cwd=adir)
_functionfmt = """
def {function}(d):
{body}
{function}(d)
"""
logformatter = bb.msg.BBLogFormatter("%(levelname)s: %(message)s")
def exec_func_python(func, d, runfile, cwd=None):
"""Execute a python BB 'function'"""
bbfile = d.getVar('FILE', True)
code = _functionfmt.format(function=func, body=d.getVar(func, True))
bb.utils.mkdirhier(os.path.dirname(runfile))
with open(runfile, 'w') as script:
2024-09-09 08:57:42 +00:00
bb.data.emit_func_python(func, script, d)
2024-09-09 08:52:07 +00:00
if cwd:
try:
olddir = os.getcwd()
except OSError:
olddir = None
os.chdir(cwd)
2024-09-09 08:57:42 +00:00
bb.debug(2, "Executing python function %s" % func)
2024-09-09 08:52:07 +00:00
try:
comp = utils.better_compile(code, func, bbfile)
utils.better_exec(comp, {"d": d}, code, bbfile)
2024-09-09 08:57:42 +00:00
except (bb.parse.SkipRecipe, bb.build.FuncFailed):
raise
2024-09-09 08:52:07 +00:00
except:
raise FuncFailed(func, None)
finally:
2024-09-09 08:57:42 +00:00
bb.debug(2, "Python function %s finished" % func)
2024-09-09 08:52:07 +00:00
if cwd and olddir:
try:
os.chdir(olddir)
except OSError:
pass
2024-09-09 08:57:42 +00:00
def shell_trap_code():
return '''#!/bin/sh\n
# Emit a useful diagnostic if something fails:
bb_exit_handler() {
ret=$?
case $ret in
0) ;;
*) case $BASH_VERSION in
"") echo "WARNING: exit code $ret from a shell command.";;
*) echo "WARNING: ${BASH_SOURCE[0]}:${BASH_LINENO[0]} exit $ret from
\"$BASH_COMMAND\"";;
esac
exit $ret
esac
}
trap 'bb_exit_handler' 0
set -e
'''
def exec_func_shell(func, d, runfile, cwd=None):
2024-09-09 08:52:07 +00:00
"""Execute a shell function from the metadata
Note on directory behavior. The 'dirs' varflag should contain a list
of the directories you need created prior to execution. The last
item in the list is where we will chdir/cd to.
"""
# Don't let the emitted shell script override PWD
d.delVarFlag('PWD', 'export')
with open(runfile, 'w') as script:
2024-09-09 08:57:42 +00:00
script.write(shell_trap_code())
bb.data.emit_func(func, script, d)
2024-09-09 08:52:07 +00:00
2024-09-09 08:57:42 +00:00
if bb.msg.loggerVerboseLogs:
script.write("set -x\n")
2024-09-09 08:52:07 +00:00
if cwd:
2024-09-09 08:57:42 +00:00
script.write("cd '%s'\n" % cwd)
script.write("%s\n" % func)
script.write('''
# cleanup
ret=$?
trap '' 0
exit $?
''')
2024-09-09 08:52:07 +00:00
os.chmod(runfile, 0775)
cmd = runfile
2024-09-09 08:57:42 +00:00
if d.getVarFlag(func, 'fakeroot'):
2024-09-09 08:52:07 +00:00
fakerootcmd = d.getVar('FAKEROOT', True)
if fakerootcmd:
cmd = [fakerootcmd, runfile]
if bb.msg.loggerDefaultVerbose:
logfile = LogTee(logger, sys.stdout)
else:
logfile = sys.stdout
2024-09-09 08:57:42 +00:00
bb.debug(2, "Executing shell function %s" % func)
2024-09-09 08:52:07 +00:00
try:
2024-09-09 08:57:42 +00:00
with open(os.devnull, 'r+') as stdin:
bb.process.run(cmd, shell=False, stdin=stdin, log=logfile)
2024-09-09 08:52:07 +00:00
except bb.process.CmdError:
logfn = d.getVar('BB_LOGFILE', True)
2024-09-09 08:57:42 +00:00
raise FuncFailed(func, logfn)
bb.debug(2, "Shell function %s finished" % func)
2024-09-09 08:52:07 +00:00
def _task_data(fn, task, d):
2024-09-09 08:57:42 +00:00
localdata = bb.data.createCopy(d)
2024-09-09 08:52:07 +00:00
localdata.setVar('BB_FILENAME', fn)
localdata.setVar('BB_CURRENTTASK', task[3:])
localdata.setVar('OVERRIDES', 'task-%s:%s' %
2024-09-09 08:57:42 +00:00
(task[3:].replace('_', '-'), d.getVar('OVERRIDES', False)))
2024-09-09 08:52:07 +00:00
localdata.finalize()
2024-09-09 08:57:42 +00:00
bb.data.expandKeys(localdata)
2024-09-09 08:52:07 +00:00
return localdata
def _exec_task(fn, task, d, quieterr):
"""Execute a BB 'task'
Execution of a task involves a bit more setup than executing a function,
running it with its own local metadata, and with some useful variables set.
"""
2024-09-09 08:57:42 +00:00
if not d.getVarFlag(task, 'task'):
2024-09-09 08:52:07 +00:00
event.fire(TaskInvalid(task, d), d)
logger.error("No such task: %s" % task)
return 1
logger.debug(1, "Executing task %s", task)
localdata = _task_data(fn, task, d)
tempdir = localdata.getVar('T', True)
if not tempdir:
bb.fatal("T variable not set, unable to build")
2024-09-09 08:57:42 +00:00
# Change nice level if we're asked to
nice = localdata.getVar("BB_TASK_NICE_LEVEL", True)
if nice:
curnice = os.nice(0)
nice = int(nice) - curnice
newnice = os.nice(nice)
logger.debug(1, "Renice to %s " % newnice)
2024-09-09 08:52:07 +00:00
bb.utils.mkdirhier(tempdir)
2024-09-09 08:57:42 +00:00
# Determine the logfile to generate
logfmt = localdata.getVar('BB_LOGFMT', True) or 'log.{task}.{pid}'
logbase = logfmt.format(task=task, pid=os.getpid())
# Document the order of the tasks...
logorder = os.path.join(tempdir, 'log.task_order')
try:
with open(logorder, 'a') as logorderfile:
logorderfile.write('{0} ({1}): {2}\n'.format(task, os.getpid(), logbase))
except OSError:
logger.exception("Opening log file '%s'", logorder)
pass
# Setup the courtesy link to the logfn
2024-09-09 08:52:07 +00:00
loglink = os.path.join(tempdir, 'log.{0}'.format(task))
2024-09-09 08:57:42 +00:00
logfn = os.path.join(tempdir, logbase)
2024-09-09 08:52:07 +00:00
if loglink:
bb.utils.remove(loglink)
try:
2024-09-09 08:57:42 +00:00
os.symlink(logbase, loglink)
2024-09-09 08:52:07 +00:00
except OSError:
pass
prefuncs = localdata.getVarFlag(task, 'prefuncs', expand=True)
postfuncs = localdata.getVarFlag(task, 'postfuncs', expand=True)
class ErrorCheckHandler(logging.Handler):
def __init__(self):
self.triggered = False
logging.Handler.__init__(self, logging.ERROR)
def emit(self, record):
self.triggered = True
# Handle logfiles
2024-09-09 08:57:42 +00:00
si = open('/dev/null', 'r')
2024-09-09 08:52:07 +00:00
try:
2024-09-09 08:57:42 +00:00
bb.utils.mkdirhier(os.path.dirname(logfn))
logfile = open(logfn, 'w')
2024-09-09 08:52:07 +00:00
except OSError:
logger.exception("Opening log file '%s'", logfn)
pass
# Dup the existing fds so we dont lose them
osi = [os.dup(sys.stdin.fileno()), sys.stdin.fileno()]
oso = [os.dup(sys.stdout.fileno()), sys.stdout.fileno()]
ose = [os.dup(sys.stderr.fileno()), sys.stderr.fileno()]
# Replace those fds with our own
os.dup2(si.fileno(), osi[1])
os.dup2(logfile.fileno(), oso[1])
os.dup2(logfile.fileno(), ose[1])
2024-09-09 08:57:42 +00:00
# Ensure Python logging goes to the logfile
2024-09-09 08:52:07 +00:00
handler = logging.StreamHandler(logfile)
handler.setFormatter(logformatter)
# Always enable full debug output into task logfiles
handler.setLevel(logging.DEBUG - 2)
bblogger.addHandler(handler)
errchk = ErrorCheckHandler()
bblogger.addHandler(errchk)
localdata.setVar('BB_LOGFILE', logfn)
2024-09-09 08:57:42 +00:00
localdata.setVar('BB_RUNTASK', task)
flags = localdata.getVarFlags(task)
2024-09-09 08:52:07 +00:00
2024-09-09 08:57:42 +00:00
event.fire(TaskStarted(task, logfn, flags, localdata), localdata)
2024-09-09 08:52:07 +00:00
try:
for func in (prefuncs or '').split():
exec_func(func, localdata)
exec_func(task, localdata)
for func in (postfuncs or '').split():
exec_func(func, localdata)
except FuncFailed as exc:
2024-09-09 08:57:42 +00:00
if quieterr:
event.fire(TaskFailedSilent(task, logfn, localdata), localdata)
else:
2024-09-09 08:52:07 +00:00
errprinted = errchk.triggered
logger.error(str(exc))
event.fire(TaskFailed(task, logfn, localdata, errprinted), localdata)
return 1
finally:
sys.stdout.flush()
sys.stderr.flush()
bblogger.removeHandler(handler)
# Restore the backup fds
os.dup2(osi[0], osi[1])
os.dup2(oso[0], oso[1])
os.dup2(ose[0], ose[1])
# Close the backup fds
os.close(osi[0])
os.close(oso[0])
os.close(ose[0])
si.close()
logfile.close()
if os.path.exists(logfn) and os.path.getsize(logfn) == 0:
logger.debug(2, "Zero size logfn %s, removing", logfn)
bb.utils.remove(logfn)
bb.utils.remove(loglink)
2024-09-09 08:57:42 +00:00
event.fire(TaskSucceeded(task, logfn, localdata), localdata)
2024-09-09 08:52:07 +00:00
if not localdata.getVarFlag(task, 'nostamp') and not localdata.getVarFlag(task, 'selfstamp'):
make_stamp(task, localdata)
return 0
2024-09-09 08:57:42 +00:00
def exec_task(fn, task, d, profile = False):
try:
2024-09-09 08:52:07 +00:00
quieterr = False
if d.getVarFlag(task, "quieterrors") is not None:
quieterr = True
2024-09-09 08:57:42 +00:00
if profile:
profname = "profile-%s.log" % (d.getVar("PN", True) + "-" + task)
try:
import cProfile as profile
except:
import profile
prof = profile.Profile()
ret = profile.Profile.runcall(prof, _exec_task, fn, task, d, quieterr)
prof.dump_stats(profname)
bb.utils.process_profilelog(profname)
return ret
else:
return _exec_task(fn, task, d, quieterr)
2024-09-09 08:52:07 +00:00
except Exception:
from traceback import format_exc
if not quieterr:
logger.error("Build of %s failed" % (task))
logger.error(format_exc())
failedevent = TaskFailed(task, None, d, True)
event.fire(failedevent, d)
return 1
2024-09-09 08:57:42 +00:00
def stamp_internal(taskname, d, file_name, baseonly=False):
2024-09-09 08:52:07 +00:00
"""
Internal stamp helper function
Makes sure the stamp directory exists
Returns the stamp path+filename
In the bitbake core, d can be a CacheData and file_name will be set.
When called in task context, d will be a data store, file_name will not be set
"""
taskflagname = taskname
if taskname.endswith("_setscene") and taskname != "do_setscene":
taskflagname = taskname.replace("_setscene", "")
if file_name:
stamp = d.stamp_base[file_name].get(taskflagname) or d.stamp[file_name]
extrainfo = d.stamp_extrainfo[file_name].get(taskflagname) or ""
else:
stamp = d.getVarFlag(taskflagname, 'stamp-base', True) or d.getVar('STAMP', True)
file_name = d.getVar('BB_FILENAME', True)
extrainfo = d.getVarFlag(taskflagname, 'stamp-extra-info', True) or ""
2024-09-09 08:57:42 +00:00
if baseonly:
return stamp
2024-09-09 08:52:07 +00:00
if not stamp:
return
stamp = bb.parse.siggen.stampfile(stamp, file_name, taskname, extrainfo)
2024-09-09 08:57:42 +00:00
stampdir = os.path.dirname(stamp)
if bb.parse.cached_mtime_noerror(stampdir) == 0:
bb.utils.mkdirhier(stampdir)
2024-09-09 08:52:07 +00:00
return stamp
2024-09-09 08:57:42 +00:00
def stamp_cleanmask_internal(taskname, d, file_name):
"""
Internal stamp helper function to generate stamp cleaning mask
Returns the stamp path+filename
In the bitbake core, d can be a CacheData and file_name will be set.
When called in task context, d will be a data store, file_name will not be set
"""
taskflagname = taskname
if taskname.endswith("_setscene") and taskname != "do_setscene":
taskflagname = taskname.replace("_setscene", "")
if file_name:
stamp = d.stamp_base_clean[file_name].get(taskflagname) or d.stampclean[file_name]
extrainfo = d.stamp_extrainfo[file_name].get(taskflagname) or ""
else:
stamp = d.getVarFlag(taskflagname, 'stamp-base-clean', True) or d.getVar('STAMPCLEAN', True)
file_name = d.getVar('BB_FILENAME', True)
extrainfo = d.getVarFlag(taskflagname, 'stamp-extra-info', True) or ""
if not stamp:
return []
cleanmask = bb.parse.siggen.stampcleanmask(stamp, file_name, taskname, extrainfo)
return [cleanmask, cleanmask.replace(taskflagname, taskflagname + "_setscene")]
2024-09-09 08:52:07 +00:00
def make_stamp(task, d, file_name = None):
"""
Creates/updates a stamp for a given task
(d can be a data dict or dataCache)
"""
2024-09-09 08:57:42 +00:00
cleanmask = stamp_cleanmask_internal(task, d, file_name)
for mask in cleanmask:
for name in glob.glob(mask):
# Preserve sigdata files in the stamps directory
if "sigdata" in name:
continue
# Preserve taint files in the stamps directory
if name.endswith('.taint'):
continue
os.unlink(name)
2024-09-09 08:52:07 +00:00
stamp = stamp_internal(task, d, file_name)
# Remove the file and recreate to force timestamp
# change on broken NFS filesystems
if stamp:
bb.utils.remove(stamp)
2024-09-09 08:57:42 +00:00
open(stamp, "w").close()
2024-09-09 08:52:07 +00:00
# If we're in task context, write out a signature file for each task
# as it completes
if not task.endswith("_setscene") and task != "do_setscene" and not file_name:
2024-09-09 08:57:42 +00:00
stampbase = stamp_internal(task, d, None, True)
2024-09-09 08:52:07 +00:00
file_name = d.getVar('BB_FILENAME', True)
2024-09-09 08:57:42 +00:00
bb.parse.siggen.dump_sigtask(file_name, task, stampbase, True)
2024-09-09 08:52:07 +00:00
def del_stamp(task, d, file_name = None):
"""
Removes a stamp for a given task
(d can be a data dict or dataCache)
"""
stamp = stamp_internal(task, d, file_name)
bb.utils.remove(stamp)
2024-09-09 08:57:42 +00:00
def write_taint(task, d, file_name = None):
"""
Creates a "taint" file which will force the specified task and its
dependents to be re-run the next time by influencing the value of its
taskhash.
(d can be a data dict or dataCache)
"""
import uuid
if file_name:
taintfn = d.stamp[file_name] + '.' + task + '.taint'
else:
taintfn = d.getVar('STAMP', True) + '.' + task + '.taint'
bb.utils.mkdirhier(os.path.dirname(taintfn))
# The specific content of the taint file is not really important,
# we just need it to be random, so a random UUID is used
with open(taintfn, 'w') as taintf:
taintf.write(str(uuid.uuid4()))
2024-09-09 08:52:07 +00:00
def stampfile(taskname, d, file_name = None):
"""
Return the stamp for a given task
(d can be a data dict or dataCache)
"""
return stamp_internal(taskname, d, file_name)
2024-09-09 08:57:42 +00:00
def add_tasks(tasklist, deltasklist, d):
task_deps = d.getVar('_task_deps')
2024-09-09 08:52:07 +00:00
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:
2024-09-09 08:57:42 +00:00
task = d.expand(task)
if task in deltasklist:
continue
d.setVarFlag(task, 'task', 1)
2024-09-09 08:52:07 +00:00
if not task in task_deps['tasks']:
task_deps['tasks'].append(task)
2024-09-09 08:57:42 +00:00
flags = d.getVarFlags(task)
2024-09-09 08:52:07 +00:00
def getTask(name):
if not name in task_deps:
task_deps[name] = {}
if name in flags:
2024-09-09 08:57:42 +00:00
deptask = d.expand(flags[name])
2024-09-09 08:52:07 +00:00
task_deps[name][task] = deptask
getTask('depends')
2024-09-09 08:57:42 +00:00
getTask('rdepends')
2024-09-09 08:52:07 +00:00
getTask('deptask')
getTask('rdeptask')
getTask('recrdeptask')
2024-09-09 08:57:42 +00:00
getTask('recideptask')
2024-09-09 08:52:07 +00:00
getTask('nostamp')
getTask('fakeroot')
getTask('noexec')
getTask('umask')
task_deps['parents'][task] = []
2024-09-09 08:57:42 +00:00
if 'deps' in flags:
for dep in flags['deps']:
dep = d.expand(dep)
task_deps['parents'][task].append(dep)
2024-09-09 08:52:07 +00:00
# don't assume holding a reference
2024-09-09 08:57:42 +00:00
d.setVar('_task_deps', task_deps)
def addtask(task, before, after, d):
if task[:3] != "do_":
task = "do_" + task
d.setVarFlag(task, "task", 1)
bbtasks = d.getVar('__BBTASKS') or []
if not task in bbtasks:
bbtasks.append(task)
d.setVar('__BBTASKS', bbtasks)
existing = d.getVarFlag(task, "deps") or []
if after is not None:
# set up deps for function
for entry in after.split():
if entry not in existing:
existing.append(entry)
d.setVarFlag(task, "deps", existing)
if before is not None:
# set up things that depend on this func
for entry in before.split():
existing = d.getVarFlag(entry, "deps") or []
if task not in existing:
d.setVarFlag(entry, "deps", [task] + existing)
def deltask(task, d):
if task[:3] != "do_":
task = "do_" + task
bbtasks = d.getVar('__BBDELTASKS') or []
if not task in bbtasks:
bbtasks.append(task)
d.setVar('__BBDELTASKS', bbtasks)
2024-09-09 08:52:07 +00:00